javax.wx.rs RESTful 接口詳解
- Restful介紹
- 準備
- 請求路徑、請求方式
- @Path,GET,POST,PUT,DELETE
- @Consumes
- @Consumes
- @Produces
- @PathParam
- @QueryParam
- @FormParam
- @BeanParam
- @DefaultValue
- @FormDataParam
- @HeaderParam
- @CookieParam
- @MatrixParam
- @Context
- @Encoded
- 例子
- 擴充--mvc實作的rest注解
Restful介紹
java.ws.rs是jax-rs規範中定義的包名.jax-rs全稱Java API for RESTful Services.jax-rs規範目前版本是2.0規範文檔.
jax-rs中定義了
- 一組啟動方式 (以jee作為http容器 還是配合servlet作為http容器)
- 一組注解@GET, @POST, @DELETE, @PUT, @Consumes … 通過 POJO Resource類 提供Rest服務
如JSR規範定義Servlet是以繼承HttpServlet 并重寫doGet doPost do…方法一樣。遵循這套标準都可以稱為Servlet 寫的Servlet程式,可以不經過任何修改放到任何實作Servlet容器中運作,寫的jax-rs程式可以不經任何修改和任何jax-rs架構配合使用。
而Spring MVC是以Servlet為http容器 并自己建構了一套Api沒有遵循jax-rs規範。
目前實作jax-rs标準的架構有很多:
- Apache CXF開源的Web服務架構
- Jersey 由Sun提供的JAX-RS的參考實作
- RESTEasy JBoss的實作
- Restlet 由Jerome Louvel和Dave Pawson開發 是最早的REST架構 先于JAX-RS出現
- Apache Wink 一個Apache軟體基金會孵化器中的項目 其服務子產品實作JAX-RS規範
準備
建立這樣一個微服務用于體驗,測試這些注解

