JAX-RS初探 一:搭建Jersey框架


项目地址:
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
11
package 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
35
package 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
51
package 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
43
package 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日