Skip to content
springside edited this page Apr 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.使用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/

返回参考手册

Clone this wiki locally