請求路徑、請求方式
@Path,GET,POST,PUT,DELETE
- 标注class時 表明該類是個資源類 凡是資源類必須使用該注解
- 标注method時 表示具體的請求資源的路徑
Path不能單獨使用,至少需要和請求方式配合使用。
比如
@Path("path")
public class PathController {
@GET
public String defaultMethod() {
return "default method for path";
}
}
如果沒有請求方式編譯器會有檢測:
Class doesn't contain any JAX-RS annotated methods
@Consumes
指定HTTP請求的MIME類型
預設是
*/*
表示任意的MIME類型
該注解支援多個值設定
可以使用MediaType來指定MIME類型
MediaType的類型大緻有
- application/xml
- application/atom+xml
- application/json
- application/svg+xml
- application/x-www-form-urlencoded
- application/octet-stream
- multipart/form-data
- text/plain
- text/xml
- text/html
@Consumes
指定HTTP請求的MIME類型
預設是
*/*
表示任意的MIME類型
該注解支援多個值設定
可以使用MediaType來指定MIME類型
MediaType的類型大緻有
- application/xml
- application/atom+xml
- application/json
- application/svg+xml
- application/x-www-form-urlencoded
- application/octet-stream
- multipart/form-data
- text/plain
- text/xml
- text/html
@Produces
指定HTTP響應的MIME類型
預設是
*/*
表示任意的MIME類型
MediaType的類型大緻有
- application/xml
- application/atom+xml
- application/json
- application/svg+xml
- application/x-www-form-urlencoded
- application/octet-stream
- multipart/form-data
- text/plain
- text/xml
- text/html
@PathParam
參數注解,從url中擷取參數
@QueryParam
參數注解,從url中擷取參數,用于GET請求。
GET請求會将參數拼接在url中。
http://www.baidu.com/s?wd=x
其中的wd就是GET請求的參數
@FormParam
用于擷取POST請求且以form(MIME類型為application/x-www-form-urlencoded)方式送出的表單的參數
@BeanParam
如果傳遞的較多 使用@FormParam等參數注解一個一個的接收每個參數可能顯得太臃腫
可以通過Bean方式接收自定義的Bean
在自定義的Bean中字段使用@FormParam等參數注解
隻需定義一個參數接收即可
@DefaultValue
配合前面的參數注解等使用 用來設定預設值
如果請求指定的參數中沒有值
通過該注解給定預設值
@FormDataParam
用于擷取POST請求且以form(MIME類型為multipart/form-data)方式送出的表單的參數
通常是在上傳檔案的時候
@HeaderParam
用于擷取HTTP請求頭中的參數值
@CookieParam
用于擷取HTTP請求cookie中的參數值
@MatrixParam
可以用來綁定包含多個property (屬性)=value(值) 方法參數表達式
用于擷取請求URL參數中的鍵值對
必須使用’;'作為鍵值對分隔符
注意MatrixParam與QueryParam的差別
QueryParam請求url的格式為 url?key1=value1&key2=value2&…
MatrixParam請求url的格式為 url;key1=value1;key2=value2;…
@Context
用來用來解析上下文參數
和Spring中的AutoWired效果類似
通過該注解可以擷取
ServletConfig
ServletContext
HttpServletRequest
HttpServletResponse
HttpHeaders
等資訊
@Path("/user")
publicclass Resource {
@Context
HttpServletRequest req;
@Context
ServletConfig servletConfig;
@Context
ServletContext servletContext;
@GET
public String get(@Context HttpHeaders hh) {
MultivaluedMap<String, String> headerParams = hh.getRequestHeaders();
Map<String, Cookie> pathParams = hh.getCookies();
}
}
@Encoded
禁止解碼
用戶端發送的參數是什麼樣
伺服器就原樣接收
例子
我們寫了8個方法:
@Path("path")
public class PathController {
@GET
public String defaultGetMethod() {
return "default method for get path";
}
@POST
public String defaultPostMethod() {
return "default method for post path";
}
@PUT
public String defaultPutMethod() {
return "default method for put path";
}
@DELETE
public String defaultDeleteMethod() {
return "default method for delete path";
}
@GET
@Path("hello")
public String getHello() {
return "hello method for get path";
}
@POST
@Path("hello")
public String postHello() {
return "hello method for post path";
}
@PUT
@Path("hello")
public String putHello() {
return "hello method for put path";
}
@DELETE
@Path("hello")
public String deleteHello() {
return "hello method for delete path";
}
}
請忽略我不正确的請求方式的使用。
使用postMan測試,或者使用idea的web Client的插件
使用httpClient
GET http://localhost:8080/path
###
POST http://localhost:8080/path
###
PUT http://localhost:8080/path
###
DELETE http://localhost:8080/path
###
GET http://localhost:8080/path/hello
###
POST http://localhost:8080/path/hello
###
PUT http://localhost:8080/path/hello
###
這是consumes的例子
import com.study.jrest.domain.Student;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
/**
* @author jiayq
* @Date 2021-04-03
*/
@Path("consumes")
public class ConsumesController {
@GET
@Consumes(MediaType.WILDCARD)
public String consumeGet(@QueryParam("name") String name) {
return "consume get , " + name;
}
@GET
@Path("{name}")
public String consumeGetPath(@PathParam("name") String name) {
return "consume get path , " + name;
}
@POST
public String consumePost(@MatrixParam("name") String name) {
return "consume post , " + name;
}
@POST
@Path("/post/{name}")
public String consumePostPath(@PathParam("name") String name) {
return "consume post path , " + name;
}
@Path("stu")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public String consumeStu(Student student) {
return "consume student , " + student;
}
@Path("stu/bean")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String consumeStuBean(@BeanParam Student student) {
return "consume student bean , " + student;
}
}
import lombok.Data;
import javax.ws.rs.FormParam;
/**
* @author jiayq
* @Date 2021-04-01
*/
@Data
public class Student {
@FormParam("id")
private Long id;
@FormParam("name")
private String name;
@FormParam("age")
private Integer age;
}
GET http://localhost:8080/consumes?name=xiaohua
###
GET http://localhost:8080/consumes/xiaomei
###
POST http://localhost:8080/consumes;name=xiaomei
###
POST http://localhost:8080/consumes/post/xiaomei
###
POST http://localhost:8080/consumes/stu
Content-Type: application/json
{"id":1,"name":"demoData","age":1}
###
POST http://localhost:8080/consumes/stu
id=1;name=demoData;age=1
###
POST http://localhost:8080/consumes/stu/bean
Content-Type: application/x-www-form-urlencoded
id=1&name=xiaomei&age=23
comsumes是請求的傳參類型,也就是請求頭中的
Content-Type: application/x-www-form-urlencoded
字段
這是Produces的例子
import com.study.jrest.domain.Student;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Map;
/**
* @author jiayq
* @Date 2021-04-03
*/
@Path("produces")
public class ProducesController {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String produceGet(@QueryParam("name") String name) {
return "produces get query param , " + name;
}
@POST
@Produces(MediaType.TEXT_HTML)
public String producePost(@MatrixParam("name") String name) {
return "produces post query param , <b>" + name + "</b>";
}
@GET
@Path("get/{name}")
@Produces(MediaType.APPLICATION_JSON)
public Map<String, String> produceGetPath(@PathParam("name") String name) {
return Map.of("result", "produces get path", "param",name);
}
@POST
@Path("post")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Student producesGetStudent(@FormParam("name") String name) {
Student student = new Student();
student.setId(0L);
student.setName(name);
student.setAge(0);
return student;
}
}
這是測試的封包
GET http://localhost:8080/produces?name=xiaomei
Accept: text/plain
###
POST http://localhost:8080/produces;name=xiaomei
Accept: text/html
###
GET http://localhost:8080/produces/get/xiaomei
Accept: application/json
###
POST http://localhost:8080/produces/post
Accept: application/json
Content-Type: application/x-www-form-urlencoded
name=xiaomei
Produces配置的是傳回結果的類型,也就是請求頭中的Accept字段
擴充–mvc實作的rest注解
mvc注解 | ws.rs注解 | 等價的mvc注解 |
RequestMapping | Path | |
GetMapping | GET | RequestMapping(method = RequestMethod.GET) |
PostMapping | POST | RequestMapping(method = RequestMethod.POST) |
PutMapping | PUT | RequestMapping(method = RequestMethod.PUT) |
DeleteMapping | DELETE | RequestMapping(method = RequestMethod.DELETE) |
PathVariable | PathParam | |
MatrixVariable | MatrixParam | |
RequestHeader | HeaderParam | |
RequestBody | Encoded | |
RequestParam | QueryParam | |
RequestPart | FormDataParam | |
CookieValue |