Jersey 開發RESTful(七)Jersey快速入門
【原創文章,轉載請註明原文章地址,謝謝!】
在之前的文章中,我們已經看到了SpringMVC開發REST應用的方式。但是注意一點,SpringMVC在開發REST應用時,是不支援JSR311/JSR339標準的。如果想要按照標準行事,最常用的實現了這兩個標準的框架就是Jersey和CxF了。但是,因為Jersey是最早的實現,也是JSR311參考的主要物件,所以,可以說Jersey就是事實上的標準(類似Hibernate是JPA的事實上的標準),也是現在使用最為廣泛的REST開發框架之一。
Hello Jersey
首先要理解,Jersey是一個REST框架,既然是REST框架,那自然提供了REST服務相關的一切東西。那麼我們在使用的時候,自然可以和SpringMVC做對比。但是,因為是一個全新的框架,所以自然細節和相關概念會比SpringMVC實現RESTful要多很多,這點需要注意。
Jersey的一大特點就是,基於Jersey的REST應用,可以執行在Servlet環境下面,也可以脫離該環境。下面就分別使用兩種方式來完成Jersey的Hello world。
基於Servlet容器
- 建立一個基於Maven的web專案,在pom.xml中只需要引入一個Jersey的Servlet容器依賴:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.25</version>
</dependency>
- 再引入maven的tomcat外掛:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8082</port>
<path>/</path>
</configuration>
</plugin>
在依賴樹中我們可以看到,Jersey的一些核心庫被引入了進來:
其中,container-servlet-core就是基於Servlet容器的jersey核心庫,common是jersey的核心基礎包,server是jersey核心服務包,在server中還依賴jersey-client包,這個是jersey的客戶端包(可以使用該包非常方便的消費REST服務和測試);
- 修改web.xml,新增一個Jersey的核心servlet(簡單理解為MVC框架中的前端控制器即可):
<servlet>
<servlet-name>JerseyServletContainer</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>cn.wolfcode.jersey</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JerseyServletContainer</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
其中注意ServletContainer即為核心控制器,而jersey.config.server.provider.packages引數一看就是用於掃描jersey中REST服務類所在的包(可以簡單理解為SpringMVC中的component-scan);
- 完成REST服務類
package cn.wolfcode.jersey._01hello;
@Path("hello")
public class HelloService {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hi(){
return "hello jersey";
}
}
簡單解釋一下這段程式碼:
1,注意類是放在cn.wolfcode.jersey._01hello包中,而這個包是我們jersey.config.server.provider.packages引數中配置的包的子包,即該類是能夠被掃描到的;
2,在類上面新增了@Path("hello"),代表資源根路徑為hello,類似於SpringMVC中在類上面新增@RequestMapping("hello");
3,方法hi上面新增了兩個標籤,@GET標籤代表該方法接受GET型別請求,類似於SpringMVC中的@GetMapping標籤;
4,@Produces標籤代表該方法的響應MIME型別為text/plain,類似於@RequestMapping中的produces屬性;
5,該方法返回String,這個String值Jersey會自動按照text/plain格式輸出。
-
啟動tomcat,請求/webapi/hello,得到正確的響應:
使用內建容器
Jersey提供了在SE環境下的部署,即使用內建的伺服器來發布REST服務。提供了對Jetty,JDK HttpServer,Grizzly HttpServer,和一個內建的Simple HttpServer來部署。下面簡單來看一下使用Jetty釋出Jersey服務的例子:
- maven中新增依賴
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>2.21</version>
</dependency>
該依賴裡面包含了jetty相關的jar包及jersey-jetty相關釋出依賴;
- 建立一個Application類,用於設定釋出環境:
package cn.wolfcode.jersey;
public class RestApplication extends ResourceConfig {
public RestApplication(){
this.packages("cn.wolfcode.jersey");
}
}
注意:
1,我們的RestApplication類繼承了ResourceConfig類,ResourceConfig是Jersey中用於配置應用資源的類,在Jersey中,把所有提供REST服務的類,都稱為資源類;
2,ResourceConfig類繼承了Application類,這是Jersey中一個非常基礎的類,用於定義一個JAX-RS應用的基礎元件。
該類實現了org.glassfish.jersey.server.ServerConfig介面,該介面用於註冊應用中的資源元件;
該類還實現了javax.ws.rs.core.Configurable介面,該介面用於向當前應用上下文中註冊一些必要的元件和元資訊(比如後面我們要介紹的Provider)。
3,在RestApplication類的構造方法中,我們呼叫了packages方法註冊了掃描資源類的基礎包;
- 釋出應用
public class App {
public static void main(String[] args) {
JettyHttpContainerFactory.createServer(URI.create("http://localhost:8082/"), new RestApplication());
}
}
新建一個App類,在該類的main方法中,使用包裝好的JettyHttpContainerFactory,來釋出一個應用。第一個引數很簡單,就是釋出的url地址,第二個引數就是傳入一個我們建立的應用配置物件。
注意:使用jetty釋出的時候,不能有虛擬路徑(必須釋出在根路徑上)
-
使用普通Java Application執行main方法,請求localhost:8082/hello,得到正確的響應:
至此,使用兩種方式釋出Jersey的Hello World應用完成。
Jersey基礎應用
下面來介紹Jersey的一些基本使用方式。做一個入門概念,注意,再次強調,Jersey的使用和SpringMVC對比著學習,會非常輕鬆。
資源設定
Jersey中使用@Path註解來設定資源,也支援資源的繼承和路徑引數,下面給出一個示例程式碼:
@Path("path")
public class PathRest {
/**
* 對映url中匹配的佔位符
*
* @param id
* @return
*/
@GET
@Path("{id}")
public String pathParam(@PathParam("id") Long id) {
System.out.println(this);
System.out.println(id);
return "success";
}
}
簡單解釋:
1,PathRest類上面的@Path("path")限制了資源根路徑為/path,而pathParam方法上的@Path("{id}")限制了子資源請求路徑為/path/{id},類似於SpringMVC中的@RequestMapping("{id}")。
2,在請求方法中,使用@PathParam("id")完成從url中對資源佔位符的解析,並同樣支援型別轉化,相當於SpringMVC中的@PathVariable標籤;
JSON和XML
在Jersey中返回JSON型別和XML型別是非常簡單的事情,而且功能比SpringMVC更強。我們先來簡單的看看怎麼使用(下面的案例使用Servlet容器部署的方式,使用Jetty的方式需要額外的操作)。
- 新增JSON和XML的pom.xml依賴
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.25</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.25</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
新增了jersey-media-json-jackson這個依賴包,使用Jackson來完成json和xml的轉化。
- 建立一個Department物件:
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@XmlRootElement
public class Department {
private Long id;
private String name;
}
注意,為了支援XML的生成,我們仍然新增了@XmlRootElement標籤。
- 資源類程式碼:
@Path("dept")
public class DepartmentRest {
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public List<Department> list() {
List<Department> dept = new ArrayList<>();
dept.add(new Department(1L, "dept1"));
dept.add(new Department(2L, "dept2"));
return dept;
}
}
注意:
1,@GET標籤:說明該資源方法是使用get方式請求;
2,@Produces標籤:代表該資源方法生產的響應MIME格式為application/json;
3,@Consumes標籤:代表該資源方法能夠接受請求MIME型別為application/json;
4,在方法中,直接返回department物件的列表;
-
請求GET /dept
可以看到,Jersey會自動的根據@Produces產生的資料來生成響應內容。我們再來看看XML的生成方式,只需要在資源類中增加一個方法:
@GET
@Produces(MediaType.APPLICATION_XML)
@Consumes(MediaType.APPLICATION_XML)
public List<Department> listXml() {
List<Department> dept = new ArrayList<>();
dept.add(new Department(1L, "dept1"));
dept.add(new Department(2L, "dept2"));
return dept;
}
可以看到,唯一的區別就是@Produces和@Consumes的型別設定為application/xml。
這次,再請求的時候,注意我們需要設定客戶端的Accepts為application/xml:
得到的請求結果為:
正確得到XML的結果。
- 合併
在上面的例子中,我們是通過兩個資源方法來完成JSON和XML格式的內容輸出,其實Jersey中提供了更合理的方式,把兩段程式碼合併起來:
@GET
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
@Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public List<Department> list() {
List<Department> dept = new ArrayList<>();
dept.add(new Department(1L, "dept1"));
dept.add(new Department(2L, "dept2"));
return dept;
}
可以看到,我們在@Produces和@Consumes中分別設定了我們要支援的application/xml和application/json格式,在請求的時候,分別設定Accepts為application/xml或者application/json,就可以得到JSON或者XML格式了!!這點是SpringMVC做不到的,而且更直接的反應出REST的概念!
請求型別設定
每個方法接受固定的請求型別,這個也是REST的基本需求之一。在SpringMVC中,通過@RequestMapping(method=XXX)來設定。在Jersey中,提供了一些更為簡單的標籤來設定,下面提供一組CRUD操作示例:
@GET //1
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_XML)
public List<Department> list() {
List<Department> dept = new ArrayList<>();
dept.add(new Department(1L, "dept1"));
dept.add(new Department(2L, "dept2"));
return dept;
}
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_XML)
public Department get(@PathParam("id") Long id) {
return new Department(id, "dept2");
}
@POST //2
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_XML)
public Department save(@FormParam("name") String name) {
Department d = new Department(1L, name);
return d;
}
@PUT //3
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_XML)
public Department update(@PathParam("id") Long id, @FormParam("name") String name) {
Department d = new Department(id, name);
return d;
}
@DELETE //4
@Path("{id}")
@Consumes(MediaType.APPLICATION_XML)
public void delete(@PathParam("id") Long id) {
System.out.println("刪除部門:" + id);
}
為了不引入更多額外的內容,只展示了一個簡單的CRUD。其中:
1,@GET註解之前已經提到過,表示接受GET型別請求,類似@GetMapping;
2,@POST,表示接受POST型別請求,類似@PostMapping,或者@RequestMapping(method=RequestMethod.POST);其次注意,在save方法引數列表中出現了@FormParam("name"),代表name引數對映請求的form表單中的name名稱的欄位值;關於引數繫結,Jersey還是提供了相當多的註解來對映,後面再介紹。
3,@PUT,表示接受POST型別請求,類似@RequestMapping(method=RequestMethod.PUT);
4,@DELETE,表示接受DELETE型別請求,類似@RequestMapping(method=RequestMethod.DELETE);
5,另外,Jersey還提供了@HEAD,@OPTIONS,看名字對應的就是HEAD和OPTIONS兩種請求方式,但是需要注意的一點就是Jersey沒有提供針對PATCH 和 TRACE這兩種請求方式的對應註解。
小結,至此,最基礎的Jersey的使用快速的瞭解的一下。可以看到,Jersey確實在REST語義方面的支援比SpringMVC還要簡單和直接,的的確確是一個REST服務開發的非常優秀的框架。後面針對Jersey的各個部分做詳細介紹。
相關文章
- Jersey 開發RESTful(十)Jersey的配置REST
- 使用 Jersey 和 Apache Tomcat 構建 RESTful Web 服務ApacheTomcatRESTWeb
- Jersey—建立restfulwebservice—例項RESTWeb
- 使用Kotlin + Jersey + Jetty + MongoDB建立可擴充套件的RESTful API - AndrewKotlinJettyMongoDB套件RESTAPI
- JERSEY學習遇到的問題
- jersey 框架傳輸格式 (2) xml框架XML
- Jersey 框架取到所有引數的方法框架
- Jersey2.x分支JavaSE相容性Java
- HarmonyOS快速開發入門
- 前端開發快速入門前端
- Jersey2.x從MavenArchetype建立一個新專案Maven
- 度量快速開發平臺——快速入門
- yii2 restful web服務快速入門RESTWeb
- RESTful入門REST
- GO 語言快速開發入門Go
- Koa2開發快速入門
- 從一次編譯出發梳理概念: Jetty,Jersey,hk2,glassFish,Javax,Jakarta編譯JettyJava
- Web開發初探之JavaScript 快速入門WebJavaScript
- 開發環境配置pyenv快速入門開發環境
- Apple Watch開發快速入門教程APP
- OUYA遊戲開發快速入門教程遊戲開發
- 一、鴻蒙開發-ArkTS快速入門鴻蒙
- Spring Boot入門系列(二十)快速打造Restful API 介面Spring BootRESTAPI
- Fan Jersey智慧T恤:可調動穿戴者的情緒很神奇
- 通俗易懂的ArcGis開發快速入門
- Util應用框架快速入門(4) - 整合測試開發入門框架
- java JAX-RS快速開發RESTful服務JavaREST
- HealthKit開發快速入門教程之HealthKit開發概述簡介
- QT開發快速入門-教程1:搭建QT開發環境QT開發環境
- 小豬的C語言快速入門系列(七)C語言
- Transform元件C#遊戲開發快速入門ORM元件C#遊戲開發
- 用 Go 快速開發一個 RESTful API 服務GoRESTAPI
- 遊戲控制桿OUYA遊戲開發快速入門教程遊戲開發
- ?HealthKit開發快速入門教程大學霸內部教程
- 介面開發-restfulREST
- 快速排序快速入門排序
- HealthKit開發快速入門教程之HealthKit資料的操作
- 七天.NET 8操作SQLite入門到實戰 - 第三天SQLite快速入門SQLite