【问题标题】:Servlet Filter not working when exception is thrown抛出异常时Servlet过滤器不起作用
【发布时间】:2013-09-07 03:56:58
【问题描述】:

我想做什么?

我正在尝试从服务器端生成新的时间戳令牌,客户端可以在其后续请求中使用

我尝试了什么?

我有一个 Servlet 过滤器,它环绕 REST 调用,看起来像

@WebFilter(urlPatterns = "/rest/secure")
public class SecurityFilter implements Filter {

    private static final Pattern PATTERN = Pattern.compile(":");
    private static final Logger LOGGER = LoggerFactory.getLogger(SecurityFilter.class);

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        //LOGGER.info("initializing SecurityFilter");
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
        final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        final String authToken = getAuthenticationHeaderValue((HttpServletRequest) request);

        try {
            validateAuthToken(authToken);
        } catch (IllegalArgumentException tokenNotValidException) {
            LOGGER.error("invalid token");
            httpServletResponse.sendError(401);
        }

        try {
            chain.doFilter(request, response);
        } catch (Exception e) {
            LOGGER.error("exception: " + e.getMessage());
        }finally {
            final String newAuthToken = generateNewAuthToken(authToken);
            httpServletResponse.addHeader(AUTH_TOKEN, newAuthToken);
            LOGGER.info("added new security token: " + newAuthToken);
        }
    }

在我的一个端点中,我这样做了

@PUT
public Response updateUser() {
    throw new IllegalArgumentException("just for test purposes");
}

我使用RESTEasy 处理所有基于REST 的工作。

我还使用Seam REST 库将服务器异常映射到基于REST 的异常

@ExceptionMapping.List({
        @ExceptionMapping(exceptionType = IllegalArgumentException.class, status = 400, useExceptionMessage = true),
        @ExceptionMapping(exceptionType = PersistenceException.class, status = 400, useExceptionMessage = true),
        @ExceptionMapping(exceptionType = ConstraintViolationException.class, status = 400, useExceptionMessage = true),
        @ExceptionMapping(exceptionType = ValidationException.class, status = 400, useExceptionMessage = true),
        @ExceptionMapping(exceptionType = NoResultException.class, status = 404, useExceptionMessage = true),
        @ExceptionMapping(exceptionType = IllegalStateException.class, status = 406, useExceptionMessage = true),
        @ExceptionMapping(exceptionType = NoClassDefFoundError.class, status = 404, useExceptionMessage = true),
        @ExceptionMapping(exceptionType = UnsupportedOperationException.class, status = 400, useExceptionMessage = true),
})
@ApplicationPath("/rest")
public class MarketApplicationConfiguration extends Application {
}

有问题?
- 当端点抛出异常时,回调永远不会返回到过滤器代码。
- 即使我使用try/catch/finally 如下

        try {
                chain.doFilter(request, response);
            } catch (Exception e) {
                LOGGER.error("exception: " + e.getMessage());
            }finally {
                final String newAuthToken = generateNewAuthToken(authToken);
                httpServletResponse.addHeader(AUTH_TOKEN, newAuthToken);
                LOGGER.info("added new security token: " + newAuthToken);
            }

- 但是,我可以根据Seam REST 异常映射测试IllegalArgumentException 是否映射到HTTP 400,但如果出现服务器异常,它永远不会返回到SecurityFilter 代码。

需要吗?
- 即使应用程序抛出异常,我也想生成服务器令牌,以便客​​户端可以使用它们
- 如果出现异常,我如何通过SecurityFilter 发送我的回复?

【问题讨论】:

  • +1 问得好。

标签: java rest jakarta-ee seam servlet-filters


【解决方案1】:

我认为您应该为此使用自己的异常处理程序,该处理程序可以在 web.xml 中定义,如果发生异常,您应该在异常处理程序中而不是在过滤器中处理它。

您可以在文章"Servlets - Exception Handling"中获得更多详细信息

【讨论】:

  • 这是我上面代码中@ExceptionMapping处理的内容
猜你喜欢
  • 2017-06-29
  • 2014-10-26
  • 2018-12-27
  • 1970-01-01
  • 2021-11-05
  • 2018-02-21
  • 2011-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多