2013-06-26 2 views
2

나는 모든 요청을 가로 채고 사용자 권한 검사를 수행하는 HandlerInterceptorAdapter을 가지고 있습니다. 아주 기본적으로 :스프링 MVC - AcceptException 헤더 기반의 @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/spring/docs/3.2.x/javadoc-api/org/springframework/web/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는하지만 앞으로 두 번째 예에서는 보통의 물건