본문 바로가기

Springboot

[spring boot] HttpMessageConverters

HttpMessageConverters

HTTP 요청 본문을 객체로 변경하거나, 객체를 HTTP 응답 본문으로 변경할 때 사용한다.

스프링 프레임워크에서 제공하는 인터페이스이고, 스프링 mvc의 일부분이다.

예시) 컨텐츠타입이 json인 요청이 들어왔다면 json message converter가 User라는 객체로 변환해준다.

{“username”:”keesun”, “password”:”123”} <-> User 

리턴 타입이 String이면 String message converter가 사용이 된다.

@ReuqestBody 와 @ResponseBody를 통해 지정할 수 있다.

@Controller
public class UserController2 {

    @GetMapping("/hello")
    public @ResponseBody String hello(){ 
        return "hello"; // String 자체를 반환한다.
    }
}

@Controller에서 @ResponseBody를 사용하지 않으면 view name resolver로 반환된다.

@Controller
public class UserController {

    @GetMapping("/hello")
    public String hello(){ 
        return "hello";
    }
}

 

[spring boot] 하지만 @ResponseBody는 @RestController가 제공해주고 있어서 생략할 수 있다.

@RestController // @ResponseBody가 포함되어 있다.
public class UserController {

    @GetMapping("/hello")
    public String hello(){ // @ResponseBody가 String 앞에 생략되어 있다.
        return "hello";
    }

    @PostMapping("/users/create") //@RequestBody는 직접 써주어야 한다.
    public User create(@RequestBody User user) {
        return user;
    }
}

 

[ 예제1 ]

JSON으로 요청하고 JSON으로 응답받는 것을 확인해보는 Test이다.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void hello() throws Exception {
        mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string("hello"));
    }

    @Test // JSON으로 만드는 테스트
    public void createUser_JSON() throws Exception {
        String userJson = "{\"username\":\"jueun\", \"password\":\"123\"}";
        mockMvc.perform(post("/users/create")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .accept(MediaType.APPLICATION_JSON_UTF8)
                .content(userJson))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.username", is(equalTo("jueun"))))
                .andExpect(jsonPath("$.password", is(equalTo("123"))));
    }

}

 

[ 예제2 ]

스프링 부트는 ViewResolver 중 하나인 ContentNegotiatingViewResolver 제공한다.

들어오는 요청의 accept header에 따라 응답이 달라지는 것을 지원한다.

accept header - 클라이언트가 어떤 타입의 응답을 원한다고 서버에게 알려주는 것이다.

더 나아가서 JSON 요청하지만 XML로 응답받도록 해보고 싶다면,

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest2 {

    @Autowired
    MockMvc mockMvc;

    @Test // JSON 요청, XML로 응답받는 테스트
    public void createUser_XML() throws Exception {
        String userJson = "{\"username\":\"jueun\", \"password\":\"123\"}";
        mockMvc.perform(post("/users/create")
                .contentType(MediaType.APPLICATION_JSON) //JSON으로 요청
                .accept(MediaType.APPLICATION_XML) // 웅답을 XML로 받아보자
                .content(userJson))
                .andDo(print()) // 실패 시 자동으로 실행됨.
                .andExpect(status().isOk())
                .andExpect(xpath("/User/username").string("jueun"))
                .andExpect(xpath("/User/password").string("123"));
    }

}

 

 

XML 메시지 컨버터를 의존성에 추가해야 한다.

HttpMessageConverters의 자동 설정 파일에서 잘 찾아보면... XmlMapper.class가 없어서 XML 관련 설정 클래스가 등록이 되지 않음을 알 수 있다

<dependency>
   <groupId>com.fasterxml.jackson.dataformat</groupId>
   <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

 

HttpMessageConverters의 자동 설정은 HttpMessageConvertersAutoConfiguration 에서 확인할 수 있다.