스프링 부트 활용

ViewResolve

   Spring Boot가 제공하는 ViewResolver 중 ContentNegotiatingViewResolver에 대해서 알아보자. ContentNegotiatingViewResolver는 들어오는 요청의 Accept Header1에 따라서 응답이 달라진다.

이 로직이 조금 복잡한데 어떤 요청이 들어오면 그 요청의 응답을 만들 수 있는 모든 view를 찾아내고, 최종적으로 Accept Header의 view 타입과 비교해서 선택을 한다. 경우에 따라서는 Accept Header를 제공하지 않는 경우도 많다. 이런 경우에 대비해서 format이라는 매개변수를 사용한다. /path?format=pdf와 같은 형식으로 알 수 있다.

스프링 3, ContentNegotiatingViewResolver가 처음 나왔을 때는 .json과 같은 형태도 지원했었다. 하지만 지금은 지원하지 않고 저렇게 작성할 경우 Mapping조차 되지않는다.

예제

   요청은 JSON으로 보내고 응답은 XML로 받는 예제를 만들어보자.

public class User {

    private Long id;

    private String username;

    private String password;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
@RestController
public class UserController {

    @PostMapping("/users/create")
    public User create(@RequestBody User user) {
        return user;
    }

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

    @Autowired
    MockMvc mockMvc;

    @Test
    public void createUser_XML() throws Exception {
        String userJson = "{\"username\":\"grace\", \"password\":\"123\"}";

        mockMvc.perform(post("/users/create")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .accept(MediaType.APPLICATION_XML)
                .content(userJson))
                .andExpect(status().isOk())
                .andExpect(xpath("/User/username")
                        .string("grace"))
                .andExpect(xpath("/User/password")
                        .string("123"));
    }

}

Handler를 생성하고 Test파일에 코드를 작성했다. 응답은 json으로 보냈지만, 요청은 xml로 받는다.

만일 error가 발생한다면, HttpMessageConverters가 없기 때문이므로 아래의 의존성을 추가해주도록 하자.

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

Reference


  1. 브라우저(클라이언트)에서 웹 서버로 요청 시 요청 메시지가 담기는 헤더. 브라우저(클라이언트)가 어떤 타입의 본문을 응답으로 원한다고 서버에 알려주는 것. 즉, 해당 데이터 타입만 허용하겠다는 뜻.