415 Unsupported Media Type Error
리뷰 데이터 저장하기 위해 컨트롤러로 파라미터를 매핑하는 과정에서 415 error가 발생했다.
간단히 말하자면 415 Unsupported Media Type
에러는 지원되지 않는 형식으로 클라이언트가 요청을 해서 서버가 요청에 대한 승인을 거부한 오류를 의미한다. 이럴 경우에는 ContentType, Content Encoding 데이터를 확인할 필요가 있다.
우선 파라미터로 컨트롤러와 매핑하는 방법 중 하나인 RequestBody
에 대해 잠깐 알아보자.
@RequestBody는 클라이언트가 전송하는 Json(application/json) 형태의 HTTP Body 내용을 Java Object로 변환시켜주는 역할을 한다. 따라서 Body가 존재하지 않는 Get 메소드에 @RequestBody를 활용하려고 한다면 에러가 발생하게 된다.
@RequestBody로 받는 데이터는 Spring에서 관리하는 MessageConverter들 중 하나인 MappingJackson2HttpMessageConverter
를 통해 Java 객체로 변환된다.
form 태그
를 사용하여 전송할 경우 Default ContentType은application/x-www-form-urlencoded
이다.
@RequestBody는 JSON 형태로 데이터가 들어오면 해당 json 데이터를 jackson 라이브러리를 사용하여 model 객체로 변환한다. 따라서 ContentType 이 (application/json)
이어야 한다.
현재 서버단에서는 review를 저장하는 컨트롤러에서 @RequestBody 타입으로 객체를 받아오도록 했다.
그런데 view단에서 리뷰를 작성할 때에는 form 데이터로 설정하고 ContentType을 수정하지 않았기 때문에 기본 ContetntType인 application/x-www-form-urlencoded
로 요청이 전달되므로 415 에러
가 발생한 것이다.
<div class="mb-3" name="reviewForm" id="reviewForm" method="post">
<fieldset>
<span class="text-bold">별점을 선택해주세요</span>
<input type="radio" name="reviewStar" value="5" id="rate1"><label for="rate1">★</label>
<input type="radio" name="reviewStar" value="4" id="rate2"><label for="rate2">★</label>
<input type="radio" name="reviewStar" value="3" id="rate3"><label for="rate3">★</label>
<input type="radio" name="reviewStar" value="2" id="rate4"><label for="rate4">★</label>
<input type="radio" name="reviewStar" value="1" id="rate5"><label for="rate5">★</label>
</fieldset>
<div>
<textarea class="col-auto form-control" type="text" id="reviewContents" placeholder="수강평을 남겨보세요"></textarea>
</div>
</div>
<button class="col-auto btn btn-primary btn-lg" id="review-write-btn">리뷰 등록</button>
/** 리뷰 작성 **/
$("#review-write-btn").click(function () {
const reviewStar = $('[name=reviewStar]:checked').val()
const reviewContents = $("#reviewContents").val();
const lectureId = $("#lectureId").val();
const data = {
'rate': reviewStar,
'content': reviewContents,
}
$.ajax({
type: 'post',
url: '/rest/lecture/review/' + lectureId,
data: JSON.stringify(data),
contentType : 'application/json; charset=utf-8',
beforeSend: function(xhr){
xhr.setRequestHeader(header, token);
}
}).done(function(){
window.location.reload();
}).fail(function(error){
alert(JSON.stringify(error));
})
});