@ExceptionHandler 没有被触发?
Posted
技术标签:
【中文标题】@ExceptionHandler 没有被触发?【英文标题】:@ExceptionHandler not being triggered? 【发布时间】:2018-12-03 19:08:02 【问题描述】:我在这个主题上看到了其他重复的堆栈溢出问题,但似乎没有一个能复制我的情况。
当抛出异常时,我的 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>
一直在讨论这个问题..
这就是我得到的全部:
【问题讨论】:
@RequestMapping(produces = "application/json")
不应在建议中使用。异常在哪里抛出?
啊,我试试看..
运气不好...即使配置了 ...
你在哪里抛出这个异常?
NiVer 我在描述中包含了这个...干杯
【参考方案1】:
@ControllerAdvice
未捕获您的异常,因为您是从使用 @Component
而不是 @Controller
注释的类中抛出的。
根据文档:
@Component 对声明类的特殊化 @ExceptionHandler、@InitBinder 或 @ModelAttribute 方法 在多个 @Controller 类之间共享。
您可以找到更完整的参考here。
【讨论】:
谢谢。那么哪种方法最适合从不同层(而不是控制器)调用异常处理程序? 即使我用@Controller注释过滤器类仍然没有运气 另一个问题是过滤器在与您的控制器进行实际交互之前执行,这就是您看不到它的原因。您应该考虑不同的方式来处理过滤器的异常。 我已经检查了我是否直接在我发送其余请求的控制器中抛出异常,它仍然作为 HTML 返回并且不会触发 ExceptionHandler 好的,我现在明白了...过滤器仍在被调用。您能否修复您发布的完整参考链接以获取更多信息。感谢您的帮助!以上是关于@ExceptionHandler 没有被触发?的主要内容,如果未能解决你的问题,请参考以下文章
如何确保 @ExceptionHandler(Exception.class) 在 Spring Boot 中最后被调用?
RestController 中 MethodArgumentNotValidException 的 Spring Boot ExceptionHandler 永远不会被调用
为啥异常在 $exceptionHandler 函数中没有属性以及如何解决此限制? DataCloneError [重复]