Spring Boot Rest Controller 다른 HTTP 상태 코드를 반환하는 방법은 무엇입니까?


102

간단한 REST API에 Spring Boot를 사용하고 있으며 실패하면 올바른 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를 처음 사용하는 기본적인 질문은 무언가가 정상이거나 실패 할 때 다른 상태 코드를 어떻게 반환합니까?

답변:


118

사용할 수있는 몇 가지 옵션이 있습니다. 아주 좋은 방법은 호출 된 처리를 위해 예외와 ​​클래스를 사용하는 것입니다 @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);
}

자세한 내용은이 훌륭한 블로그 게시물을 참조하십시오 : Spring MVC의 예외 처리


노트

Spring MVC에서는 @ResponseBody어노테이션을 사용하는 것이 중복 @RestController됩니다. 이미 어노테이션에 포함되어 있습니다.


댓글처럼 15 분 전에 테스트를했는데 '@ResponseBody'주석이없는 '@RestController'가 그의 메서드에 대해 본문이 아닌 ForwardedURL로 반환 된 문자열을 배치했습니다. 나는 spring / springboot 내 자신에 꽤 멍청한 놈
이니까

@Anearion 대답에 오타가 있습니다. 실제로 '@RestController'가 아닌 '@RestControllerAdvice'가 필요합니다.
yoliho

오타가 아닙니다. 이 부분은 컨트롤러에 대한 질문 및 주석과 관련이 있습니다
Jakub Kubrynski aug

1
참고, javax.servlet.http.HttpServletResponse모든 StatusCodes이없는 것 같다 org.springframework.http.HttpStatus수행합니다. 따라서 HttpStatus.UNPROCESSABLE_ENTITY.value()int- 값을 response.setStatus에 전달하는 데 사용할 수 있습니다 . 또한 이것은 @ExceptionHandler.
Igor

43

이를 수행하는 방법 중 하나는 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);

}

3
Spring의 이후 버전에서 null을 사용할 필요가 없습니다. new ResponseEntity <> (HttpStatus.NOT_FOUND)
Kong

4

이 코드를 시도하십시오.

@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));
}

이것은 다소 오래된 질문이므로 참조 할 패키지 및 버전 정보를 추가해야합니다.
ZF007

의 구현 예를 포함 할 수 있습니까 ErrorBean?
Brent Bradburn

4

좋은 방법은 Spring의 ResponseStatusException 을 사용하는 것입니다.

a ResponseEntity또는 이와 유사한 것을 반환하는 대신 ResponseStatusException컨트롤러에서 HttpStatus및 원인을 사용하여 간단히 던집니다. 예를 들면 다음과 같습니다.

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

또는:

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

그러면 다음과 같은 본문과 함께 HTTP 상태 (예 : 400 잘못된 요청)가 포함 된 클라이언트에 대한 응답이 발생합니다.

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

REST 클라이언트로 간단하고 깨끗하며 소비 가능합니다.
Alecz

2

사용자 정의 상태 코드를 반환하려면 다음과 같이 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 상태 코드 내부 또는 외부의 정수일 수 있습니다.


이 유창한 API 접근 방식이 마음에 듭니다.
v.ladynev

0

상태 코드를 반환하는 방법에는 여러 가지가 있습니다. 1 : RestController 클래스는 BaseRest 클래스를 확장해야하며 BaseRest 클래스에서 예외를 처리하고 예상 오류 코드를 반환 할 수 있습니다. 예 :

@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;
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.