복붙노트

[SPRING] Spring에 대한 간단한 예외 처리 기술이 있습니까?

SPRING

Spring에 대한 간단한 예외 처리 기술이 있습니까?

@ExceptionHandler를 사용하여 컨트롤러 기반 예외에 대해 읽었습니다.

@ControllerAdvice를 사용하여 전역 예외 처리에 대해 읽었습니다.

더 자세한 예외 처리를 위해 HandlerExceptionResolver를 확장하는 방법에 대해서도 읽었습니다.

그러나 이상적으로는 응용 프로그램의 모든 레이어에서 JSON 응답을 클라이언트에 반환하도록 지시하는 매개 변수를 사용하여 전역 예외를 throw 할 수 있습니다.

예를 들면 :

throw new CustomGlobalException(HttpStatus.UNAUTHORISED, "This JWT Token is not Authorised.")

throw new CustomGlobalException(HttpStatus.FORBIDDEN, "This JWT Token is not valid.")

다음과 같이 상태와 함께 만든 모델을 기반으로 JSON 응답을 반환합니다.

{
    "success" : "false",
    "message" : "This JWT Token is not Authorised."
} 

그리고 내 컨트롤러에서 REST 응답으로 반환됩니다. 이게 가능한가? 또는 문서에 설명 된대로 모든 사항에 대해 사용자 정의 오류 예외를 만드는 과정을 거쳐야합니까?

명확히하기 위해 진행중인 프로세스가 무엇이든 중단하고 데이터베이스에서 데이터를 가져와 즉시 예외를 클라이언트에 반환하는 예외가 필요합니다. Web mvc 설정이 있습니다.

세부 사항 :

 @ControllerAdvice
 @RequestMapping(produces = "application/json")
public class GlobalExceptionHandler {

@ExceptionHandler(CustomException.class)
public ResponseEntity<Object> handleCustomException(CustomException ex,
                                                    WebRequest request) {
    Map<String, Object> response = new HashMap<>();

    response.put("message", ex.getMessage());
    return new ResponseEntity<>(response, ex.getCode());
}
}

여기에 예외가 발생했습니다.

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain
        filterChain) throws ServletException, IOException {

    logger.debug("Filtering request for JWT header verification");

    try {
        String jwt = getJwtFromRequest(request);

        logger.debug("JWT Value: {}", jwt);

        if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
            String username = tokenProvider.getUserIdFromJWT(jwt);

            UserDetails userDetails = customUserDetailsService.loadUserByUsername(username);
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken
                    (userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

            SecurityContextHolder.getContext().setAuthentication(authentication);
        } else {
            logger.error("No Valid JWT Token Provided");
                            throw new CustomException(HttpStatus.UNAUTHORIZED, "No Valid JWT Token Provided");
        }
    } catch (Exception ex) {
        logger.error("Could not set user authentication in security context", ex);
    }

    filterChain.doFilter(request, response);
}

해결법

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

    1.여기에 예외를 처리하는 방법에 대한 내 게시물을 따라, 당신은이 같은 뭔가를 자신의 처리기를 작성할 수 있습니다,

    여기에 예외를 처리하는 방법에 대한 내 게시물을 따라, 당신은이 같은 뭔가를 자신의 처리기를 작성할 수 있습니다,

    class CustomGlobalException {
        String message;
        HttpStatus status;
    }
    
    @ExceptionHandler(CustomGlobalException.class)
    public ResponseEntity<Object> handleCustomException(CustomGlobalException ex,
                WebRequest request) {
        Map<String, Object> response = new HashMap<>();
    
        response.put("success", "false");
        response.put("message", ex.getMessage());
    
        return new ResponseEntity<>(response, ex.getStatus());
    }
    

    위에서 언급 한 코드는 CustomGlobalException을 처리 할 것이다.

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

    2.이것은 당신이 달성하고자하는 것을 정확히하지는 않지만, 당신이 원하는 것을 거의 할 수있는 가장 간단한 방법은 (그리고 더 깨끗한 IMO입니다), 다음과 같이 예외를 정의하는 것입니다 :

    이것은 당신이 달성하고자하는 것을 정확히하지는 않지만, 당신이 원하는 것을 거의 할 수있는 가장 간단한 방법은 (그리고 더 깨끗한 IMO입니다), 다음과 같이 예외를 정의하는 것입니다 :

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public class UnauthorizedException extends RuntimeException {
        public UnauthorisedException(String message) {
            super(message);
        }
    }
    

    이제 이러한 예외가 (직접 또는 간접적으로) 컨트롤러 메서드에서 throw (반환되지 않음) 될 때마다 다음과 같은 응답이 표시됩니다.

    {
        "timestamp": "2018-06-24T09:38:51.453+0000",
        "status": 401,
        "error": "Unauthorized",
        "message": "This JWT Token is not Authorised.",
        "path": "/api/blabla"
    }
    

    물론 HTTP 응답의 실제 상태 코드도 401이됩니다.

    좀 더 일반적인 ResponseStatusException을 던져서 동일한 예외 유형을 사용하고 상태를 인수로 전달할 수도 있습니다. 그러나 나는 그것이 덜 깨끗하다는 것을 안다.

  3. from https://stackoverflow.com/questions/51008530/is-there-a-simpler-exception-handling-technique-for-spring by cc-by-sa and MIT license