2013-06-26 117 views
2

我有一个HandlerInterceptorAdapter,它拦截所有请求并执行用户授权检查。很基本:基于Accept头的Spring MVC - @ExceptionHandler

@Override 
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
    User user = ... // get user 
    checkIfAuthorized(user); // throws AuthorizationException 
    return true; 
} 

我再有那个AuthorizationException一个@ExceptionHandler

@ExceptionHandler(value = AuthorizationException.class) 
public ResponseEntity<String> handleNotAuthorized(AuthorizationException e) { 
    // TODO Custom EXCEPTION HANDLER for json/jsp/xml/other types, based on content type 
    ResponseEntity<String> responseEntity = new ResponseEntity<>("You are not authorized to access that page.", HttpStatus.UNAUTHORIZED); 
    return responseEntity; 
} 

这是细如果(未授权的)请求接受text/plain(和可以容易地改变为JSON)。 如何为特定的Accept标题制作不同的@ExceptionHandler

@RequestMappingproduces()@ExceptionHandler有类似的东西吗?

回答

2

我认为两种方法:

手动

public ResponseEntity<String> handleNotAuthorized(AuthorizationException e, HttpServletRequest request) { 
    // TODO Custom EXCEPTION HANDLER for json/jsp/xml/other types, based on content type 
    if (/*read header accept from request and build appropiate response*/) {} 
    ResponseEntity<String> responseEntity = new ResponseEntity<>("You are not authorized to access that page.", HttpStatus.UNAUTHORIZED); 
    return responseEntity; 

自动

@ResponseBody 
public SomeObject handleNotAuthorized(AuthorizationException e, HttpServletRequest request) { 
    // TODO Custom EXCEPTION HANDLER for json/jsp/xml/other types, based on content type 
    /* Construct someObject and let Spring MessageConverters transform it to JSON or XML. I don't remember what happens in case of HTML (it should go to a view)*/ 
    return someObject; 

不要忘记设置响应的状态码。

+0

在第二个例子中,HTML,它会使用[RequestToViewNameTranslator(HTTP://静态.springsource.org /弹簧/文档/ 3.2.x中/ Javadoc的API /组织/ springframework的/网络/ servlet的/ RequestToViewNameTranslator.html)。我有点不想以路径命名的jsp。用你的第一个例子,我不想为'text/html'返回一个视图名称,使用'ResponseEntity'可以吗? –

+0

它看起来像ResponseEntity更加面向REST响应。你应该返回一个ModelAndView(或者只有一个View)。 – Luciano

+0

你建议简单的使用返回类型'Object'并返回基于头部的信息? –

0

我知道这件事很晚,但我一直在寻找解决方案,遇到了这个问题,并发现我认为是一个更好的解决方案。您可以返回 “前进:/错误” 在你的@ExceptionHandler(返回一个字符串)将请求转发到

@RequestMapping("/error") 
ErrorController {...} 

,并在该ErrorController的一种方法使用

@RequestMapping(produces = "text/html") 
ModelAndView errorPage() {...} 

@RequestMapping(produces = "application/json") // or no 'produces' attribute for a default 
MyJsonObject errorJson() {...} on another. 

我认为这是一个非常干净的方式来做到这一点,它可能已经在那里,但我没有找到它时,试图查找它。

所以基本上@ExceptionHandler是所有相同,但转发到一个控制器,可以做平常的东西