Spring @RequestBody 415 Unsupported Media Type (feat. Postman)
Github에서 공개된 프로젝트 소스를 받아 Postman을 이용하여 Rest API 테스트 중 다음과 같은 오류가 발생하였다. 이미 알고 공부했던 내용임에도 불구하고 오류를 맞닦드리면 기억이 나지 않아 또 검색하여 찾게 된다. 게다가 내가 직접 코딩한 소스가 아니라면 헷갈림은 배가 된다. 시간이 지남에 따라 또 금새 잊혀지므로 간단하게나마 정리해보자.
- HTTP Status Code
415 Unsupported Media Type
- Spring Console
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported]
Spring에서는 @RequestBody, @ResponseBody 어노테이션을 사용하면 MessageConverter를 통한 데이터 변환 과정을 거친다. 내가 Github에서 받은 오픈소스는 아래 소스처럼 Controller에 @RequestBody 어노테이션을 사용하였고 포스트맨에서는 Content-Type을 x-www-form-unlencoded로 설정하여 데이터를 전송하였기 때문에 서버에서 기대한 Content-Type이 아니였으므로 에러를 발생시킨다.
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@PostMapping("/signin")
public ResponseEntity<?> signin(@Valid @RequestBody LoginRequest loginRequest) {
...
return ResponseEntity.ok().build();
}
}
서버에서는 @RequestBody 어노테이션을 사용함으로써 JSON 이나 XML 형식의 데이터를 전송을 허용하고 해당 데이터를 LoginRequest 클래스의 Java Object로 변환을 해준다. 이를 위해서는 클라이언트에서는 데이터 타입을 JSON 형식으로 보내야 한다. Body의 raw-JSON 선택하면 Headers의 Content-Type이 application/json으로 바뀌며 요청 시 정상적으로 HTTP Status Code 200을 받는다.
Content-Type을 다른 형식으로 보낼 순 없을까? 당연하게도 @RequestBody 어노테이션을 사용하지 않으면 된다. 아래 코드와 같이 @RequestBody 어노테이션을 제거하면 multipart/form-data 형식이나 application/x-www-form-urlencoded로 데이터를 전송할 수 있다.
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@PostMapping("/signin")
public ResponseEntity<?> signin(@Valid LoginRequest loginRequest) {
...
return ResponseEntity.ok().build();
}
}
번외로 ajax 또는 axios 처럼 비동기통신을 할 때 Controller에서 @RequestBody 어노테이션을 명시하여 사용하는 경우에는 아래와 같이 Content-Type을 지정해주는 것이 좋다. 기본적으로 Content-Type이 application/json으로 자동으로 인식하여 리퀘스트 헤더에 적용되는 경우도 있지만 예외적으로 그렇지 않는 경우도 있어 오류가 발생하기도 하기 때문이다.
- ajax
var data = {"username":"jiurinie" ,"password":"jiurinie"};
$.ajax({
type: 'POST',
url: '/api/auth/signin',
contentType: "application/json",
data : JSON.stringify(data),
success : function(result) {
console.log(result);
},
});
- axios
const data = {"username":"jiurinie" ,"password":"jiurinie"};
return axios.post('/api/auth/signin', data, {
headers: {
'Content-type': 'application/json',
},
});
'Programming > Spring' 카테고리의 다른 글
Spring JPA 복합키(Composite Key) 설정 (0) | 2023.06.14 |
---|
댓글