How to use @ExceptionHandler in Spring Interceptor?

Wp7Beginner picture Wp7Beginner · Feb 27, 2014 · Viewed 18.8k times · Source

I am using springmvc to create restful api for client, I have an interceptor for checking the accesstoken.

public class AccessTokenInterceptor extends HandlerInterceptorAdapter
{    
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
    if (handler instanceof HandlerMethod)
    {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Authorize authorizeRequired = handlerMethod.getMethodAnnotation(Authorize.class);
        if (authorizeRequired != null)
        {
            String token = request.getHeader("accesstoken");
            ValidateToken(token);
        }
    }
    return true;
}

protected long ValidateToken(String token)
{
    AccessToken accessToken = TokenImpl.GetAccessToken(token);

    if (accessToken != null)
    {
        if (accessToken.getExpirationDate().compareTo(new Date()) > 0)
        {
            throw new TokenExpiredException();
        }
        return accessToken.getUserId();
    }
    else
    {
        throw new InvalidTokenException();
    }
}

And in my controller, I use @ExceptionHandler to handle exceptions, the code to handle InvalidTokenException looks like

@ExceptionHandler(InvalidTokenException.class)
public @ResponseBody
Response handleInvalidTokenException(InvalidTokenException e)
{
    Log.p.debug(e.getMessage());
    Response rs = new Response();
    rs.setErrorCode(ErrorCode.INVALID_TOKEN);
    return rs;
}

But unfortunately the exception throwed in preHandle method is not caught by the exception handler defined in controller.

Can any one give me an solution of handling the exception? PS: My controller method produce both json and xml using code below:

@RequestMapping(value = "login", method = RequestMethod.POST, produces =
{
    "application/xml", "application/json"
})

Answer

István Békési picture István Békési · Jan 7, 2015

Moving your @ExceptionHandler methods into a @ControllerAdvice annotated class can help here. See: ControllerAdvice

Rembo suggested it in comment already (marked as "not sure"), I confirm that works for me: in this case the thrown exceptions are caught correctly.