programing

404 찾을 수 없음 예외에 본문 추가

muds 2023. 6. 25. 20:37
반응형

404 찾을 수 없음 예외에 본문 추가

JHipster로 생성된 REST API에서 404개 정도의 예외를 던지고 싶습니다.일반적으로 다음과 같이 수행됩니다.

return new ResponseEntity<>(HttpStatus.NOT_FOUND);

이는 실제로 xhr 요청에 대한 404 응답을 초래합니다.문제는 정면에서 JHipster가 반응을 해석한다는 것입니다.

angular.fromJson(result)

404가 실제 응답일 때 이러한 결과는 비어 있으므로 구문 분석이 실패합니다.

매핑되지 않은 URI를 가리킨다면,/api/user내 컨트롤러가 에 매핑되는 동안/api/users(복수 참고) API에서 얻은 404에는 본문이 있습니다.

{
    "timestamp": "2016-04-25T18:33:19.947+0000",
    "status": 404,
    "error": "Not Found",
    "message": "No message available",
    "path": "/api/user/myuser/contact"
}

각도로 정확하게 구문 분석됩니다.

어떻게 하면 이런 몸을 만들 수 있을까요?이 예외는 봄에 의해 던져지는 것입니까, 아니면 봄에 던져지는 것입니까?

시도해 봤습니다.Spring-MVC 컨트롤러에서 트리거 404? 그러나 응답의 파라미터를 설정할 수 없습니다.

기본 아이디어


첫 번째 옵션은 오류 개체를 정의하고 다음과 같이 반환하는 것입니다.404 Not Found몸. 다음과 같은 것.

Map<String, String> errors = ....;
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errors);

일반적인 것을 반환하는 대신ResponseEntity던질 수 있습니다.Exception그것은 해결될 것입니다.404 Not Found당신이 가지고 있다고 가정합니다.NotFoundException예:

@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {}

그런 다음 컨트롤러에 이 예외를 적용하면 다음과 같은 것이 표시됩니다.

{  
   "timestamp":1461621047967,
   "status":404,
   "error":"Not Found",
   "exception":"NotFoundException",
   "message":"No message available",
   "path":"/greet"
}

메시지 및 신체의 다른 부분을 사용자 지정하려면 다음을 정의해야 합니다.ExceptionHandler위해서NotFoundException.

예외 계층 소개


RESTful API를 만드는 경우 예외적인 경우마다 다른 오류 코드 및 오류 메시지를 사용하려면 이러한 경우를 나타내는 예외 계층을 만들고 각 예외에서 메시지와 코드를 추출할 수 있습니다.

예를 들어, 다음과 같은 예외를 도입할 수 있습니다.APIException이는 컨트롤러에 의해 던져진 다른 모든 예외의 슈퍼 클래스입니다.이 클래스는 다음과 같은 코드/메시지 쌍을 정의합니다.

public class APIException extends RuntimeException {
    private final int code;
    private final String message;

    APIException(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int code() {
        return code;
    }

    public String message() {
        return message;
    }
}

예외의 특성에 따라 각 하위 클래스는 이 쌍에 대해 몇 가지 합리적인 값을 제공할 수 있습니다.예를 들어, 우리는 그것을 가질 수 있습니다.InvalidStateException:

@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public class InvalidStateException extends APIException {
    public InvalidStateException() {
        super(1, "Application is in invalid state");
    }
}

아니면 그 악명 높은 발견되지 않은 것들:

@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class SomethingNotFoundException extends APIException {
    public SomethingNotFoundException() {
        super(2, "Couldn't find something!");
    }
}

그러면 우리는 정의해야 합니다.ErrorController이러한 예외를 포착하여 의미 있는 JSON 표현으로 전환합니다.이 오류 컨트롤러는 다음과 같습니다.

@RestController
public class APIExceptionHandler extends AbstractErrorController {
    private static final String ERROR_PATH = "/error";
    private final ErrorAttributes errorAttributes;

    @Autowired
    public APIExceptionHandler(ErrorAttributes errorAttributes) {
        super(errorAttributes);
        this.errorAttributes = errorAttributes;
    }

    @RequestMapping(path = ERROR_PATH)
    public ResponseEntity<?> handleError(HttpServletRequest request) {
        HttpStatus status = getStatus(request);

        Map<String, Object> errors = getErrorAttributes(request, false);
        getApiException(request).ifPresent(apiError -> {
            errors.put("message" , apiError.message());
            errors.put("code", apiError.code());
        });
        // If you don't want to expose exception!
        errors.remove("exception");


        return ResponseEntity.status(status).body(errors);
    }

    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }

    private Optional<APIException> getApiException(HttpServletRequest request) {
        RequestAttributes attributes = new ServletRequestAttributes(request);
        Throwable throwable = errorAttributes.getError(attributes);
        if (throwable instanceof APIException) {
            APIException exception = (APIException) throwable;
            return Optional.of(exception);
        }

        return Optional.empty();
    }
}

그래서, 만약 당신이 던진다면.SomethingNotFoundException반환되는 JSON은 다음과 같습니다.

{  
   "timestamp":1461621047967,
   "status":404,
   "error":"Not Found",
   "message":"Couldn't find something!",
   "code": 2,
   "path":"/greet"
}

오류 코드로 메시지를 반환하거나 테스트하려면 이 작업을 수행할 수 있습니다.

@ResponseBody
public ResponseEntity somthing() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8");
return new ResponseEntity<>(new Gson().toJson("hello this is my message"), headers, HttpStatus.NOT_FOUND);
}

새 ResponseStatusException(HttpStatus)을 만듭니다.NOT_Found, "메시지";

언급URL : https://stackoverflow.com/questions/36848562/add-a-body-to-a-404-not-found-exception

반응형