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

时间:2022-07-28 21:11:59

What am I trying to do?

我想做什么?

I am trying to generate new timestamped tokens from server side that client can use in their subsequent request

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

What I have tried?

我试过了什么?

I have a Servlet filter which wraps around REST calls and looks like

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

and in one of my endpoints I do

在我的一个端点我做

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

I am using RESTEasy for all REST based work.

我正在使用RESTEasy进行所有基于REST的工作。

and I am also using Seam REST library to map server exceptions to REST based exceptions

我还使用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 {
}

Problem?
- when endpoint throws the exception, the callback is never returned to the filter code.
- This is even when I use try/catch/finally as follows

问题? - 当端点抛出异常时,回调永远不会返回到过滤器代码。 - 即使我使用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);
            }

- I can however test that the IllegalArgumentException is mapped to HTTP 400 based on Seam REST exception mapping, but it is never returned back to the SecurityFilter code in case of server exceptions.

- 但我可以测试IllegalArgumentException是否基于Seam REST异常映射映射到HTTP 400,但是在服务器异常的情况下它永远不会返回到SecurityFilter代码。

Required?
- I want to generate server tokens even when the application throws exception(s) so that client can use them
- How can, in case of exceptions, I can route my response through SecurityFilter?

需要? - 我想生成服务器令牌,即使应用程序抛出异常,以便客户端可以使用它们 - 如果出现异常,我可以通过SecurityFilter路由我的响应?

1 个解决方案

#1


0  

i think you should use for this purpose own exceptions handler which can be defined in web.xml and in case of exception you should process it inside exception handler and not in filter.

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

you can get more details in article "Servlets - Exception Handling"

你可以在文章“Servlets - 异常处理”中获得更多细节

#1


0  

i think you should use for this purpose own exceptions handler which can be defined in web.xml and in case of exception you should process it inside exception handler and not in filter.

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

you can get more details in article "Servlets - Exception Handling"

你可以在文章“Servlets - 异常处理”中获得更多细节