Skip to content
springside edited this page Mar 23, 2012 · 10 revisions

#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客户端。

client.path("/users/" + id).accept(MediaType.APPLICATION_JSON).get(UserDTO.class);

wr.accept(MediaType.APPLICATION_JSON).get(new GenericType<List<UserDTO>>() {});

client.path("/users/search").queryParam("name", name).get(String.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/

返回参考手册

Clone this wiki locally