Spring 引导休息控制器如何返回不同的 HTTP 状态码?

我使用 SpringBoot 来实现一个简单的 REST API,如果出现问题,我希望返回一个正确的 HTTP 状态代码。

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)
@ResponseBody
@ResponseStatus( HttpStatus.OK )
public RestModel create(@RequestBody String data) {
// code ommitted..
// how do i return a correct status code if something fails?
}

作为 Spring 和 Spring Boot 的新手,基本问题是当某些东西正常或失败时,我如何返回不同的状态代码?

268487 次浏览

你可以使用以下几种方法,比较好的方法是使用异常和类来处理 @ControllerAdvice:

@ControllerAdvice
class GlobalControllerExceptionHandler {
@ResponseStatus(HttpStatus.CONFLICT)  // 409
@ExceptionHandler(DataIntegrityViolationException.class)
public void handleConflict() {
// Nothing to do
}
}

也可以将 HttpServletResponse传递给控制器方法,然后只需设置响应代码:

public RestModel create(@RequestBody String data, HttpServletResponse response) {
// response committed...
response.setStatus(HttpServletResponse.SC_ACCEPTED);
}

请参考这个伟大的博客文章的细节: < em > Spring MVC 中的异常处理


注意

在 Spring 中,使用 @ResponseBody注释是多余的——它已经包含在 @RestController注释中。

实现这一点的方法之一是可以使用 ResponseEntity作为返回对象。

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)
public ResponseEntity<?> create(@RequestBody String data) {
if(everything_fine) {
return new ResponseEntity<>(RestModel, HttpStatus.OK);
} else {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

试试这个代码:

@RequestMapping(value = "/validate", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<ErrorBean> validateUser(@QueryParam("jsonInput") final String jsonInput) {
int numberHTTPDesired = 400;
ErrorBean responseBean = new ErrorBean();
responseBean.setError("ERROR");
responseBean.setMensaje("Error in validation!");


return new ResponseEntity<ErrorBean>(responseBean, HttpStatus.valueOf(numberHTTPDesired));
}

如果您想返回自定义的状态代码,您可以使用 ResponseEntity,如下所示:

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)
public ResponseEntity<?> create(@RequestBody String data) {
int customHttpStatusValue = 499;
Foo foo = bar();
return ResponseEntity.status(customHttpStatusValue).body(foo);
}

CustomHttpStatusValue 可以是标准 HTTP 状态代码内部或外部的任何整数。

一个很好的方法是使用 Spring 的 响应状态异常

不需要返回 ResponseEntity或类似的值,只需要从控制器中抛出带有 HttpStatusResponseStatusException并导致,例如:

throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Cause description here");

这将导致对包含 HTTP 状态的客户端的响应:

{
"timestamp": "2020-07-09T04:43:04.695+0000",
"status": 400,
"error": "Bad Request",
"message": "Cause description here",
"path": "/test-api/v1/search"
}

注意 : HttpStatus为方便您提供了许多不同的状态代码。

有不同的方式返回状态码, RestController 类应该扩展 BaseRestclass,在 BaseRestclass 中我们可以处理异常并返回预期的错误代码。 例如:

@RestController
@RequestMapping
class RestController extends BaseRest{


}


@ControllerAdvice
public class BaseRest {
@ExceptionHandler({Exception.class,...})
@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorModel genericError(HttpServletRequest request,
HttpServletResponse response, Exception exception) {
        

ErrorModel error = new ErrorModel();
resource.addError("error code", exception.getLocalizedMessage());
return error;
}

我认为最简单的方法是将方法的返回类型设置为

ResponseEntity<WHATEVER YOU WANT TO RETURN>

如果要发送任何状态代码,只需添加 return 语句作为

return ResponseEntity.status(HTTP STATUS).build();

例如,如果要返回图书列表,

public ResponseEntity<List<books>> getBooks(){


List<books> list = this.bookService.getAllBooks();
  

if(list.size() <= 0)
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
else
return ResponseEntity.of(Optional.of(list));


}