目的: 基于jersy的restful的实例
请求正常,返回取得对象User的json
请求正常&jsonp,返回jsonpcallback(User的json)
请求异常,返回错误消息的json
请求异常&jsonp,返回jsonpcallback(错误情报的json)
使用的jar如下:
commons-lang3-3.1.jar
jackson-core-asl-1.9.2.jar
jackson-jaxrs-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
jackson-xc-1.9.2.jar
jersey-client-1.19.jar
jersey-core-1.19.jar
jersey-json-1.19.jar
jersey-server-1.19.jar
jersey-servlet-1.19.jar
jettison-1.1.jar
jsr311-api-1.1.1.jar
上面的jar可以从jersy的官网https://jersey.java.net/download.html,直接下载
下面上代码
1.web.xml中的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- jersy servlet--> <servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name>
<!-- 类似于springmvc 配置扫描的包 -->
<!-- sample.jersy.demo.resources hander的类的包名-->
<!-- -sample.jersy.demo.exception WebApiExceptionMapper所在包的包名-> <param-value>sample.jersy.demo.resources,sample.jersy.demo.exception</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <!-- jsonp? json filter --> <filter> <display-name>JsonpFilter</display-name> <filter-name>JsonpFilter</filter-name> <filter-class>sample.jersy.demo.filter.JsonpFilter</filter-class> </filter> <filter-mapping> <filter-name>JsonpFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
2.请求正常处理的User的entity,以及请求异常时候的MsgInfo的entity
User中的代码如下:
package sample.jersy.demo.entity; import javax.xml.bind.annotation.XmlRootElement; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @XmlRootElement(name="user") public class User { private Integer id; private String name; private String address; private int age; // setter, getter方法省略public String toString(){ return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }
MsgInfo代码如下:
package sample.jersy.demo.entity; import java.io.StringWriter; import javax.xml.bind.JAXB; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "message") public class MsgInfo { private String msgCode; private String msgValue;
// setter,getter方法,以及无参有惨构造方法 省略, public String toXml() { StringWriter sw = new StringWriter(); JAXB.marshal(this, sw); return sw.toString(); } }
3.自定义的异常类,以及监视异常的处理Mapper
自定义的异常类WebApiException的代码如下:
package sample.jersy.demo.exception; import javax.ws.rs.core.Response.Status; import sample.jersy.demo.entity.MsgInfo; public class WebApiException extends Exception { private static final long serialVersionUID = -4230864191367207414L; private Status status; // 请求返回Response中的status private String headerKey; // 请求返回Response中的headerKey private String headerValue; private MsgInfo msgInfo; // 异常时候,返回消息情报对象 // setter, getter方法, 以及无参,有参构造函数 }
监视异常处理的Mapper WebApiExceptionMapper的代码如下:
package sample.jersy.demo.exception; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; import com.sun.jersey.api.client.config.DefaultClientConfig; import com.sun.jersey.api.json.JSONConfiguration; @Provider public class WebApiExceptionMapper implements ExceptionMapper<WebApiException> { @Override public Response toResponse(WebApiException e) { (new DefaultClientConfig()).getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); return Response.status(e.getStatus()) .header(e.getHeaderKey(), e.getHeaderValue()) .entity(e.getMsgInfo()) .build(); } }
3.请求处理的hander如何写
UserResource的代码如下:
package sample.jersy.demo.resources; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import sample.jersy.demo.entity.MsgInfo; import sample.jersy.demo.entity.User; import sample.jersy.demo.exception.WebApiException; @Path("/user") public class UserResource { @GET @Path("/{user_id}") @Produces({ "application/json; charset=UTF-8;"}) public Response getUser(@PathParam("user_id") String userId) throws WebApiException { if("ok".equals(userId)){ System.out.println("success!!!!!"); User user = new User(); user.setId(1); user.setName("Tom"); user.setAge(18); user.setAddress("Tom_address"); return Response.ok(user).build(); }else{ System.out.println("error!!!!"); throw new WebApiException(Response.Status.NOT_FOUND, "headerKey", "headerValue", new MsgInfo("404", "user is not exist")); } } }
看到上面的handler里面的返回的数据类型是json,但是我们的要求是根据请求,
如果请求$.ajax的的dataType是jsonp的时候,要求返回的javascript,怎么办呢,下面来定义一个过滤器,
根据请求的url中是否有callback来判定,返回json还是jsonp
4.判断请求应该返回json还是jsonp的过滤器
JsonpFilter的代码如下
package sample.jersy.demo.filter; import java.io.IOException; import java.io.OutputStream; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet Filter implementation class JsonpFilter */ public class JsonpFilter implements Filter { /** * Default constructor. */ public JsonpFilter() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse resp = (HttpServletResponse)response; String jsonpCallback = req.getParameter("callback"); if(jsonpCallback !=null && !"".equals(jsonpCallback)){ System.out.println("数据返回: jsonp"); OutputStream os = resp.getOutputStream(); os.write((jsonpCallback+"(").getBytes()); chain.doFilter(request, response); os.write(")".getBytes()); }else{ System.out.println("数据返回: json"); chain.doFilter(request, response); } } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub } }
到这里为止,代码结束了
下面来测试
测试代码如下:
package sample.jersy.demo.test; import org.junit.Before; import org.junit.Test; 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; public class ClientTest { Client client = null; @Before public void before(){ ClientConfig config = new DefaultClientConfig(); config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); client = Client.create(config); } @Test public void testGet() { System.out.println("http://localhost:8080/Jersy_Rest_Demo/user/ok"); WebResource resource = client.resource("http://localhost:8080/Jersy_Rest_Demo/user/ok"); ClientResponse response = resource.get(ClientResponse.class); String content = response.getEntity(String.class); System.out.println("response.getStatus() : "+response.getStatus()); System.out.println(content); System.out.println(); } @Test public void testGet2() { System.out.println("http://localhost:8080/Jersy_Rest_Demo/user/error"); WebResource resource = client.resource("http://localhost:8080/Jersy_Rest_Demo/user/error"); ClientResponse response = resource.get(ClientResponse.class); String content = response.getEntity(String.class); System.out.println("response.getStatus() : "+response.getStatus()); System.out.println(content); System.out.println(); } @Test public void testGet3() { System.out.println("http://localhost:8080/Jersy_Rest_Demo/user/ok?callback=jsonpCallback"); WebResource resource = client.resource("http://localhost:8080/Jersy_Rest_Demo/user/ok?callback=jsonpCallback"); ClientResponse response = resource.get(ClientResponse.class); String content = response.getEntity(String.class); System.out.println("response.getStatus() : "+response.getStatus()); System.out.println(content); System.out.println(); } @Test public void testGet4() { System.out.println("http://localhost:8080/Jersy_Rest_Demo/user/error?callback=jsonpCallback"); WebResource resource = client.resource("http://localhost:8080/Jersy_Rest_Demo/user/error?callback=jsonpCallback"); ClientResponse response = resource.get(ClientResponse.class); String content = response.getEntity(String.class); System.out.println("response.getStatus() : "+response.getStatus()); System.out.println(content); System.out.println(); } }
启动tomcat服务器,会看到如下情报:
情報: Scanning for root resource and provider classes in the packages: sample.jersy.demo.resources sample.jersy.demo.exception 2016/01/27 15:12:05 com.sun.jersey.api.core.ScanningResourceConfig logClasses 情報: Root resource classes found: class sample.jersy.demo.resources.UserResource 2016/01/27 15:12:05 com.sun.jersey.api.core.ScanningResourceConfig logClasses 情報: Provider classes found: class sample.jersy.demo.exception.WebApiExceptionMapper
测试结果贴一帖:
http://localhost:8080/Jersy_Rest_Demo/user/ok response.getStatus() : 200 {"address":"Tom_address","age":"18","id":"1","name":"Tom"} http://localhost:8080/Jersy_Rest_Demo/user/error response.getStatus() : 404 {"msgCode":"404","msgValue":"user is not exist"} http://localhost:8080/Jersy_Rest_Demo/user/ok?callback=jsonpCallback response.getStatus() : 200 jsonpCallback({"address":"Tom_address","age":"18","id":"1","name":"Tom"}) http://localhost:8080/Jersy_Rest_Demo/user/error?callback=jsonpCallback response.getStatus() : 404 jsonpCallback({"msgCode":"404","msgValue":"user is not exist"})