23.11.30 TIL

전주현·2023년 11월 30일

TIL

목록 보기
14/21

converter.HttpMessageNotReadableException

1. 문제

Test코드 작성하는 과제를 하다가 controller테스트를 만들면서 막히게 되었다.
다음과 같은 테스트 코드를 실행했는데

@Test
    @DisplayName("회원가입 컨트롤러 테스트")
    void signup() throws Exception {
        //given
        MultiValueMap<String, String> signupRequestForm = new LinkedMultiValueMap<>();
        signupRequestForm.add("username","sparta");
        signupRequestForm.add("password","codingClub");

        //when-then
        mvc.perform(post("/api/signup")
                        .params(signupRequestForm)
                )
                .andDo(print());

    }

아래와 같이 HttpMessageNotReadableException 예외가 생기면서 MockHttpServletResponse의 상태가 400이고 아무값도 담기지 않게 되었다.

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/signup
       Parameters = {username=[sparta], password=[codingClub]}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.sparta.springtodoapp.controller.UserController
           Method = com.sparta.springtodoapp.controller.UserController#signup(UserRequestDto)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.http.converter.HttpMessageNotReadableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 400
    Error message = null
          Headers = []
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
> Task :test

converter.HttpMessageNotReadableException에 대해서 찾아보니 대충 json 형태가 아니라서 그렇다고 한다.

2. 해결

처음에는 반환 값이 문제인 줄 알고 계속 반환 값이 왜 문제지만 생각하면서 강의 내용과 비교하던 중 강의에서는 컨트롤러 부분에서 파라미터를 받을 때 @RequestBody로 받는 것이 아니라 @ModelAttribute 방식으로 받고 있었다.

위 테스트 코드에서처럼 params으로 넘겨주게 되면 @RequestBody 형식은 json 형식으로 변환을 못하는 것 같다.

위 코드를 아래처럼 바꿔 ModelAttribute방식(생략 가능)으로 하니 해결되었다.

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/signup
       Parameters = {username=[sparta], password=[codingClub]}
          Headers = []
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.sparta.springtodoapp.controller.UserController
           Method = com.sparta.springtodoapp.controller.UserController#signup(UserRequestDto)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = {"message":"회원가입 성공","status":201}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
> Task :test

🎈ModelAttribute를 저번에 대충 공부하고 넘겼었는데 ModelAttribute방식을 사용하려면 해당 객체에 데이터를 바인딩할 수 있는 생성자를 만들거나 setter를 설정해야 사용 가능하다

profile
개발

0개의 댓글