2013-06-26 53 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是所有相同,但轉發到一個控制器,可以做平常的東西