简体   繁体   中英

Servlet Filter not working when exception is thrown

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

@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.

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

@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 {
                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.

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 ?

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM