source

스프링 부트에서 JSON에서 예외를 다시 던지는 방법

manysource 2023. 7. 9. 11:18

스프링 부트에서 JSON에서 예외를 다시 던지는 방법

요청 매핑이 있습니다.

  @RequestMapping("/fetchErrorMessages")
  public @ResponseBody int fetchErrorMessages(@RequestParam("startTime") String startTime,@RequestParam("endTime") String endTime) throws Exception
  {
      if(SanityChecker.checkDateSanity(startTime)&&SanityChecker.checkDateSanity(endTime))
      {
          return 0;
      }
      else
      {
          throw new NotFoundException("Datetime is invalid");
      }
  }

startTime과 endTime이 올바르지 않으면 500 오류를 발생시키지만 JSON에서 예외 문자열을 반환합니다.하지만 대신 HTML 페이지가 나타납니다.

화이트라벨 오류 페이지

이 응용 프로그램에는 /error에 대한 명시적인 매핑이 없으므로 이를 폴백으로 보는 것입니다.

10:37 IST 12월 10:49:37
치 않은가 발생했습니다(type"type").내부 서버 오류, 상태=500).
날짜 시간이 잘못되었습니다.

저는 대신 JSON과 함께 500개를 반품하고 싶었습니다.

{"error":"Date time format is invalid"}

어떻게 해야 하나요?

클래스가 합니다.NotFoundException그리고 그 구현은 다음과 같습니다.

public class NotFoundException extends Exception {

    private int errorCode;
    private String errorMessage;

    public NotFoundException(Throwable throwable) {
        super(throwable);
    }

    public NotFoundException(String msg, Throwable throwable) {
        super(msg, throwable);
    }

    public NotFoundException(String msg) {
        super(msg);
    }

    public NotFoundException(String message, int errorCode) {
        super();
        this.errorCode = errorCode;
        this.errorMessage = message;
    }


    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    @Override
    public String toString() {
        return this.errorCode + " : " + this.getErrorMessage();
    }
}

이제 컨트롤러에서 몇 가지 예외를 적용하려고 합니다. 클래스에서 . 를 들어 에는 " " " " 를 제공합니다. 예를 들어 봄에 예외가 제공됩니다.@ControllerAdvice클래스 표준 오류 처리기를 만드는 데 적용할 주석입니다.클래스에 적용되면 이 스프링 구성 요소(주석을 추가한 클래스)에서 컨트롤러에서 발생한 예외를 포착할 수 있습니다.하지만 우리는 적절한 방법으로 예외 클래스를 매핑해야 합니다.로 메소드를 했습니다.NotFoundException아래와 같은 것을 처리합니다.

@ControllerAdvice
public class RestErrorHandler {

    @ExceptionHandler(NotFoundException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public Object processValidationError(NotFoundException ex) {
        String result = ex.getErrorMessage();
        System.out.println("###########"+result);
        return ex;
    }
}

http 상태를 내부 서버 오류(500)로 보내고자 합니다. 그래서 여기서 사용했습니다.@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 주석 이외에는 .@ResponseBody자동으로 실행할 수 있습니다.

사용자 지정 예외를 만듭니다.

public class SecurityException extends RuntimeException {

    private static final long serialVersionUID = -7806029002430564887L;

    private String message;

    public SecurityException() {
    }

