본문 바로가기

study/java

[Web] 415 (Unsupported Media Type) 오류 원인 살펴보기

415 Unsupported Media Type

한번쯤 만나봤을 이 골치아픈 415는 클라이언트(View)와 서버(Controller)의 요청/응답하는 데이터의 매개변수 설정이 잘못되었을 때 주로 발생한다.

 

오늘 해결방법으로 두 가지를 모두 살펴볼 것이다.

  1. 헤더 타입 설정
  2. RequestBody 설정

 

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

추천인 코드 : AF8800551

HTTP Request, Content-Type 헤더와 Accept 헤더 확인하기

 

Content-Type 헤더와 Consumes 설정
@RequestMapping의 consumes 설정과 Content-Type request 헤더가 일치할 경우에 URL이 호출된다.

 

Content-Type은 HTTP 메시지(요청과 응답 모두)에 담겨 보내는 데이터 형식을 알려주는 헤더이다.
대부분의 브라우저와 웹서버는 HTTP 표준 스펙을 따르는 Content-Type 헤더를 기준으로 HTTP 메시지에 담긴 데이터를 분석·파싱한다.
그러나 HTTP 요청의 경우 GET방식인 경우는 무조건 URL 끝에 쿼리스트링(key=value) 형식이기 때문에 Content-Type 헤더가 굳이 필요없다.
따라서 Content-Type은 POST방식이나 PUT방식처럼 BODY에 데이터를 싣어 보낼 때 중요하다.

 

일반적으로는 사용되는 Content-Type은 3가지가 있다.

 

application/json

요청 데이터가 Json {key : value}  형식일 때 사용한다.

@RequestMapping(value="/test.do", method=RequestMethod.POST, consumes="application/json;")
contentType : "application/json"

 

 

application/x-www-form-urlencoded

요청 데이터가 쿼리스트링(key=value) 형식일 때 사용한다.

 

HTML 폼을 만들어 데이터를 전송할 때 주로 사용하는 헤더이지만, 요즘은 Json Handling을 많이하기 때문에 사용이 예전에 비해 많이 줄었다.

@RequestMapping(value="/test.do", method=RequestMethod.POST, consumes="application/x-www-form-urlencoded")
contentType : "application/x-www-form-urlencoded"

 

multipart/form-data

요청 데이터에 파일이 첨부될 수 있음을 알릴 때 사용한다.

@RequestMapping(value="/test.do", method=RequestMethod.POST, consumes="multipart/form-data")
contentType : "multipart/form-data"

 

Accept 헤더와 produces 설정
@RequestMapping의 produces 설정과 Accept request 헤더가 일치할 경우에 URL이 호출된다.

브라우저(클라이언트)에서 웹서버로 요청 시 요청 메시지에 담기는 헤더이다.
Accept 헤더는 자신에게 이러한 데이터 타입만 허용하겠다는 뜻으로, 브라우저가 요청 메시지의 Accept 헤더 값을 application/json 이라고 설정했다면
웹 서버에게 나는 json 데이터만 처리할 수 있으니, json 데이터 형식으로 응답을 돌려줘라고 말하는 것과 같다.

@RequestMapping(value="/test.do", method=RequestMethod.POST, produces="application/json;")
dataType : "json"	// ajax

 

 

URI를 호출하는 클라이언트쪽은 Ajax를 기준의 예시로 작성하였다.

만약 XMLHttpRequest의 예시가 궁금하다면 각각 다음처럼 사용할 수 있다.

 

var xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.setRequestHeader('Content-type', 'application/json; charset=UTF-8;');

 

 

데이터 타입별 예제는 아래 게시글에 자세히 설명되어있으니 참고하자.

 

springboot form, ajax 데이터 타입별 Controller에서 받는 방법 @RequestParam, @RequestBody

springboot form, ajax 데이터 타입별 Controller에서 받는 방법 @RequestParam, @RequestBody 이번 포스팅에서는 springboot web project에서 form 과 ajax로 자주 사용되는 데이터타입을 전송하고 받는 방법을.....

aljjabaegi.tistory.com

 

 

 

 

@RequestBody 

위의 헤더 타입을 맞추고 나서도 415 에러가 계속 떨어지는 경우는 RequestBody 설정이 제대로 되어있지 않을 확률이 99%이다 !!

 

Jackson 라이브러리 의존성 추가

pom.xml 위치에 다음 의존성을 추가한다.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.0</version>
</dependency>

 

annotation-driven 추가 ★

dispatchar-servlet.xml (WEB-INF/config/springmvc 경로)에 다음 태그를 추가한다.

<mvc:annotation-driven />

 

Spring 3.0부터 제공하고 있는 annotation 기반의 controller 호출이나 bean  객체 등록, 매핑의 작업을 편리하게 해준다.

<mvc:annotation-driven/>을 사용하면 내부에서 자동으로 RequestMappingHandlerMapping 과 RequestMappingHandlerAdapter를 구성해주어 Handler 역할을 쉽게 구현시켜주는 것이다.

 

이 설정을 놓치는 부분이 생각보다 굉장히 많다. (나포함)

설정을 하지 않고 RequestBody를 사용한다면 제대로 동작하지 않을 수 있다.

 

https://haenny.tistory.com/280  에서 퍼옴 정리 잘되어 있음