项目地址:
https://github.com/FateSolo/JSH-Test
目录:
JAX-RS(JSR-311 & JSR-339标准),全称Java API for RESTful Web Services,旨在定义一个统一的规范,使得Java程序员可以使用一套固定的接口来开发RESTful应用,避免了依赖于第三方框架。
RESTful,全称Representational State Transfer,是一种网络服务设计风格,将所有的URI都视为资源,在URI中只包含名词而没有动词,以HTTP的四种方法来对资源进行操作。
JAX-RS与JPA类似,都是标准却没有实现,需要第三方来提供具体实现,而Jersey框架就是Sun公司推出的JSR-311的参考实现,本章将使用Jersey框架搭建一个RESTful服务。
项目环境:
- Ubuntu 14.04.3
- Intellij IDEA 15.0.2
1. 项目搭建:
1) 打开IDEA,点击Create New Project,在左侧边栏找到Gradle,并勾选Java和Web,JDK选择1.8。
2) 点击Next,GroupId:com.fatesolo;ArtifactId:JSH-Test。
3) 点击Next,勾选Use auto-import和Create directories for…。
4) 点击Next,直接Finish即完成了项目的创建。
2. 配置依赖
1) 打开build.gradle文件, 在dependencies中,加入Jersey相关依赖:1
/**
* Jersey
*/
compile 'org.glassfish.jersey.containers:jersey-container-servlet-core:2.25.1'
3. 编写web.xml
1) 打开web.xml,编写如下配置:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>JSH-Test</display-name>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>JSH-Test.root</param-value>
</context-param>
<!-- Jersey -->
<servlet>
<servlet-name>Jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.fatesolo.jsh.application.Application</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
4. 编写基础代码
1) 在com.fatesolo.jsh下建立application子包,并创建Application类,继承ResourceConfig,用来注册Jersey下的各种资源:1
2
3
4
5
6
7
8
9
10
11package com.fatesolo.jsh.application;
import org.glassfish.jersey.server.ResourceConfig;
public class Application extends ResourceConfig {
public Application() {
}
}
2) 建立entity子包,存放实体,这里以书籍Book为例,编写Book的实体代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35package com.fatesolo.jsh.entity;
public class Book {
private int id;
private String name;
private String author;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
3) 再创建Result类,作为请求的响应实体:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51package com.fatesolo.jsh.entity;
public class Result {
private String code;
private String msg;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public static Result success(String msg) {
Result result = new Result();
result.setCode("SUCCESS");
result.setMsg(msg);
return result;
}
public static Result success() {
return success(null);
}
public static Result failure(String msg) {
Result result = new Result();
result.setCode("FAILURE");
result.setMsg(msg);
return result;
}
public static Result failure() {
return failure(null);
}
}
4) 建立resource子包,并创建BookResource类,编写如下代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43package com.fatesolo.jsh.resource;
import com.fatesolo.jsh.entity.Book;
import com.fatesolo.jsh.entity.Result;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;
@Path("/book")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class BookResource {
@GET
@Path("/{id}")
public Book getBookById(@PathParam("id") int id) {
Book book = new Book();
book.setId(id);
book.setName("Book " + id);
book.setAuthor("Author " + id);
return book;
}
@GET
@Path("/")
public List<Book> getBooks() {
List<Book> books = new ArrayList<>();
books.add(getBookById(1));
books.add(getBookById(2));
books.add(getBookById(3));
return books;
}
@POST
@Path("/")
public Result addBook(Book book) {
return Result.success(book.getName());
}
}
这里只是简单new了一个实体作为返回,方便测试。
5) 资源类若想被访问到,需要在Application类中注册,在Application的默认构造函数中增加如下代码:1
register(BookResource.class);
6) 在BookResource中,@Consumes和@Produces分别限定了Content-Type和Accept的类型,这里限定只接受和返回xml类型数据,所以要在User和Result两个实体类上加xml注解:1
@XmlRootElement
5. 项目运行:
1) 使用Tomcat 8运行项目,使用curl工具添加一条数据:1
curl -H "Content-Type:application/xml" -d "<book><name>Book</name><author>Fate</author></book>" http://localhost:8080/rest/book
得到如下返回:1
2
3
4<result>
<code>SUCCESS</code>
<msg>Book</msg>
</result>
2) 访问http://localhost:8080/rest/book/1 ,得到如下结果:1
2
3
4
5<book>
<author>Author 1</author>
<id>1</id>
<name>Book 1</name>
</book>
3) 访问http://localhost:8080/rest/book ,得到如下结果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<books>
<book>
<author>Author 1</author>
<id>1</id>
<name>Book 1</name>
</book>
<book>
<author>Author 2</author>
<id>2</id>
<name>Book 2</name>
</book>
<book>
<author>Author 3</author>
<id>3</id>
<name>Book 3</name>
</book>
</books>
至此,Jersey框架搭建完毕。
作者 [@FateSolo]
2017 年 03月 22日