5

すべてHandlerInterceptorAdapterのリクエストを傍受し、ユーザー認証チェックを実行する があります。非常に基本的に:

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

次に、その@ExceptionHandlerための がありAuthorizationExceptionます。

@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 用に簡単に変更できる) 場合、これは問題ありません。@ExceptionHandler特定のAcceptヘッダーに異なる を作成するにはどうすればよいですか?

@RequestMapping持っていproduces()ます。に似たものはあり@ExceptionHandlerますか?

4

3 に答える 3

2

私は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;

応答のステータス コードを設定することを忘れないでください。

于 2013-06-26T14:20:55.807 に答える
0

まったく同じユースケースではありませんが、要件は同じです。カスタム HttpMessageConverter 実装で解決します。

@RestController
@RequestMapping("/foo")
public class MyResource {

    @GetMapping(path = "/{id}", produces = "application/json")
    public ResponseEntity<MyDto> get (@PathVariable(ID) long id)
            throws IOException {

        throw new MyCustomException();
    }

    @GetMapping(path = "/{id}/export", produces = "application/zip")
    public ResponseEntity<byte[]> export (@PathVariable(ID) long id)
            throws IOException {

        throw new MyCustomException();
    }
}

...

@ControllerAdvice
public class MyCustomExceptionHandler {

    @ResponseBody
    @ExceptionHandler
    @ResponseStatus(BAD_REQUEST)
    public JsonAPIErrorDocument handleException (MyCustomException e) {

        return ....;
    }
}

...

public class JsonAPIErrorDocumentToByteArrayMessageConverter extends AbstractHttpMessageConverter {

    public ErrorDocumentToByteArrayMessageConverter () {

        super(new MediaType("application", "zip"), MediaType.ALL);
    }

    @Override
    protected boolean supports (Class clazz) {

        return JsonAPIErrorDocument.class == clazz;
    }

    @Override
    protected Object readInternal (Class clazz, HttpInputMessage inputMessage)
            throws IOException,
            HttpMessageNotReadableException {

        return new byte[0];
    }

    @Override
    protected void writeInternal (Object t, HttpOutputMessage outputMessage)
            throws IOException,
            HttpMessageNotWritableException {

    }
}

...

@EnableWebMvc
@Configuration
@ComponentScan({ "com.foo" })
public class ApplicationConfig implements WebMvcConfigurer {

    ...

    @Override
    public void configureMessageConverters (List<HttpMessageConverter<?>> converters) {

        converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
        converters.add(new ByteArrayHttpMessageConverter());
        converters.add(new JsonAPIErrorDocumentToByteArrayMessageConverter());
    }

    ...
}
于 2018-05-31T14:37:25.963 に答える