簡體   English   中英

如何在Spring Interceptor中使用@ExceptionHandler?

[英]How to use @ExceptionHandler in Spring Interceptor?

我正在使用springmvc為客戶端創建restful api,我有一個用於檢查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();
    }
}

在我的控制器中,我使用@ExceptionHandler來處理異常,處理InvalidTokenException的代碼看起來像

@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;
}

但不幸的是,preHandle方法拋出的異常並未被控制器中定義的異常處理程序捕獲。

任何人都可以給我一個處理異常的解決方案嗎? PS:我的控制器方法使用以下代碼生成json和xml

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

@ExceptionHandler方法移動到@ControllerAdvice注釋類可以在這里提供幫助。 請參閱: ControllerAdvice

Rembo已經在評論中建議它(標記為“不確定”),我確認這對我有用 :在這種情況下,拋出的異常被正確捕獲。

使用其他方法解決,捕獲異常並轉發到另一個控制器。

try
{
    ValidateToken(token);
} catch (InvalidTokenException ex)
{
    request.getRequestDispatcher("/api/error/invalidtoken").forward(request, response);
    return false;
} catch (TokenExpiredException ex)
{
    request.getRequestDispatcher("/api/error/tokenexpired").forward(request, response);
    return false;
}

添加一個默認的控制器,如FallbackController,使用一個空的RequestMapping路徑方法來處理所有異常請求:

@Controller
public class FallbackController {
    @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String fallback(HttpServletRequest request, HttpServletResponse response) {
        return "Anything you want";
    }

    @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;
    }
}

希望能幫助到你。

你有無效的返回類型,這就是為什么不被異常處理程序捕獲

處理程序方法支持以下返回類型:

  • 一個ModelAndView對象(Servlet MVC或Portlet MVC)。
  • 一個Model對象,通過RequestToViewNameTranslator隱式確定視圖名稱。
  • 用於公開模型的Map對象,其中視圖名稱通過RequestToViewNameTranslator隱式確定。
  • 一個View對象。
  • 一個String值,它被解釋為視圖名稱。
  • 如果方法處理響應本身(通過直接編寫響應內容,為此目的聲明類型為ServletResponse / HttpServletResponse / RenderResponse的參數)或者視圖名稱應該通過RequestToViewNameTranslator隱式確定(不聲明響應參數),則返回void在處理程序方法簽名中;僅適用於Servlet環境)。

嘗試更改您的返回類型,以使其工作。

參考: 泉源

如果您通過ur應用程序在任何地方使用@EnableWebMvc注釋,將應用HandlerExceptionResolverComposite (subclass of HandlerExceptionResolver) 因為我們知道HandlerExceptionResolver不僅會通過控制器方法執行周期調用, 而且還會在控制器之前/之后調用(例如HandlerInterceptor。 在這里檢查), HandlerExceptionResolverComposite將調用HandlerExceptionResolverComposite 因為默認情況下,HandlerExceptionResolverComposite將注冊3個解析器,其中一個是: ExceptionHandlerExceptionResolver ,基於https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/ MVC /方法/注解/ ExceptionHandlerExceptionResolver.html#doResolveHandlerMethodException-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-org.springframework.web.method.HandlerMethod-java.lang.Exception-

它將嘗試查找控制器級別@ExceptionHandler注釋並將異常轉發給該異常處理程序。 (參見上面鏈接中的“doResolveHandlerMethodException”)

所以只要你有@EnableWebMvc(為什么不呢?),你的@ExceptionHandler應該能夠捕獲從spring攔截器拋出的異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM