当前位置: 首页 > 编程日记 > 正文

JAX-RS(基于Jersey) + Spring 4.x + MyBatis构建REST服务架构

0. 大背景

众所周知,REST架构已经成为现代服务端的趋势。

很多公司,已经采用REST作为App, H5以及其它客户端的服务端架构。

1. 什么是JAX-RS?

JAX-RS是JAVA EE6 引入的一个新技术。 JAX-RS即Java API for RESTful Web Services,是一个Java 编程语言的应用程序接口,支持按照表述性状态转移(REST)架构风格创建Web服务。

JAX-RS使用了Java SE5引入的Java标注来简化Web服务的客户端和服务端的开发和部署。
Roy Fielding也参与了JAX-RS的制订,他在自己的博士论文中定义了REST。

对于那些想要构建RESTful Web Services的开发者来说,JAX-RS给出了不同于JAX-WS(JSR-224)的另一种解决方案。


JAX-RS提供了一些标注将一个资源类,一个POJO Java类,封装为Web资源。

基于JAX-RS实现的框架有Jersey,RESTEasy等。这两个框架创建的应用可以很方便地部署到Servlet 容器中,比如Tomcat,JBoss等。

值得一提的是RESTEasy是由JBoss公司开发的,所以将用RESTEasy框架实现的应用部署到JBoss服务器上,可以实现很多额外的功能。

目前共有4种JAX-RS实现,所有这些实现都支持Spring,Jersey则是JAX-RS的参考实现,也是本文所用的实现。

JAX-RS常用标注:
@Path,标注资源类或者方法的相对路径
@GET,@PUT,@POST,@DELETE,标注方法是HTTP请求的类型。
@Produces,标注返回的MIME媒体类型
@Consumes,标注可接受请求的MIME媒体类型
@PathParam,@QueryParam,@HeaderParam,@CookieParam,@MatrixParam,@FormParam,

分别标注方法的参数来自于HTTP请求的不同位置,

例如

@PathParam来自于URL的路径,

@QueryParam来自于URL的查询参数,

@HeaderParam来自于HTTP请求的头信息,

@CookieParam来自于HTTP请求的Cookie。

2. 为什么使用Spring + MyBatis?

Spring我想就不必介绍了,做Java的都知道。

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。

2013年11月迁移到Github。
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。
MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。

MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

目前Java EE开发的现状是:Hibernate的数据访问层地位已经在逐步下降,而更加轻量级的MyBati正在逐渐在中小型项目中崭露头角。

3. 开发前的准备工作

首先,你要下载2个必须的jar, 一个是jersey, 另一个则是jersey-spring,由于jersey默认没有整合Spring,因此后一个jar特别重要。

如果,你还不知道从哪里下载,那么本博主提供了下载地址:

http://www.coolbaba.net/Upload/Jar/Jersey-Jax.zip

然后,新建一个空的Java Web项目,将下载的2个jar拷贝到你的项目并添加对它们的引用。

4. 配置文件编辑

需要准备2个配置文件,一个是spring-mybatis.xml,

