抛出异常时Servlet过滤器不工作

时间:2013-09-03 19:49:48

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

我想做什么?

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

我尝试了什么?

我有一个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);
            }

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

必需吗
- 我想生成服务器令牌,即使应用程序抛出异常,以便客户端可以使用它们 - 如果例外,我可以通过{{1}}路由我的回复?

1 个答案:

答案 0 :(得分:0)

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

您可以在文章"Servlets - Exception Handling"

中获得更多详细信息