    public SecurityException(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

사용자 지정 응답 엔터티를 만듭니다.

public class SecurityResponse {

    private String error;

    public SecurityResponse() {

    }

    public SecurityResponse(String error) {
        this.error = error;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

}

사용자 지정 예외 처리기를 사용하여 ControllerAdvisory를 생성하면 사용자 지정 예외를 처리하고 아래와 같이 사용자 지정 응답을 입력하고 반환합니다.

@ControllerAdvice
public class SecurityControllerAdvice {

    @ExceptionHandler(SecurityException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public SecurityResponse handleSecurityException(SecurityException se) {
        SecurityResponse response = new SecurityResponse(se.getMessage());
        return response;
    }
}

사용자의 조건에 따라 사용자 지정 예외를 던집니다.

throw new SecurityException("Date time format is invalid");

이제 앱을 실행하고 테스트합니다.예:

enter image description here

은 수있다니습생을 수 있습니다.NotFoundException 있는 @ResponseStatus아래와 같은 주석:

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class NotFoundException extends RuntimeException {
   public NotFoundException() {
   }

   public NotFoundException(String message) {
    super(message);
   }

}

Javax의 인터페이스 이름은 ExceptionMapper입니다.모든 런타임에 대해 아래 코드 조각을 참조하십시오.응용 프로그램에서는 예외적으로 Json 응답 엔티티에 매핑됩니다.

public class RuntimeExceptionMapper implements ExceptionMapper <RuntimeException> {

@Override
public Response toResponse(RuntimeException exception) {
    ErrorResponse errorResponse = new ErrorResponse();
    errorResponse.setMessage(exception.getMessage);
    if (exception== null) {
        logger.error("Exception Details Not found");            
    } else {
        return Response.status(Status.INTERNAL_SERVER_ERROR)
            .entity(errorResponse )
                .type(MediaType.APPLICATION_JSON)
                    .header("trace-id", "1234").build();
    }


}

}

애플리케이션에서 수행한 작업은 다음과 같습니다.

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class ExceptionHandlingControllerAdvice {

   @ExceptionHandler(ExecutionRestrictionViolationException.class)
   public ResponseEntity<String> handleExecutionRestrictionViolationException(ExecutionRestrictionViolationException ex) {
     return response("Invalid Query", ex.getMessage(), HttpStatus.UNPROCESSABLE_ENTITY);
   }

   private static String createJson(String message, String reason) {
    return "{\"error\" : \"" + message + "\"," +
            "\"reason\" : \"" + reason  + "\"}";
   }

   private static ResponseEntity<String> response(String message,
                                               String reason,
                                               HttpStatus httpStatus) {
    String json = createJson(message, reason);
    return new ResponseEntity<>(json, httpStatus);
   }

}

설명:

  1. 컨트롤러 어드바이스를 만들고, 특별한 주석으로 표시하고, 다른 빈과 마찬가지로 정의합니다(나의 경우 자바 구성이었지만 실제로는 문제가 되지 않습니다).

  2. 이렇게 처리할 각 예외에 대해 - 원하는 형식으로 응답을 생성할 처리기를 정의합니다.

  3. 정적인 방법인 createJson이 있습니다. 다른 방법을 사용할 수 있습니다. 또한 실제로는 문제가 되지 않습니다.

이제 이 방법은 한 가지 방법에 불과합니다(더 최신 봄 부팅 버전에서 사용 가능). 그러나 다른 방법도 있습니다.

제가 알고 있는 (그리고 그 이상의) 모든 방법이 여기에 나열되어 있습니다.

봄은 여러분의 상황에 따라 다른 것들보다 더 합리적인 몇 가지 방법을 제공합니다.

(여러 옵션에 대한 좋은 튜토리얼입니다.https://www.baeldung.com/spring-exceptions-json)

제가 가장 좋아하는 것은 이것입니다. 왜냐하면 저는 슈퍼 클래스를 만들거나 유틸리티 클래스에서 도우미 메소드를 만들거나 어디에서나 보일러 플레이트를 복사하지 않고 적절한 오류 메시지와 적절한 http 응답을 보내고 싶기 때문입니다.

올바른 JSON에서 이벤트로 인해 오류가 발생했음을 발신자에게 알리려면 Spring의 ResponseStatusException을 사용합니다.httpResponse 개체에 대한 액세스 권한을 제공하므로 'ok' 이외의 응답도 보낼 수 있습니다.

매개 변수 중 하나로 예외를 원합니다.시나리오 중 하나를 위해 이미 존재하는 사용자를 등록하려고 한다는 것을 발신자에게 알리고 싶었습니다.일반적으로 사용자를 검색할 때 예외를 발생시키지 않지만 이 경우에는 내가 직접 예외를 생성하여 다음과 같은 ResponseStatusException에서 호출자에게 다시 던집니다.

  @PostMapping("/register")
  public ResponseEntity register(@RequestBody AccountUserDto user) {
    UserDetails userExists = userDetailsService.loadUserByEmail(user.getEmail());

  if (userExists != null) {
      UserExistsException exc = new UserExistsException("Error: Email address " + user.getEmail() +  " is already in use.");
        throw new ResponseStatusException(
        HttpStatus.BAD_REQUEST, "User Exists", exc);
  }
....(fall through and create user)

언급URL : https://stackoverflow.com/questions/47899292/how-to-throw-an-exception-back-in-json-in-spring-boot