当为Spring REST风格的应用程序使用ResponseEntity <T>和@RestController时
我正在使用Spring Framework 4.0.7以及MVC和Rest
我可以和平地工作:
@Controller-  
ResponseEntity<T> 
例如:
 @Controller @RequestMapping("/person") @Profile("responseentity") public class PersonRestResponseEntityController { 
用这个方法(只是为了创build)
 @RequestMapping(value="/", method=RequestMethod.POST) public ResponseEntity<Void> createPerson(@RequestBody Person person, UriComponentsBuilder ucb){ logger.info("PersonRestResponseEntityController - createPerson"); if(person==null) logger.error("person is null!!!"); else logger.info("{}", person.toString()); personMapRepository.savePerson(person); HttpHeaders headers = new HttpHeaders(); headers.add("1", "uno"); //http://localhost:8080/spring-utility/person/1 headers.setLocation(ucb.path("/person/{id}").buildAndExpand(person.getId()).toUri()); return new ResponseEntity<>(headers, HttpStatus.CREATED); } 
返回一些东西
 @RequestMapping(value="/{id}", method=RequestMethod.GET) public ResponseEntity<Person> getPerson(@PathVariable Integer id){ logger.info("PersonRestResponseEntityController - getPerson - id: {}", id); Person person = personMapRepository.findPerson(id); return new ResponseEntity<>(person, HttpStatus.FOUND); } 
工作正常
我可以这样做 :
-   
@RestController(我知道这是@Controller+@ResponseBody相同) -  
@ResponseStatus 
例如:
 @RestController @RequestMapping("/person") @Profile("restcontroller") public class PersonRestController { 
用这个方法(只是为了创build)
 @RequestMapping(value="/", method=RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) public void createPerson(@RequestBody Person person, HttpServletRequest request, HttpServletResponse response){ logger.info("PersonRestController - createPerson"); if(person==null) logger.error("person is null!!!"); else logger.info("{}", person.toString()); personMapRepository.savePerson(person); response.setHeader("1", "uno"); //http://localhost:8080/spring-utility/person/1 response.setHeader("Location", request.getRequestURL().append(person.getId()).toString()); } 
返回一些东西
 @RequestMapping(value="/{id}", method=RequestMethod.GET) @ResponseStatus(HttpStatus.FOUND) public Person getPerson(@PathVariable Integer id){ logger.info("PersonRestController - getPerson - id: {}", id); Person person = personMapRepository.findPerson(id); return person; } 
我的问题是:
- 当出于坚实的理由或具体情况时,必须强制使用一个选项
 - 如果(1)无关紧要,build议采取什么方法,为什么。
 
  ResponseEntity旨在表示整个HTTP响应。 您可以控制进入它的任何内容:状态码,标题和正文。 
  @ResponseBody是HTTP响应主体的标记, @ResponseStatus声明了HTTP响应的状态码。 
  @ResponseStatus不是很灵活。 它标记了整个方法,所以你必须确保你的处理器方法总是以相同的方式运行。 而且您仍然无法设置标题。 你需要HttpServletResponse或HttpHeaders参数。 
 基本上, ResponseEntity让你做更多。 
从Sotorios Delimanolis完成答案。
 的确, ResponseEntity给了你更多的灵活性,但是在大多数情况下你不需要它,你的控制器到处都会有这个ResponseEntity ,所以很难阅读和理解。 
 如果你想处理像错误(Not Found,Conflict等)的特殊情况,你可以在你的Springconfiguration中添加一个HandlerExceptionResolver 。 因此,在你的代码中,你只需要抛出一个特定的exception(例如NotFoundException ),并决定在你的Handler中做什么(把HTTP状态设置为404),使Controller代码更清晰。 
根据官方文档: 使用@RestController注释创buildREST控制器
@RestController是一个结合了@ResponseBody和@Controller的构造型注释。 更重要的是,它给你的控制器带来了更多的意义,也可能在框架的未来版本中带来额外的语义。
 看起来最好使用@RestController来清晰起见,但是你也可以在需要的时候把它和ResponseEntity 结合起来使用( 根据官方的教程和代码以及我的问题来确认 )。 
例如:
 @RestController public class MyController { @GetMapping(path = "/test") @ResponseStatus(HttpStatus.OK) public User test() { User user = new User(); user.setName("Name 1"); return user; } } 
是相同的:
 @RestController public class MyController { @GetMapping(path = "/test") public ResponseEntity<User> test() { User user = new User(); user.setName("Name 1"); HttpHeaders responseHeaders = new HttpHeaders(); // ... return new ResponseEntity<>(user, responseHeaders, HttpStatus.OK); } } 
 这样,只有在需要时才可以定义ResponseEntity 。 
更新
你可以使用这个:
  return ResponseEntity.ok().headers(responseHeaders).body(user); 
- 如何在web.xml中注册Spring @Configuration注释类而不是applicationContext.xml文件?
 - 我该如何告诉Spring Boot可执行jar使用哪个主类?
 - 如何使用spring来pipe理REST API版本?
 - java.lang.ClassNotFoundException:org.springframework.web.servlet.DispatcherServlet
 - Spring @Autowired使用
 - 在Spring数据jpa中save和saveAndFlush之间的区别
 - servlet和web服务的区别
 - 如何在Hibernate 4和Spring中使用注释来定义不同types的关系?
 - 打印所有加载的Spring bean