복붙노트

[SPRING] Spring 애플리케이션의 예외 처리 위치

SPRING

Spring 애플리케이션의 예외 처리 위치

나는 아직도 봄을 배우고있다. 응용 프로그램 집합을 올렸으므로 Spring에서 예외 처리를 이해하려고합니다.

@ControllerAdvice를 사용하여 예외를 처리하고 있습니다. 내 응용 프로그램에는 서비스, 컨트롤러, 모델 및 저장소와 같은 몇 가지 레이어가 있습니다. 어떤 레이어에서 예외를 처리해야합니까? 또는 각 레이어에서 예외를 적절하게 처리해야합니까?

해결법

  1. ==============================

    1.Spring에서 Exception 처리를 시작하는 좋은 방법이다.

    Spring에서 Exception 처리를 시작하는 좋은 방법이다.

    스텝 1 - 특정의 DefaultExceptionHandler 클래스를 작성해, @ControllerAdvice 주석을 사용해 주석을 붙입니다. 이 핸들러 클래스에는 @ExceptionHandler 어노테이션을 사용하여 주석이 달린 예상 된 예외와 예기치 않은 예외를 모두 포착하는 여러 가지 메소드가있다.

    @ControllerAdvice("com.stackoverflow.example")
    @SuppressWarnings("WeakerAccess")
    public class DefaultExceptionHandler extends ResponseEntityExceptionHandler {
    
        private final Logger log = LoggerFactory.getLogger("DefaultExceptionHandler");
    
        private final MessageSourceAccessor messageSource;
    
        @Autowired
        public DefaultExceptionHandler(MessageSourceAccessor messageSource) {
            Assert.notNull(messageSource, "messageSource must not be null");
            this.messageSource = messageSource;
         }
    
          @ExceptionHandler(ApplicationSpecificException.class)
          public ResponseEntity<Object> handleApplicationSpecificException(ApplicationSpecificExceptionex) {
             final Error error = buildError(ex);
             return handleExceptionInternal(ex, ex.getHttpStatus(), error);
          }
    
           @ExceptionHandler(Exception.class)
           public ResponseEntity<Object> handleException(Exception ex) {
               final Error error = buildError(ex);
               return handleExceptionInternal(ex, HttpStatus.INTERNAL_SERVER_ERROR, error);
        }
    }
    

    2 단계 - 예상 예외에 사용되는 응용 프로그램 특정 예외 (ApplicationSpecificException 클래스)를 작성하고이 예외를 모든 레벨에서 발생 시키면 Spring에 의해 선택됩니다.

    public class ApplicationSpecificException extends RuntimeException {
    
        private static final long serialVersionUID = 1L;
    
        private final ExceptionType exceptionType;
    
        public ApplicationSpecificException(ExceptionType exceptionType, Object... messageArguments) {
            super(MessageFormat.format(exceptionType.getMessage(), messageArguments));
            this.exceptionType = exceptionType;
        }
    
        public ApplicationSpecificException(ExceptionType exceptionType, final Throwable cause, Object... messageArguments) {
            super(MessageFormat.format(exceptionType.getMessage(), messageArguments), cause);
            this.exceptionType = exceptionType;
        }
    
        public HttpStatus getHttpStatus() {
            return exceptionType.getStatus();
        }
    
        public ExceptionType getExceptionType() {
            return exceptionType;
        }
    }
    

    ExceptionType이 enum 인 경우 :

    public enum ExceptionType {
    
        HTTP_INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "An internal server error occurred.");
        //you can specify your own exception types...
    
        private HttpStatus status;
        private String message;
    
        ExceptionType(HttpStatus status, String message) {
            this.status = status;
            this.message = message;
        }
    
        public HttpStatus getStatus() {
            return status;
        }
    
        public String getMessage() {
            return message;
        }
    }
    

    3 단계 - 마지막으로 ExceptionFactory 클래스를 생성합니다. 이렇게하면 응용 프로그램 로그에 자동으로 예외를 기록 할 수 있습니다.

    public class ExceptionFactory {
    
        private static final Logger LOG = LoggerFactory.getLogger(ExceptionFactory.class);
    
        public static ApplicationSpecificException create(final Throwable cause, final ExceptionType exceptionType, final Object... messageArguments) {
            LOG.error(MessageFormat.format(exceptionType.getMessage(), messageArguments), cause);
            return new ApplicationSpecificException (exceptionType, cause, messageArguments);
        }
    
        public static ApplicationSpecificException create(final ExceptionType exceptionType, final Object... messageArguments) {
            LOG.error(MessageFormat.format(exceptionType.getMessage(), messageArguments));
            return new TerminologyServerException(exceptionType, messageArguments);
        }
    }
    

    4 단계 - 응용 프로그램의 모든 위치에서 이제 예외를 throw 할 수 있으며 응용 프로그램 로그에 예외가 기록됩니다. 이 예외는 Spring @ControllerAdvice 주석으로 인해 DefaultExceptionHandler에 의해 발생되고 선택됩니다.

    throw ExceptionFactory.create(ExceptionType.INTERNAL_SERVER_ERROR);
    

    이렇게하면 예외 처리 프로세스를 교차 관심사로 처리 할 수 ​​있습니다. 내부 서버 오류는 최종 사용자에게 전달되지 않으며 예상 및 예기치 않은 예외는 모두 DefaultExceptionHandler에 의해 처리됩니다. 예외에는 특정 HTTP 오류 코드와 오류 메시지가 지정되어 클라이언트로 반환됩니다.

  2. ==============================

    2.예기치 않은 모든 문제를 처리하는 @ControllerAdvice로 주석 된 전용 클래스를 만드는 것이 좋습니다. 이렇게하면 응용 프로그램의 내부가 클라이언트에 노출되는 것을 방지 할 수 있습니다.

    예기치 않은 모든 문제를 처리하는 @ControllerAdvice로 주석 된 전용 클래스를 만드는 것이 좋습니다. 이렇게하면 응용 프로그램의 내부가 클라이언트에 노출되는 것을 방지 할 수 있습니다.

    @ControllerAdvice
    public class UncaughtExceptionHandler {
    
        private static final Logger log = LoggerFactory.getLogger(UncaughtExceptionHandler.class);
    
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        @ExceptionHandler(Exception.class)
        public void handleAll(Exception e) {
            log.error("Unhandled exception occurred", e);
        }
    
    }
    

    예상되는 예외 (확인 된 예외와 혼동하지 말 것)에 대해서는 발생하는 문제를 어떻게 처리해야 할 것인가. 일부 예외는 전파되거나 랩핑되고 @ControllerAdvice로 구현 된 동일한 전역 핸들러에 다시 전달되어 예외 전체를 단일 지점에서 유지할 수 있습니다.

  3. ==============================

    3.@ExceptionHandler 어노테이션을 시도해야한다.

    @ExceptionHandler 어노테이션을 시도해야한다.

    당신은 그것에 관하여 더 많은 것을 여기에서 읽을 수있다 : https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

  4. ==============================

    4.@ControllerAdvice는 스프링 애플리케이션의 전역 예외 처리기로 사용할 수 있습니다. Checkout이 잘 설명 된 자습서. @ControllerAdvice를 사용하면 비즈니스 코드가 덜 복잡해지고 모든 예외를 처리 할 수있는 별도의 장소가 생깁니다. @ControllerAdvice를 사용하면 관심사의 디자인 원칙을 따를 수 있습니다.

    @ControllerAdvice는 스프링 애플리케이션의 전역 예외 처리기로 사용할 수 있습니다. Checkout이 잘 설명 된 자습서. @ControllerAdvice를 사용하면 비즈니스 코드가 덜 복잡해지고 모든 예외를 처리 할 수있는 별도의 장소가 생깁니다. @ControllerAdvice를 사용하면 관심사의 디자인 원칙을 따를 수 있습니다.

  5. ==============================

    5.Spring Framework를 사용하여 예외를 처리 할 수있는 세 가지 방법이 있습니다.

    Spring Framework를 사용하여 예외를 처리 할 수있는 세 가지 방법이 있습니다.

  6. ==============================

    6.나는 받아 들여진 대답이 좋다고 생각한다. 전역 예외 처리를 위해 Spring @ControllerAdvice를 사용하고, 오류 코드와 HTTP 상태를 결합하는 enum도 사용합니다.

    나는 받아 들여진 대답이 좋다고 생각한다. 전역 예외 처리를 위해 Spring @ControllerAdvice를 사용하고, 오류 코드와 HTTP 상태를 결합하는 enum도 사용합니다.

    그러나 예외 팩토리 부분에는 동의하지 않습니다. 팩토리는 예외를 기록하고이를 버립니다. 이것은 이것과 같은 많은 기사에서 권장되지 않습니다. 물론 예외 번역과 같은 것이 없다면 예외가 한 번만 기록되므로 확인해야합니다. 그러나 번역은 앞으로는 필요하지 않을 것이라고 확신 할 수 없습니다.

    @ControllerAdvice를 사용하여 로깅하는 것이 좋습니다. 응용 프로그램 예외의 최종 목적지이기 때문입니다. 이렇게하면 모든 예외가 한 번 로그되고 클라이언트에게 제시 할 수있는 좋은 처리를 할 수 있습니다.

  7. from https://stackoverflow.com/questions/45034371/where-to-handle-exceptions-in-spring-applications by cc-by-sa and MIT license