Есть ли более простая техника обработки исключений для Spring? - PullRequest
0 голосов
/ 24 июня 2018

Я читал об исключениях на основе контроллера, используя @ ExceptionHandler.

Я читал о глобальной обработке исключений с помощью @ ControllerAdvice.

Я также читал о расширении HandlerExceptionResolver для более подробного исключения.обработка.

Однако в идеале я хотел бы создать глобальное исключение с параметрами, которые определяют ответ JSON, возвращаемый клиенту, на любом уровне моего приложения.

Например:

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 от моего контроллера.Возможно ли что-то подобное?Или я должен пройти через процесс создания пользовательских исключений ошибок для всего, как описано в документации.

Чтобы прояснить, я требую, чтобы исключение прерывало любой текущий процесс, возможно, выборку данных из базы данных,и немедленно вернуть данное исключение клиенту.У меня есть настройка веб-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);
}

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

Следуя моему посту о том, как обрабатывать исключения здесь , вы можете написать свой собственный обработчик примерно так:

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 произошел любой слой кода.

0 голосов
/ 24 июня 2018

Это не совсем то, что вы хотите достичь, но самый простой способ сделать почти то, что вы хотите (и чище, IMO), это просто определить исключение, подобное следующему:

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

Теперь каждый раз, когда такое исключение выдается (не возвращается) из метода контроллера (прямо или косвенно), вы получите ответ, такой как

{
    "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, который является более общим и позволяет использовать тот же тип исключения и передавать статус в качестве аргумента. Но я нахожу это менее чистым.

...