它是Spring和MyBatis的整合配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.1.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"><!-- 自动扫描 --><context:component-scan base-package="bbc" /><!-- 引入配置文件 --><bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location" value="classpath:jdbc.properties" /></bean><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName" value="com.mysql.jdbc.Driver" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /><!-- 初始化连接大小 --><property name="initialSize" value="${initialSize}"></property><!-- 连接池最大数量 --><property name="maxActive" value="${maxActive}"></property><!-- 连接池最大空闲 --><property name="maxIdle" value="${maxIdle}"></property><!-- 连接池最小空闲 --><property name="minIdle" value="${minIdle}"></property><!-- 获取连接最大等待时间 --><property name="maxWait" value="${maxWait}"></property></bean><!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><!-- 自动扫描mapping.xml文件 --><property name="mapperLocations" value="classpath:bbc/mapping/*.xml"></property><property name="typeAliasesPackage" value="bbc.domain"/></bean><!-- DAO接口所在包名,Spring会自动查找其下的类 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="bbc.dao" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property></bean><!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!-- <bean id="SpringContextUtil " class="bbc.util.web.SpringContextUtil " scope="singleton" /> -->
</beans>

jdbc.properties配置如下:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=UTF-8
jdbc.username=your_username
jdbc.password=your_password
initialSize=0
#定义最大连接数
maxActive=20
#定义最大空闲
maxIdle=20
#定义最小空闲
minIdle=1
#定义最长等待时间
maxWait=60000

最后是web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"version="3.0"><!-- 处理中文乱码 --><filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mybatis.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><servlet><servlet-name>ComicJaxServlet</servlet-name><servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class><init-param><param-name>com.sun.jersey.config.property.packages</param-name><param-value>bbc.resource</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>ComicJaxServlet</servlet-name><url-pattern>/resources/*</url-pattern></servlet-mapping>
</web-app>

上面有两处需要特别注意:

一是 servlet的配置处,class需要改成

com.sun.jersey.spi.spring.container.servlet.SpringServlet

而不是原来的

com.sun.jersey.spi.container.servlet.ServletContainer (错误!!)

二是init-param中bbc.resource是我的REST服务所在的包名,这里你可以改成你自己的。

5. 编写domain pojo

Series.java

package bbc.domain;/*** Created by KG on 16/11/24.*/
public class Series extends BaseDomain {private int id;private int sourceId;private String name;private String brief;private String address;private String folder;private String cover;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getSourceId() {return sourceId;}public void setSourceId(int sourceId) {this.sourceId = sourceId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getBrief() {return brief;}public void setBrief(String brief) {this.brief = brief;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public String getFolder() {return folder;}public void setFolder(String folder) {this.folder = folder;}public String getCover() {return cover;}public void setCover(String cover) {this.cover = cover;}
}

6. 编写dao和映射文件

SeriesDao.java

package bbc.dao;import bbc.domain.Series;import java.util.List;/*** Created by KG on 16/11/24.*/
public interface SeriesDao {List<Series> selectAllRecords();
}

SeriesDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace="bbc.dao.SeriesDao" ><resultMap type="Series" id="SeriesResult"><id property="id" column="id" /><result property="sourceId" column="source_id" /><result property="name" column="name" /><result property="brief" column="brief" /><result property="address" column="address" /><result property="folder" column="folder" /><result property="cover" column="cover" /><result property="createTime" column="create_time" /><result property="lastUpda" column="last_upda" /></resultMap><select id="selectAllRecords" resultType="Series" resultMap="SeriesResult">select *from series</select>
</mapper>

7. 编写REST服务,并将dao通过Spring注入服务

SeriesResource.java

package bbc.resource;import bbc.dao.SeriesDao;
import bbc.domain.Series;
import bbc.service.SeriesService;
import com.sun.jersey.api.core.InjectParam;
import com.sun.jersey.spi.inject.Inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import java.util.List;/*** Created by KG on 16/11/24.*/
@Path("/series/")
@Component
@Scope("prototype")
public class SeriesResource {@Autowiredprivate SeriesDao seriesDao;@GET@Produces("application/json")public String getAllSeries() {List<Series> seriesList = seriesDao.selectAllRecords();....}
}

上面通过Autowired自动绑定dao接口的实现。

一般我们服务端中用的最多的是POST请求,如果是post的话也很简单,如下:

@Path("/some/")
@Component
public class SomeResource {@POST@Path("/testpost")@Produces("application/json")public String testPost(String request) {return "Response: " + request;}
}

上面中参数request会自动收到客户端传过来的json字符串,然后你可以选择解析该json并且反序列化为pojo对象,进行后一步的操作,

最后把结果序列化成json丢回给客户端。

好了,一切大功告成!!

启动tomcat,你可以通过如下地址访问你的服务:

http://localhost:8080/resources/series

相关文章:

c语言宏嵌套和展开规则

基本原则&#xff1a; 在展开当前宏函数时&#xff0c;如果形参有#或##则不进行宏参数的展开&#xff0c;否则先展开宏参数&#xff0c;再展开当前宏。 #是在定义两边加上双引号 #define _TOSTR(s) #sprintf(_TOSTR(test ABC)) printf(_TOSTR("test ABC")); print…

【ACM】杭电OJ 2027

注意输出格式&#xff01;&#xff01;&#xff01;&#xff01; #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn 10000; char s1[maxn]; int main () {int n,j,i,a,e,o,u;scanf("%d",&n)…

搜索引擎广告过滤Chrome插件

搜索广告屏蔽Chrome插件:自动过滤&#xff1a;百度&#xff0c;360&#xff0c;搜狗&#xff0c;google&#xff0c;bing的搜索广告&#xff0c;让魏则西的悲剧不再重演。珍爱生命&#xff0c;远离搜索广告&#xff01;下载&#xff1a;FuckAd.zip 安装&#xff1a;方法自行百度…

Scala程序设计:Java虚拟机多核编程实战(国内第一本Scala图书)

Scala程序设计&#xff1a;Java虚拟机多核编程实战(国内第一本Scala图书) 基本信息 作者&#xff1a; (美)Venkat Subramaniam 译者&#xff1a; 郑晔 李剑 丛书名&#xff1a; 图灵程序设计丛书 出版社&#xff1a;人民邮电出版社 ISBN&#xff1a;9787115232953 上架时间&am…

emacs快捷键

https://blog.wozouwokan.com/%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91/2015/07/14/spacemacs/ 超全开发快捷键&#xff1a;https://edward852.github.io/post/%E9%80%9A%E7%94%A8%E4%BB%A3%E7%A0%81%E7%BC%96%E8%BE%91%E5%99%A8spacemacs/ spc f T快速定位当前文件在neotree中的…

python 小程序,输错三次密码锁定账户

1 [rootsun ~]# cat 7.py 2 #!/usr/bin/python3 # -*- codingUTF-8 -*-4 5 usera_name usera6 usera_passwd aresu7 usera_status on8 userb_name userb9 userb_passwd bresu 10 userb_status on 11 ng 0 12 13 14 name raw_input(请输入用户名&#xff1a;) 15 …

【数据结构】图的深度优先遍历 广度优先遍历

文件操作比直接输入方便许多 #include <stdio.h> #include <stdlib.h> #include <string.h> #define M 20/*邻接表的储存结构*/ typedef struct node /*表结点 或者 边表结点*/ {int adjvex;struct node *next; }edgenode;typedef struct vnode /*头结点*/ …

C++ Primer(第4版)(评注版)

《C Primer(第4版)(评注版)》基本信息原书名&#xff1a; C Primer (4th Edition) 原出版社&#xff1a; Addison-Wesley Professional; 4 edition 作者&#xff1a; (美)Stanley B.Lippman Josee Lajoie Barbara E.Moo 译者&#xff1a; 陈硕 丛书名&#xff1a; 传世经典书丛…

win10安装emacs+spacemacs,建议用官方安装方式

1、下载emacs最新版 26.1 官网下载地址&#xff1a;https://www.gnu.org/software/emacs/download.html#nonfree 2、解压emacs到你的安装目录,我的系统是D:/Program File/。执行/bin目录下的addpm.exe 这一步会在开始菜单创建快捷方式 3、在系统环境变量中添加新项HOME(具体环…

【ACM】杭电OJ 2028

int 会 WA &#xff0c;注意使用 long long 先除后乘&#xff0c;避免超出范围&#xff0c;但好像本题先乘后除也AC #include <iostream> #include <cstdio> #include <cstring>long long lcm(long long a,long long b) {long long c,t,ma,nb;if(a<b) {…

IIS8 添加配置 WCF服务

今天在Windows8.1 操作系统部署了半天的WCF 一直老是在报错、在这里做个记录 防止下次忘记 在网上查了半天。终于知道原来IIS&#xff18;不支持WCF服务SVC的请求。所以必须要给IIS&#xff18;添加WCF服务 的Managed Handler。 添加步骤&#xff1a; &#xff11;打开IIS&a…

spacemacs各种问题修复方法

快捷键操作时报 tr不是内部命令 ------说明是缺少tr命令&#xff0c;win10可以安装coreutils for gnuwin32工具集&#xff0c;然后把bin目录加到系统path路径即可 没有ispell, flycheck error ------缺少ispell命令&#xff0c;windows下面用aspell替换&#xff0c;需要安装…

2016/08/27 What I Learned About Going Fast at eBay and Google

每天推荐一个英文视频 http://v.qq.com/page/i/2/d/i0...https://www.youtube.com/watch... 本日看点

【ACM】杭电OJ 2030

注意getchar()的使用&#xff0c;以及汉字占两个字节&#xff0c;因为比较特殊&#xff0c;可以单独记忆 #include <iostream> #include <cstdio> #include <cstring> int main () {char c;int n,i,sum;scanf("%d",&n);getchar();while(n--)…

背景图自适应屏幕居中显示,且不变形

html&#xff1a;<div classitem><div class container /> </div> css:.item {width: 100%;height: 100%;.container {max-width: 100%;height: auto;min-height: 600px; // 这里可监听屏幕变化&#xff0c;改变最小高度position: absolute;left: 50%;top:…

emacs按键绑定详解

key-binding: https://crazylxr.github.io/spacemacas-zh_CH-doc/binding-keys.html 概述&#xff1a;Emacs的键绑定方式看起来花样繁多&#xff0c;其本质上都是同一个机制 (define-key keymap key def) 这里的key是你要绑定的键。keymap是这个key所属的集合&#xff0c;不…

【面试】重建二叉树

一、描述 输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请重建出该二叉树&#xff0c;假设输入的前序遍历和中序遍历的结果中都不含重复的数字&#xff0c;例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}&#xff0c;则重建出该二叉树。二叉树结…

【ACM】杭电OJ 2034

开了三个数组 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <set> #include <algorithm> using namespace std; const int maxn 105; int a[maxn],b[maxn],c[maxn];…

Android 依赖库发布(上传 Library 到 JCenter)gradle最高支持4.4

1.注册 Bintray 注册时要注意哦&#xff0c;千万不要注册成组织的账户&#xff0c;一定要注册为个人。因为组织账户只有一个月的免费使用时间。 个人账户注册地址&#xff1a;bintray.com/signup/oss 有Github、Google、Twitter账号的可以直接登录哦 2.创建Maven仓库&#xff0…

emacs参考资料整理

spacemacs dired模式用法: https://blog.slegetank.com/blog/20170106-dired.htmlEmacs文件管理神器--dired常用操作说明 - 暗无天日快捷键用法&#xff1a;https://yuyang0.github.io/notes/spacemacs.htmlemacs官方参考手册&#xff1a;https://www.gnu.org/software/emacs/m…

Codeigniter文件上传类型不匹配错误

Codeigniter的文件上传类方便了我们使用PHP来处理文件上传的操作&#xff0c;使用起来非常简单&#xff0c;如下&#xff1a;$config[upload_path] ./uploads/;$config[allowed_types] gif|jpg|png;$config[max_size] 100;$config[max_width] 1024;$config[max_height] …

【ACM】杭电OJ 2036(待更)

AC代码 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <set> #include <algorithm> using namespace std; const int maxn 105; double a[maxn][3]; int main () {in…

Spring_boot_pom.xml和启动方式

spring-boot-starter-parent 整合第三方常用框架信息(各种依赖信息) spring-boot-starter-web 是Springboot整合SpringMvc Web 实现原理:Maven依赖继承关系 相当于把第三方常用maven依赖信息,在parent项目中已经封装好了 提供依赖信息关联整合的jar包 springboot中快速原理…

ubuntu18安装virtualbox

1. 报错No rule to make target arch/x86/tools/relocs_32.c 解决办法&#xff1a;sudo apt install linux-source sudo apt-get install linux-headers-5.4.0-42:i386 安装步骤&#xff1a; https://blog.csdn.net/AAMahone/article/details/86428040 安装完成后&…

10分钟学会php面相对象基础(Ⅰ)

<?php 声明一个类 class mycar{ etc. //成员方法 } class mycar{ function drive(){ etc. } } ?> 对象的实例化 内存中分栈和堆&#xff0c;栈定长&#xff0c;堆较大不能直接访问。实例化后&#xff0c;实例名称放在栈内&#xff0c;实例放在堆内&#xff0c;通过实例…

【ACM】杭电OJ 2039

先让啊、三边边长a&#xff0c;b&#xff0c;c按从小到大顺序排列&#xff0c;然后再用两边之和大于第三边&#xff0c;两边之差小于第三边来判断 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib&…

AI一周热闻:GitHub免费开放无限私有库;苹果市值蒸发超450亿美元;小米入股TCL...

CES 2019&#xff1a;英伟达发布RTX 2060和RTX 2080移动版小米入股TCL&#xff0c;增强供应链话语权苹果市值蒸发价值超过Facebook&#xff0c;全球市值第一不保GitHub开放无限私有仓库免费使用英特尔和Facebook等发布计算机视觉系统测试新基准旷视创建高性能的“姿态估计”网络…

ubuntu使用相关

ubuntu查看显卡驱动并安装适配的显卡驱动https://blog.csdn.net/qiancaobaicheng/article/details/95096354ubuntu20设置openssl tls versionhttps://www.coder.work/article/7495451

Atitit.提升 升级类库框架后的api代码兼容性设计指南

Atitit.提升 升级类库框架后的api代码兼容性设计指南 1. 增加api直接增加&#xff0c;版本号在注释上面增加1 2. 废弃api&#xff0c;使用主见dep1 3. 修改api&#xff0c;1 4. 修改依赖import&#xff0c;雅瑶增加文件模式。保持兼容性。。1 5. 优先选择同一个文件内的修改&am…

【ACM】杭电OJ 2040

第一个程序是 15MS #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <set> #include <algorithm> using namespace std; const int maxn 600000; int vis[maxn]; int ma…