Spring HttpMediaTypeNotAcceptableException
1. 문제
Spring으로 API 엔드포인트를 구현할 때 일반적으로 소비/생산 미디어 유형을 지정해야 한다(소비 및 생성 매개변수를 통해). 이렇게 하면 API가 해당 특정 작업에 대해 클라이언트에 다시 반환할 수 있는 형식이 좁아진다.
HTTP 에는 클라이언트가 인식하고 수락할 수 있는 미디어 유형을 지정하는 데 사용되는 전용 “Accept” 헤더도 있다. 간단히 말해서, 서버는 클라이언트가 요청한 미디어 유형 중 하나를 사용하여 리소스 표현을 다시 보낸다.
그러나 양측이 작업할 수 있는 공통 유형이 없으면 Spring은 HttpMediaTypeNotAcceptableException 예외를 발생시킨다.
2. 실제 사례
간단한 예제이다.
application/json
에서만 작동 하고 JSON 데이터도 반환하는 POST 엔드포인트를 사용한다.
1
2
3
4
5
6
7
@PostMapping(
value = "/test",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public Map<String, String> example() {
return Collections.singletonMap("key", "value");
}
인식할 수 없는 콘텐츠 유형이 포함된 CURL을 사용하여 요청을 보낸다.
1
2
3
4
5
6
curl -X POST --header "Accept: application/pdf" http://localhost:8080/test -v
> POST /test HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.51.0
> Accept: application/pdf
응답은 다음과 같다.
1
2
< HTTP/1.1 406
< Content-Length: 0
3. 해결책
문제를 해결하는 방법은 지원되는 유형 중 하나를 보내고 받는 것이다.
허용 가능한 모든 미디어 유형에 대해 클라이언트에 알리는 사용자 정의 ExceptionHandler를 사용하여 보다 설명적인 메시지(기본적으로 Spring은 빈 본문을 반환함)를 제공하는 것이다.
application/json
뿐이다.
1
2
3
4
5
@ResponseBody
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public String handleHttpMediaTypeNotAcceptableException() {
return "acceptable MIME type:" + MediaType.APPLICATION_JSON_VALUE;
}
[출처 및 참고]
This post is licensed under CC BY 4.0 by the author.