Jersey1.8在spring环境上的实现 包括实例代码
最近项目里面要使用rest或者webservice来实现一些对外的接口。
查了很多资料,最后选择了Restlet、Apache CXF、Jersey。
Restlet是抛弃了servlet api,自身实现了一些api,最关键的是没有提供spring的集成。
CXF很好,很强大,但是觉得它的json不爽,总是要先绕道jaxb。
Jersey是sun推出来的,很轻量、很环保、支持JAX-RS规范,据说要整合到jdk中去的。
最终权衡之下选择了Jersey。
Jersey的官方网站http://jersey.java.net/,相关文件可以在里面下载的。
1.资料,在线文档。
http://jersey.java.net/nonav/documentation/latest/getting-started.html
可以通过maven进行环境的搭建。
我没有使用maven的习惯,最后手工下载的,下载了好久,基本把所有插件都下载到了。
这边附近只能上传10M,上传一张相关的lib截图,需要的另外附上。
2.与spring集成
在classpath里里加入jersey-spring.jar,web.xml里面划一个url如/restapi/* 归Jersey的SpringServlet管即可。 然后SpringServlet就会在Spring的Context里查找支持某个具体path的Bean来出来处理请求。
<!-- Jersey 配置 --> <servlet> <servlet-name>JerseyServlet</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>com.tianque.locationtalk.api</param-value> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> </servlet>
3.参数支持和接口
@PathParam用来表示Restful风格下在URL中的id等标识。
@QueryParameter可以转换任何有以String为参数的构造函数的类,还可以设定defaultValue, 当参数为空时会自动抛异常
@POST+ @Consumes 以POST方式传递XML或JSON编码的Java对象
@Context UriInfo,@Context HttpHeaders, @Context HttpServletRequest 获取灵活的,不固定的参数. 可以从原版HttpServletRequest中获取,也可以用封装好的更方便的UriInfo和HttpHeaders.
4.使用Jackson处理JSON
在classpath里加入jersey-json.jar后,在服务端,web.xml里SpringServlet的定义要加入
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
package com.xxx.locationtalk.api; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class User { public Long userId; public String userName; public String nickName; public User(){ } public User(Long userId,String userName,String nickName){ this.userId =userId; this.userName=userName; this.nickName=nickName; } }
package com.xxx.locationtalk.api; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import com.xxx.locationtalk.domain.MobileNumber; import com.xxx.locationtalk.service.MobileNumberService; @Component @Scope("request") @Path("/bookapi") public class BookService { @Autowired private MobileNumberService mobileNumberService; public MobileNumberService getMobileNumberService() { return mobileNumberService; } public void setMobileNumberService(MobileNumberService mobileNumberService) { this.mobileNumberService = mobileNumberService; } //外部传过来的参数 @QueryParam("id") String userId; @GET @Produces(MediaType.TEXT_PLAIN) public String helloWorld() { String ret = "Hello World!"; return ret; } // 子路径 @Path("getUsers") @GET @Produces( {MediaType.APPLICATION_XML }) public List<User> getUsers() { List<User> users = new ArrayList<User>(); for (long i = 1; i < 5; i++) { User user = new User(); user.userId=(i); user.userName=("yuhan" + i); user.nickName=("supben" + i); users.add(user); } return users; } // 子路径 @Path("getUserById") @GET @Produces( {MediaType.APPLICATION_JSON }) public User getUsersById(){ User user = new User(); //使用spring的类读取数据库信息,随便赋值 MobileNumber object=mobileNumberService.getMobileNumberById(Long.valueOf(userId)); user.userId=object.getId(); user.userName=object.getUsersName(); user.nickName=object.getMobileNumber(); return user; } @Path("getUserXmlById") @GET @Produces( {MediaType.APPLICATION_XML }) public User getUsersByIdForXML(){ User user = new User(); MobileNumber object=mobileNumberService.getMobileNumberById(Long.valueOf(userId)); user.userId=object.getId(); user.userName=object.getUsersName(); user.nickName=object.getMobileNumber(); return user; } @Path("setUser") @PUT @Produces( {MediaType.APPLICATION_JSON }) public User setUser(User user){ if(user==null){ System.out.println("数值为空!!"); user.userId=(13486197987L); user.userName=("yuhan"); user.nickName=("supben"); }else{ System.out.println("user.userId="+user.userId); System.out.println("user.userName="+user.userName); System.out.println("user.nickName="+user.nickName); user.userId=(user.userId); user.userName=(user.userName); user.nickName=(user.nickName); } return user; } // 子路径 @Path("getUserByXML") @GET @Produces( {MediaType.APPLICATION_XML }) public User getUserByIdWithXML() throws UnsupportedEncodingException{ User user = new User(); user.userId=(10000L); user.userName=URLEncoder.encode(("哈哈"), "utf-8"); user.nickName=URLEncoder.encode(("老色狼"), "utf-8"); return user; } }
package com.xxx.locationtalk.api; import java.io.UnsupportedEncodingException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.client.config.ClientConfig; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.json.JSONConfiguration; import com.sun.jersey.core.util.MultivaluedMapImpl; import com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider; public class ClientDemo{ public static void main(String[] args) throws UnsupportedEncodingException{ ClientConfig clientConfig = new DefaultClientConfig(); clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); Client c = Client.create(clientConfig); String url = "http://localhost:8080/api/bookapi"; WebResource r = c.resource(url); User user = new User(); user.userId=1000L; user.userName="江江123"; user.nickName="老色狼"; System.out.println("状态码="+r.path("setUser").accept(new String[] {MediaType.APPLICATION_JSON}). entity(user, MediaType.APPLICATION_JSON).put(ClientResponse.class).getStatus()); MultivaluedMap<String, String> param = new MultivaluedMapImpl(); param.add("userId", "10000"); param.add("userName", "脏话"); param.add("nickName", "脏话色狼"); System.out.println(r.queryParams(param) .type(MediaType.APPLICATION_JSON).post(String.class)); } }
附件包括
一张相关的jersey用到的所有lib截图
官方下载的最新jersey说明文档
官方下载的jersey1.8.zip,包括核心的lib以及doc
Get /tasks index page to list all tasks
Get /tasks/${id} show page to show task
Get /tasks/create create page to create task
Post /tasks/add add to create task
Get /tasks/${id}/edit edit page to edit task
Put /tasks/${id} update to update task
Delete /tasks/${id} destory to detete task
http://localhost:8080/api/bookapi/getUserByXML获得一个xml格式的对象
http://localhost:8080/api/bookapi/setUser可以对一个user对象进行赋值
http://localhost:8080/api/bookapi/getUserXmlById可以传入一个id参数,获得一个xml格式的对象
这么设计是处于什么考虑的?增强url对function的表意?
每一个url表示一个资源,每个资源允许几种定义好的行为,crud。
这样一个url对应现实的一个物体。
http://localhost:8080/api/bookapi/getUserByXML获得一个xml格式的对象
http://localhost:8080/api/bookapi/setUser可以对一个user对象进行赋值
http://localhost:8080/api/bookapi/getUserXmlById可以传入一个id参数,获得一个xml格式的对象
这个url, 我估计会设计成这样:
root: /api/bookapi/*
Get /users 获取所有用户对象
Get /users/${id} 根据ID获取用户信息, xml/json 根据请求的ContentType对应数据格式
ContentType: text/html, text/xml, text/json
Jersey下你的包了, 这还不太了解,不知道能不能实现我上面的这种方式
我写的是个demo 内部沟通使用的
毕竟大部分还是习惯普通的get命名方式