当为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