ResponseEntity 表示整个HTTP响应:状态代码,标题和正文。因此,我们可以使用它来完全配置HTTP响应,它是一个对象,而 @ResponseBody 和@ResponseStatus是注解,适合于简单直接的场合。
@ResponseBody 一般与@Controller组合使用,用来返回JSON字符串:
而ResponseStatus一般与RestController组合使用:
@ResponseStatus无法设置标题,也无法设置HttpServletResponse或HttpHeaders参数,但是很简单方便。
ResponseEntity让你做更多的定制工作。
ResponseEntity 是一种泛型类型。因此,我们可以使用任何类型作为响应主体:
@Controller public class XXXController{ @GetMapping("/hello") public ResponseEntity<String> hello() { return new ResponseEntity<>("Hello World!", HttpStatus.OK); }
这里字符串"Hello World!"作为字符串返回给REST端。
我们可以设置HTTP标头:
@GetMapping("/customHeader") ResponseEntity<String> customHeader() { HttpHeaders headers = new HttpHeaders(); headers.add("Custom-Header", "foo"); return new ResponseEntity<>( "Custom header set", headers, HttpStatus.OK); }
设置自定义标头:
@GetMapping("/customHeader") ResponseEntity<String> customHeader() { return ResponseEntity.ok() .header("Custom-Header", "foo") .body("Custom header set")
如果将一个对象放入:
@GetMapping("/hello") public ResponseEntity<String> hello() { return new ResponseEntity<>(new User(‘jdon’), HttpStatus.OK); }
返回是JSON字符串:
[ { ‘name’: 'jdon'}]
下面是返回对象的JSON列表:
public ResponseEntity<List<ProcessDef>> repositoryProcessDefinitionsGet() { return new ResponseEntity<>(processDefRepo.findAll(), HttpStatus.FOUND); }
以上是通过ResponseEntity这个对象在代码中灵活操控响应,但是在一般情况下我们只是想返回一个带有数据的正常响应,那么只要使用@注解即可
在类级别使用@Controller标注情况下 , @ResponseBody 注解告诉返回的对象将自动序列化为JSON,并通过回控制器 的HttpResponse 对象。
@Controller public class XXXController{ @ResponseBody public User postResponseController(@RequestBody LoginForm loginForm) { return new User("Thanks For Posting!!!"); }
将返回客户端JSON字符串:
[ { ‘name’: Thanks For Posting!!!"}]
在@RestController注解了类的情况下,我们就不需要再使用 @ResponseBody 了,可以直接返回对象,并使用ResponseStatus返回状态码!
ResponseStatus虽然只是规定了返回的状态,但是只需要标注在方法上,简单,而且状态码与返回类型分离,比较清晰。我们将上面返回对象列表的代码使用ResponseStatus改写如下,注意类级别@RestController:
@RestController public class XXXController{ @ResponseStatus(HttpStatus.FOUND) public User postResponseController() { return new User("Thanks For Posting!!!"); }
这也会返回客户端JSON字符串:
[ { ‘name’: Thanks For Posting!!!"}]
这样的代码更加专注于业务。
Spring还允许我们直接访问 javax.servlet.http.HttpServletResponse 对象; 我们只需要将它声明为方法参数:
@GetMapping("/manual") public void manual(HttpServletResponse response) throws IOException { response.setHeader("Custom-Header", "foo"); response.setStatus(200); response.getWriter().println("Hello World!"); }
由于Spring在底层实现之上提供了抽象和附加功能,因此 如果以这种方式直接操纵响应,会失去很多Spring提供方便功能 。
@RestController + @ResponseStatus = @Controller + @ResponseBody