ResponseEntity實現Rest風格的返回值
簡介
在前面,我們使用了@ResponseBody注解和@RestController注解,其作用就不多說了,但是問題就來了,如果想向前段返回一個狀態碼該怎么實現呢?
我們知道響應頭並不屬於響應體,所以即使使用自己封裝的Bean加入狀態碼屬性,也只能在前段獲取一個所謂的狀態碼而已,在RESTful風格中,我們要明確的返回正確的狀態碼。那么單單使用@ResponseBody就不夠用了。
@ResponseStatus
前面我們說到@ResponseBody不能正確的返回響應狀態碼,於是出現了@ResponseStatus注解,帶有@ResponseStatus注解的異常類會被ResponseStatusExceptionResolver 解析。可以實現自定義的一些異常,同時在頁面上進行顯示。具體的使用方法如下:
1.首先定義一個異常類:
@ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "用戶名和密碼不匹配!")
public class UserNameNotMatchPasswordException extends RuntimeException{
}
2.人為拋出一個異常:
@RequestMapping("/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
if (i==13){
throw new UserNameNotMatchPasswordException();
}
System.out.println("testResponseStatusExceptionResolver....");
return "success";
}
3.輸入如下額路徑:
http://localhost:8090/testResponseStatusExceptionResolver?i=13
此時瀏覽器會顯示403,以及用戶名密碼不匹配。
當然,也可以在方法上進行修飾:
@ResponseStatus(reason = "測試",value = HttpStatus.NOT_FOUND)
@RequestMapping("/testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
if (i==13){
throw new UserNameNotMatchPasswordException();
}
System.out.println("testResponseStatusExceptionResolver....");
return "success";
}
這時所有的請求都會報錯。
不過我們也不會使用這個注解,會使用全局的異常處理。詳見上篇。
ResponseEntity
它是Spring提供的一個類,它內部封裝了狀態碼,請求頭,請求體等信息,用戶可以根據自己的需要修改狀態碼、請求體的信息。ResponseEntity
HttpStatus
這是Spring提供的一個枚舉類,其遵循RESTful風格封裝了大量了響應狀態碼。詳見org.springframework.http.HttpStatus;
如何使用ResponseEntity
使用構造返回,其中第一個參數為響應體,第二個為響應碼
//使用構造參數構建
new ResponseEntity<String>("return info",HttpStatus.BAD_REQUEST);
//使用構造參數構建
new ResponseEntity<JavaBean>(javaBean,HttpStatus.BAD_REQUEST);
使用status設置響應碼,body指定響應頭
//使用status方法和body方法
ResponseEntity.status(HttpStatus.CREATED).body(javaBean);
//使用status方法和body方法
ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
另外還可以設置響應頭:
@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "foo");
return new ResponseEntity<>(
"Custom header set", headers, HttpStatus.OK);
}
如果只是返回一個狀態碼為200的內容,可以簡寫為:
@GetMapping("/hello")
ResponseEntity<String> hello() {
return ResponseEntity.ok("Hello World!");
}
最后強調一下:BodyBuilder.body()返回ResponseEntity ,所以需要最后調用。
使用HttpServletResponse response
Spring同樣支持我們使用HttpServletResponse對象來操作請求頭和請求體,用法如下:
@GetMapping("/manual")
void manual(HttpServletResponse response) throws IOException {
response.setHeader("Custom-Header", "foo");
response.setStatus(200);
response.getWriter().println("Hello World!");
}
既然spring已經提供底層實現的抽象和附件功能,我們不建議直接操作response。
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
ResponseEntity.ok(list);
ResponseEntity.badRequest().build();
ResponseEntity.notFound().build();
上述是比較簡單的兩種用法,分別是500和200、400、404