[英]How to use @ExceptionHandler with Spring Interceptor for two JSP pages?
[英]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
使用其他方法解決,捕獲異常並轉發到另一個控制器。
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.