使用ResponseEntity时<;T>;和@RestController,用于Spring RESTful应用程序
我正在使用SpringFramework4.0.7,以及MVC和Rest 我可以与以下人员和平相处:使用ResponseEntity时<;T>;和@RestController,用于Spring RESTful应用程序,spring,spring-mvc,spring-3,spring-4,Spring,Spring Mvc,Spring 3,Spring 4,我正在使用SpringFramework4.0.7,以及MVC和Rest 我可以与以下人员和平相处: @控制器 响应性 例如: @Controller @RequestMapping("/person") @Profile("responseentity") public class PersonRestResponseEntityController { @RestController @RequestMapping("/person") @Profile("restcontroller
@控制器
响应性
@Controller
@RequestMapping("/person")
@Profile("responseentity")
public class PersonRestResponseEntityController {
@RestController
@RequestMapping("/person")
@Profile("restcontroller")
public class PersonRestController {
@RestController
public class MyController {
@GetMapping(path = "/test")
@ResponseStatus(HttpStatus.OK)
public User test() {
User user = new User();
user.setName("Name 1");
return user;
}
}
使用方法(仅用于创建)
使用方法(仅用于创建)
归还某物
@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);
}
@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;
}
我的问题是:
ResponseEntity
表示整个HTTP响应。您可以控制其中的任何内容:状态代码、标题和正文
@ResponseBody
是HTTP响应主体的标记,@ResponseStatus
声明HTTP响应的状态代码
@ResponseStatus
不是很灵活。它标记整个方法,因此您必须确保处理程序方法始终以相同的方式运行。您仍然无法设置标题。您需要HttpServletResponse
或HttpHeaders
参数
基本上,
ResponseEntity
可以让你做得更多。完成索托里奥斯·德里马诺利斯的回答
诚然,ResponseEntity
为您提供了更大的灵活性,但在大多数情况下,您并不需要它,最终您的控制器中到处都会出现这些ResponseEntity
,因此难以阅读和理解
如果您想处理诸如错误(未找到、冲突等)之类的特殊情况,可以向Spring配置中添加一个。因此,在代码中,您只需抛出一个特定的异常(
NotFoundException
),并决定在处理程序中执行什么操作(将HTTP状态设置为404),使控制器代码更加清晰。根据官方文档:
@RestController是一个结合@ResponseBody的原型注释
和@Controller更重要的是,它赋予您的
控制器,也可能在将来的版本中带有附加语义
框架的一部分。
为了清晰起见,最好使用@RestController
,但您也可以将它与响应性
结合起来,以便在需要时灵活使用(和)
例如:
@Controller
@RequestMapping("/person")
@Profile("responseentity")
public class PersonRestResponseEntityController {
@RestController
@RequestMapping("/person")
@Profile("restcontroller")
public class PersonRestController {
@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);
}
}
一个合适的RESTAPI应该有以下组件作为响应
// Step 1 - Without any options provided
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public @ResponseBody Spittle spittleById(@PathVariable long id) {
return spittleRepository.findOne(id);
}
// Step 2- We need to handle exception scenarios, as step 1 only caters happy path.
@ExceptionHandler(SpittleNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public Error spittleNotFound(SpittleNotFoundException e) {
long spittleId = e.getSpittleId();
return new Error(4, "Spittle [" + spittleId + "] not found");
}
// Step 3 - Now we will alter the service method, **if you want to provide location**
@RequestMapping(
method=RequestMethod.POST
consumes="application/json")
public ResponseEntity<Spittle> saveSpittle(
@RequestBody Spittle spittle,
UriComponentsBuilder ucb) {
Spittle spittle = spittleRepository.save(spittle);
HttpHeaders headers = new HttpHeaders();
URI locationUri =
ucb.path("/spittles/")
.path(String.valueOf(spittle.getId()))
.build()
.toUri();
headers.setLocation(locationUri);
ResponseEntity<Spittle> responseEntity =
new ResponseEntity<Spittle>(
spittle, headers, HttpStatus.CREATED)
return responseEntity;
}
// Step4 - If you are not interested to provide the url location, you can omit ResponseEntity and go with
@RequestMapping(
method=RequestMethod.POST
consumes="application/json")
@ResponseStatus(HttpStatus.CREATED)
public Spittle saveSpittle(@RequestBody Spittle spittle) {
return spittleRepository.save(spittle);
}
//步骤1-不提供任何选项
@RequestMapping(value=“/{id}”,method=RequestMethod.GET)
public@ResponseBody Spittle spittleById(@PathVariable long id){
返回spittleRepository.findOne(id);
}
//第2步-我们需要处理异常情况,因为第1步只提供了一条快乐的道路。
@ExceptionHandler(SpitleNotFoundException.class)
@ResponseStatus(未找到HttpStatus.NOT_)
公共错误SpitleNotFound(SpitleNotFound异常){
long spittleId=e.getSpittleId();
返回新错误(4,“未找到Spitle[“+SpitleId+”);
}
//步骤3-现在我们将更改服务方法,**如果您想提供位置**
@请求映射(
method=RequestMethod.POST
consumes=“application/json”)
公共责任节约唾沫(
@身体上的唾沫,
UriComponentsBuilder(ucb){
Spittle Spittle=spittleRepository.save(Spittle);
HttpHeaders=新的HttpHeaders();
URI位置URI=
ucb.path(“/spittles/”)
.path(String.valueOf(spittle.getId()))
.build()
.toUri();
headers.setLocation(locationUri);
响应响应响应响应响应响应=
新反应(
Spitle、标头、HttpStatus.CREATED)
返回响应性;
}
//第4步-如果您对提供url位置不感兴趣,可以省略ResponseEntity并使用
@请求映射(
method=RequestMethod.POST
consumes=“application/json”)
@ResponseStatus(HttpStatus.CREATED)
公共唾沫节约唾沫(@RequestBody唾沫){
返回spittle存储库。保存(spittle);
}
关于第三个观察的观点很好。谢谢你……我对响应性也有同样的想法,它更灵活。只是我对@RestController
有点怀疑。谢谢您您的观点在使用(@)ExceptionHandler时是有效的。要点是:如果希望在一个方法(Try/Catch)中处理所有请求,那么HttpEntity很适合,如果希望重用异常处理(@)ExceptionHandler处理多个(@)请求,那么映射很适合。我喜欢HttpEntity,因为我也可以使用HttpHeaders。如果我们在方法上添加了@ResponseStatus(HttpStatus.OK),但方法返回新的ResponseEntity(user,responseHeaders,HttpStatus.NOT_FOUND);我只是在想@ResponseStatus是否会进一步修改响应代码。@Hemant似乎在返回ResponseEntity(用户、响应负责人、HttpStatus.NOT_FOUND)
时忽略了@ResponseStatus(HttpStatus.OK)
。HTTP响应是来自ResponseStatus的JavaDocs的404
。当调用处理程序方法时,状态代码将应用于HTTP响应,并通过其他方式覆盖状态信息集,如{@code ResponseEntity}或{@code“redirect:”}。