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
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>JerseyExample</groupId>
<artifactId>JerseyExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>JerseyExample</name>
<description />
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>snapshot-repository.java.net</id>
<name>Java.net Snapshot Repository for Maven</name>
<url>https://maven.java.net/content/repositories/snapshots/</url>
<layout>default</layout>
</repository>
</repositories>
<dependencies>
<!-- Jersey server -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<!-- Jersey client -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.8</version>
</dependency>
<!-- http://mvnrepository.com/artifact/com.sun.jersey/jersey-json -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.8</version>
</dependency>
<!-- Spring 4 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!-- Jersey + Spring -->
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.8</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 处理json -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.8</version>
</dependency>
<!-- jsp接口 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- servlet接口 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<version>3.1</version>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.1.2 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>JerseyExample</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>jersey-serlvet</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.lin.jersey.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
2.2 domain类
package com.lin.jersey.domain;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public 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 List<News> newsDAO = new ArrayList<News>();
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<newsDAO.size();i++)
{
if(newsDAO.get(i).getId() == id)
{
newsDAO.remove(i);
return;
}
}
}
/**
* update
* @param news
*/
public void updateNews(News news)
{
News temp = null;
for(int i=0;i<newsDAO.size();i++)
{
temp = newsDAO.get(i);
if(temp.getId() == news.getId())
{
newsDAO.remove(i);
newsDAO.add(news);
return;
}
}
}
/**
* read
* @param id
* @return
*/
public News queryNews(int id)
{
for(News news : newsDAO)
{
if(news.getId() == id)
{
return news;
}
}
return null;
}
/**
* read all
* @return
*/
public News[] queryAllNews()
{
News[] newsArray = new News[newsDAO.size()];
for(int i=0;i<newsDAO.size();i++)
{
newsArray[i] = newsDAO.get(i);
}
return newsArray;
}
}
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
@GET ,@POST ,@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();
}
}
}