-
Notifications
You must be signed in to change notification settings - Fork 0
Jersey
#Jersey Restful Framework ##Overview Jersey与Spring MVC的概念很像,区别只是一个是JAX-RS标准,另一个不是。用哪一个问题都不大。Jersey无非标准些,涉及的东西少些,关于Restful控制更精确些,但有时候一个Spring MVC既对付Web Page,又对付Restful的Ajax请求,再对付Restful Service,也不错。
而client方面,Jersey做的不错,估计JAX-RS2.0的client标准应该以它为蓝本了。
除了Restful Framework, Hibernaet Validator(输入参数校验) 和 Dozer(定义DTO对象,隔离核心业务对象,在两者间进行复制)对Restful Service也很重要,在后面的章节中说明。
##Quick Start 在Spring Base的Web应用中使用Jersey的场景如下
Step1.下载相关jersey包 包括 jersey-server,jersey-servlet,jersey-spring 和 jersey-json
Step2. web.xml里使用servlet 侦听相关相应路径
<servlet>
<servlet-name>JerseyServlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>JerseyServlet</servlet-name>
<url-pattern>/rs/*</url-pattern>
</servlet-mapping>
注意的是这里的路径是/rs/*,则以后@Path("/user"),会被映射成/rs/user。
step3. 按照JAX-Rs编写RestfulService的POJO,并用@Component或application-*.xml定义Bean
##Tips ###1.使用Jackson2.0做JSON解释包 Jersey-JSon默认是用那个基于Jaxb的JSON解释包的。想使用jackson还要进行配置,再加上Jackson升到2.0后,package名都变了,所以就干脆直接使用Jackson提供的jackson-jaxrs-json-provider. 要自己在项目的META-INF/services里,放一个javax.ws.rs.ext.MessageBodyReader文件,一个javax.ws.rs.ext.MessageBodyWriter文件,里面的内容都是
com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
注意2.0版后,如果用下面的语句获取一个json格式的字符串会报错,因为JacksonJsonProvider不再skip掉String型和byte[]型的返回值请求。
client.path(url).accept(MediaType.APPLICATION_JSON).get(String.class);
###2. Jersey的Client Jersey的Client见mini-service的AccountResourceClient和showcase的UserResourceClient,个人觉得是最好用的Rest客户端。 设置读取各种Restful常用的输入输出参数都比较方便,还能很好的在各种格式的数据与Java类之间转换。
按文档所说,Client类的创建是昂贵的,最好重用。而Client类和WebResource类都是ThreadSafe的,可以在多个线程间Share。
client.path("/users/" + id).accept(MediaType.APPLICATION_JSON).get(UserDTO.class);
client.path("/users").accept(MediaType.APPLICATION_JSON).get(new GenericType<List<UserDTO>>() {});
client.path("/users/search").queryParam("name", name).get(String.class);
client.path("/users").entity(user, MediaType.APPLICATION_JSON).post(ClientResponse.class)
###3. MultiPart 下载jersey-multipart.jar, 基于MimePull的实现。 见showcase中的UserResourceClient和UserResourceServer Client:
MultiPart inputMultiPart = new MultiPart().bodyPart(new BodyPart(user, MediaType.APPLICATION_JSON_TYPE))
.bodyPart(new BodyPart(descriptionText, MediaType.TEXT_PLAIN_TYPE));
return client.path("/users/multipart").type("multipart/mixed").post(String.class, inputMultiPart);
Server:
@Consumes("multipart/mixed")
public String multiPart(MultiPart multiPart) {
User user = multiPart.getBodyParts().get(0).getEntityAs(User.class);
String text = multiPart.getBodyParts().get(1).getEntityAs(String.class);
}
###4. 与Shiro结合的Http-Basic认证与权限控制 还是看Showcase的的UserResourceClient和UserResourceServer
Client端用Servlets.encodeHttpBasic(userName,password)生成明文的用户名密码信息并附送在HttpHeader中
Shiro在applicationContext-shiro.xml中配置http-basic filter侦听相关请求
Shiro用annotation控制UserResourceClient中的公共函数。
编写一个异常转换的Mapper,将Shiro的Exception转换成401或403错误,注意要注册到Spring的applicationContext里。
@Provider
public class ShiroExceptionMapper implements ExceptionMapper<UnauthorizedException> {
public Response toResponse(UnauthorizedException ex) {
return Jerseys.buildTextResponse(Status.UNAUTHORIZED, ex.getMessage());
}
}
##SpringSide Modules 虽说Jax-RS用的是优美的Builder模式,但构造一个Exception或者Response的代码还是有点长,所以封装了Jerseys来实现快速构造。
另外,Jersey抛出异常后不会自动打log,一定要自己写log,也封装在Jerseys的函数里了。
##资料 Jersey的ChangeLog在某核心开发人员的Blog里: https://blogs.oracle.com/japod/