1 介绍
1.1 什么是JAX-RS标准
JAX-RS是java领域的REST式的WEB服务的标准规范。它的目标是这样的:
(1)基于POJO,规定使用POJO来公布WEB资源
(2)以HTTP为中心,采用HTTP协议,无状态
(3)格式独立性,JAX-RS2.0对传输数据类型/格式的支持非常宽泛,允许在标准风格之上使用额外的数据类型
(4)容器独立性,JAX-RS2.0的应用可以部署在各种Servlet容器中,比如Tomcat/Jetty,也可以部署在JAX-RS容器中比如GlassFish
(5)内置于JavaEE,JAX-RS2.0是java ee规范的一部分,它定义了在一个JavaEE容器内的Web资源类的内部如何使用JavaEE的功能 和组件
1.2 什么是Jersey
Jersey是JAX-RS标准的参考实现。此外还有其他实现比如SpringMVC,CXF等等
2 基于Jersey构建Web服务
2.1 创建项目
这里和Spring整合在一起,无非就是把Service组件注入Resource对象
2.1.1 pom.xml
4.0.0 JerseyExample JerseyExample 0.0.1-SNAPSHOT war JerseyExample UTF-8 snapshot-repository.java.net Java.net Snapshot Repository for Maven https://maven.java.net/content/repositories/snapshots/ default com.sun.jersey jersey-server 1.8 com.sun.jersey jersey-client 1.8 com.sun.jersey jersey-json 1.8 org.springframework spring-core 4.1.6.RELEASE org.springframework spring-context 4.1.6.RELEASE org.springframework spring-web 4.1.6.RELEASE org.springframework spring-test 4.1.6.RELEASE com.sun.jersey.contribs jersey-spring 1.8 org.springframework spring org.springframework spring-core org.springframework spring-web org.springframework spring-beans org.springframework spring-context com.sun.jersey jersey-bundle 1.18.1 com.sun.jersey.contribs jersey-multipart 1.8 javax.servlet.jsp jsp-api 2.1 provided javax.servlet servlet-api 2.5 provided maven-compiler-plugin 2.3.2 maven-war-plugin 2.2 3.1 false
2.1.2 web.xml
JerseyExample index.html index.htm index.jsp default.html default.htm default.jsp contextConfigLocation classpath*:applicationContext.xml org.springframework.web.context.ContextLoaderListener jersey-serlvet com.sun.jersey.spi.spring.container.servlet.SpringServlet com.sun.jersey.config.property.packages com.lin.jersey.resources 1 jersey-serlvet /rest/*
2.2 domain类
package com.lin.jersey.domain;import java.io.Serializable;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElementpublic class News implements Serializable { private static final long serialVersionUID = -4381505327088114370L; private int id; private String title; private String content; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "News [id=" + id + ", title=" + title + ", content=" + content + "]"; }}
需要在该类上使用注解@XmlRootElement,用于传输时JSON/XML与对象的转换
2.3 业务逻辑组件
一般把业务逻辑组件注入到Resource类,和MVC是一样的,JavaEE的REST服务只是把Controller换成了Resource,Service和DAO层是一样的。。。
package com.lin.jersey.service;import java.util.ArrayList;import java.util.List;import com.lin.jersey.domain.News;public class NewsServcieImpl { private ListnewsDAO = new ArrayList (); public NewsServcieImpl() { for(int i=0;i<10;i++) { News news = new News(); news.setId(i); news.setTitle("Title"+i); news.setContent("Content"+i); newsDAO.add(news); } } /** * create * @param news */ public void addNews(News news) { if(news != null) { newsDAO.add(news); } } /** * delete * @param id */ public void deleteNews(int id) { for(int i=0;i
2.4 Resource类
package com.lin.jersey.resources;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.ws.rs.Consumes;import javax.ws.rs.FormParam;import javax.ws.rs.GET;import javax.ws.rs.POST;import javax.ws.rs.Path;import javax.ws.rs.Produces;import javax.ws.rs.QueryParam;import javax.ws.rs.core.Context;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.Response;import javax.ws.rs.core.UriInfo;import com.lin.jersey.domain.News;import com.lin.jersey.service.NewsServcieImpl;@Path("/news")public class NewsResource { @Context private HttpServletRequest request; @Context private HttpServletResponse response; private NewsServcieImpl newsService; public NewsServcieImpl getNewsService() { return newsService; } public void setNewsService(NewsServcieImpl newsService) { this.newsService = newsService; } @POST @Consumes(MediaType.APPLICATION_JSON) public Response addNews(News news) { String result = news.toString(); System.out.println(result); return Response.status(201).entity(result).build(); } /** * 以提交表单的方式访问REST服务 */ @POST @Produces(MediaType.TEXT_HTML) @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public void addNews(@FormParam("id")int id,@FormParam("title")String title,@FormParam("content")String content) { News news = new News(); news.setId(id); news.setTitle(title); news.setContent(content); newsService.addNews(news); System.out.println(news.toString()); try { request.getRequestDispatcher("/WEB-INF/success.jsp").forward(request, response);//在服务中进行页面跳转 } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 用URL的方式访问并提交参数到REST服务 * @param uriuInfo * @return */ @Path("parameters") @GET @Produces({MediaType.APPLICATION_JSON}) public News queryNews(@QueryParam("id")int id,@QueryParam("title")String title,@QueryParam("content")String content) { System.out.println("id:"+id+"\t"+"title:"+title+"\t"+"cotent:"+content); News news = new News(); news.setId(id); news.setTitle(title); news.setContent(content); return news; } /** * 默认的GET方法 * @return */ @GET @Produces({MediaType.APPLICATION_JSON}) public News[] getAllNews() { return newsService.queryAllNews(); }}
关于注解:
@Context:把Servlet体系结构中的相关对象诸如到Resource对象
@Path:构成服务的URI
, ,@PUT,@DELETE:作用于方法,表示客户端访问时使用HTTP哪种方法
@Produces:向客户端传输的数据形式
@Consumes:从客户端接受的数据的形式
@QueryParam:已GET方式访问服务时,URL中的参数与Resource类方法参数的对应
此外还有其他注解,用法可以看JAX-RS标准,在包javax.ws.rs内。
3 访问WEB服务
3.1 在浏览器中访问
略
3.2 使用Jersey客户端访问
package com.lin.jersey.test;import java.util.HashMap;import java.util.Map;import javax.ws.rs.client.ClientBuilder;import javax.ws.rs.client.WebTarget;import org.springframework.http.ResponseEntity;import org.springframework.web.client.RestTemplate;import com.lin.jersey.domain.News;import com.sun.jersey.api.client.Client;import com.sun.jersey.api.client.ClientResponse;import com.sun.jersey.api.client.UniformInterfaceException;import com.sun.jersey.api.client.WebResource;public class JerseyClient { public static void main(String[] args) { // testPost(); //testGet(); testGetWithParameter(); } /** * POST 方法 */ private static void testPost() { Client client = Client.create(); WebResource webResource = client .resource("http://localhost:8080/JerseyExample/rest/news"); News news = new News(); news.setId(20); news.setTitle("test"); news.setContent("test"); ClientResponse response; try { response = webResource.type("application/json").post( ClientResponse.class, news); System.out.print(response.toString()); } catch (UniformInterfaceException ue) { System.out.print(ue.getMessage()); } } /** * GET 方法 */ private static void testGet() { try { Client client = Client.create(); WebResource webResource = client .resource("http://localhost:8080/JerseyExample/rest/news"); ClientResponse response = webResource.accept("application/json") .get(ClientResponse.class); if (response.getStatus() != 200) { throw new RuntimeException("Failed : HTTP error code : " + response.getStatus()); } String output = response.getEntity(String.class); System.out.println("Output from Server .... \n"); System.out.println(output); } catch (Exception e) { e.printStackTrace(); } } /** * 有参数的GET方法 */ private static void testGetWithParameter() { try { Client client = Client.create(); WebResource webResource = client .resource("http://localhost:8080/JerseyExample/rest/news/parameters") .queryParam("id","20").queryParam("title", "test").queryParam("content", "test"); ClientResponse response = webResource.accept("application/json") .get(ClientResponse.class); if (response.getStatus() != 200) { throw new RuntimeException("Failed : HTTP error code : " + response.getStatus()); } String output = response.getEntity(String.class); System.out.println("Output from Server .... \n"); System.out.println(output); } catch (Exception e) { e.printStackTrace(); } }}