REST 是英文 Representational State Transfer 的缩写,有中文翻译为“表述性状态转移”。REST 这个术语是由 Roy Fielding 在他的博士论文 《 Architectural Styles and the Design of Network-based Software Architectures 》中提出的。REST 并非标准,而是一种开发 Web 应用的架构风格,可以将其理解为一种设计模式。REST 基于 HTTP,URI,以及 XML 这些现有的广泛流行的协议和标准,伴随着 REST,HTTP 协议得到了更加正确的使用。
Jersy是一个业内使用非常广泛的Java Rest框架,本文就Jersey(2.13版本)的快速使用进行简单介绍,如需要了解更多的高级用法请查看官方的文档。
1、在pom.xml中加入jersey相关依赖
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-grizzly2-servlet</artifactId>
    <version>2.13</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet-core</artifactId>
    <version>2.13</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.13</version>
</dependency>
2、配置web.xml文件
<servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.devzeng.demo.api</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Jersey REST Service<rvlet-name>
	<url-pattern>/api/*</url-pattern>
</servlet-mapping>
3、开发
@Path("/api")
public class HelloApiService {
    @POST
	@Path("save")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	@Produces(MediaType.APPLICATION_JSON)
	public String save(@FormParam("data") String data) {
		return "{\"message\":\"save\"}";
	}
	
	@GET
	@Path("list")
	@Produces(MediaType.APPLICATION_JSON)
	public String list(@QueryParam("from") String from, @QueryParam("to") String to) {
		return "{\"message\":\"list\"}"; 
	}
	
	@GET
	@Path("detail/{id}")
	@Produces(MediaType.APPLICATION_JSON)
	public String detail(@PathParam("id") String id) {
		return "{\"message\":\"detail\"}"; 
	}
}
说明:
(1)跨域问题解决
如果编写的API接口需要给前端进行调用,通常会遇到跨域的问题,可以使用下面的方式进行解决:
@Provider
public class SceduleApiServiceCorsFilter implements ContainerResponseFilter {
	public void filter(ContainerRequestContext creq, ContainerResponseContext cres) throws IOException {
		cres.getHeaders().add("Access-Control-Allow-Origin", "*");
        cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
        cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
        cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        cres.getHeaders().add("Access-Control-Max-Age", "1209600");
	}
	
}
(2)JSON & XML处理
对于REST的接口通常需要返回的数据格式是JSON、XML。如果每次都是使用JSONObject这样的库来进行拼接,也是一件很麻烦的事情,为何不能直接返回对应的POJO对象呢。Jersey就支持这样的处理,为了让项目结构比较清晰,推荐建立一个单独的package(如com.devzeng.rest.pojo),在该package创建一个POJO对象MyCustomBean。
public class MyCustomBean {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
}
1)JSON处理
@GET
@Path("hellojson")
@Produces(MediaType.APPLICATION_JSON)
public MyCustomBean sayHelloWithJson() {
    MyCustomBean bean = new MyCustomBean();
    bean("tom");
    bean.setAge(20);
    return bean;
}
说明:
① Produces注解需要指定返回的数据格式是JSON格式(MediaType.APPLICATION_JSON)。
② 如果启动之后报如下错误:
org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor aroundWriteTo
表示POJO对象没有被序列化成JSON对象,需要添加相关的库,推荐使用jersey-media-json-jackson模块:
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.13</version>
</dependency>
2) XML处理
@GET
@Path("helloxml")
@Produces(MediaType.APPLICATION_XML)
public MyCustomBean sayHelloWithXML() {
    MyCustomBean bean = new MyCustomBean();
    bean("tom");
    bean.setAge(20);
    return bean;
}
① Produces注解需要指定返回的数据格式是XML格式(MediaType.APPLICATION_XML)。
② 启动项目之后如果报如下错误:
org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor aroundWriteTo
需要在POJO对象上面加上@XmlRootElement,@XmlRootElement表示将一个类或者是枚举类型映射成为一个XML元素。
(3)中文乱码问题
1) 推荐将项目的所有格式设置为UTF-8;
2) 如果还存在中文乱码的问题,需要将
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")