@ExceptionHandler не запускается?

Я видел другие дублирующие проблемы с переполнением стека по этой теме, но, похоже, ни одна из них не повторяет мою ситуацию.

При генерировании исключения мой класс ExceptionHandler не берет его и не возвращает json, вместо этого код по умолчанию 500 с деталями исключения возвращается клиенту в виде HTML. Я проверил, и Spring инициализирует мой класс ExceptionHandler, но по какой-то причине методы не вызываются.

GlobalExceptionHandler.class:

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

private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);

public GlobalExceptionHandler(){
    LOG.debug("This gets called in logs...");
}

@ExceptionHandler({CustomException.class})
public @ResponseBody ResponseEntity<Object> handleCustomException(HttpServletRequest request,
                                             CustomException ex) {

    LOG.debug("This does not get called...");
    Map<String, Object> response = new HashMap<>();

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

CustomException.class:

public class CustomException extends RuntimeException{

private HttpStatus code;
private String message;

public CustomException(final HttpStatus code, final String message){

    this.code = code;
    this.message = message;
}


/**
 * Gets message.
 *
 * @return Value of message.
 */
public String getMessage() {
    return message;
}

/**
 * Sets new code.
 *
 * @param code
 *         New value of code.
 */
public void setCode(HttpStatus code) {
    this.code = code;
}

/**
 * Sets new message.
 *
 * @param message
 *         New value of message.
 */
public void setMessage(String message) {
    this.message = message;
}

/**
 * Gets code.
 *
 * @return Value of code.
 */
public HttpStatus getCode() {
    return code;
}
}

Здесь запускается обработчик исключения:

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Autowired
private JwtTokenProvider tokenProvider;

@Autowired
private CustomUserDetailsService customUserDetailsService;

private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

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

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

    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("{}", new CustomException(HttpStatus.UNAUTHORIZED, "No Valid JWT Token Provided"));
        throw new CustomException(HttpStatus.UNAUTHORIZED, "No Valid JWT Token Provided");
    }

    filterChain.doFilter(request, response);
}
}

У меня есть все необходимые свойства в веб-конфигурации:

<!--<context:annotation-config />-->
<tx:annotation-driven/>
<context:component-scan base-package = "com.app.controller"/>

Мой Web.xml:

<web-app>

<!-- For web context -->
<servlet>
    <servlet-name>appDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appDispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- Logging -->
<context-param>
    <param-name>logbackConfigLocation</param-name>
    <param-value>/WEB-INF/classes/logback.xml</param-value>
</context-param>

<filter>
    <filter-name>jwtFilter</filter-name>
    <filter-class>com.app.controller.security.filters.JwtAuthenticationFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>jwtFilter</filter-name>
    <servlet-name>appDispatcher</servlet-name>
</filter-mapping>

</web-app>

Некоторое время размышлял над этой проблемой ..

Это все, что я получаю:

@ExceptionHandler не запускается?

@RequestMapping(produces = "application/json") не следует использовать в советах. А где выбрасывается исключение?
NiVeR 25.06.2018 10:56

Ах, я попробую ..

Joss MT 25.06.2018 11:02

Не повезло ... Даже с настроенным <aop: aspectj-autoproxy /> ...

Joss MT 25.06.2018 11:05

Где вы выбрасываете это исключение?

NiVeR 25.06.2018 11:06

NiVer Я включил это в описание ... Ура

Joss MT 25.06.2018 11:06
0
5
287
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваше исключение не перехватывается @ControllerAdvice, потому что вы выбрасываете его из класса, аннотированного @Component, а не @Controller.

Согласно документации:

Specialization of @Component for classes that declare @ExceptionHandler, @InitBinder, or @ModelAttribute methods to be shared across multiple @Controller classes.

Вы можете найти более полную ссылку здесь.

Спасибо. Какой метод тогда был бы идеальным для вызова обработчика исключений с разных уровней (не контроллера)?

Joss MT 25.06.2018 11:17

По-прежнему не повезло, даже если я аннотирую класс фильтра с помощью @Controller

Joss MT 25.06.2018 11:18

Другая проблема заключается в том, что фильтры выполняются до фактического взаимодействия с вашим контроллером, поэтому вы этого не видите. Вам следует подумать о другом способе обработки исключения для фильтров.

NiVeR 25.06.2018 11:20

Я проверил, вызываю ли я исключение сразу в контроллере, которому я отправляю запрос на отдых, он по-прежнему возвращается как HTML и не запускает ExceptionHandler

Joss MT 25.06.2018 11:21

Хорошо, теперь я понял ... Фильтр все еще вызывали. Не могли бы вы исправить полную ссылку, которую вы разместили для получения дополнительной информации. Спасибо за вашу помощь!

Joss MT 25.06.2018 11:25

Фиксированный. Простите за это.

NiVeR 26.06.2018 10:00

Другие вопросы по теме