-
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.使用Jackson做JSON解释包 Jersey默认是用那个基于Jaxb的JSON解释包的。想使用jackson,在Server端,在web.xml的servlet定义里加入
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
在Client端,
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
Client client = Client.create(clientConfig);
###2. Jersey的Client Jersey的Client见mini-service的AccountResourceClient和showcase的UserResourceClient,个人觉得是最好用的Rest客户端。 设置读取各种Restful常用的输入输出参数都比较方便,还能很好的在各种格式的数据与Java类之间转换。
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/