ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [11] Spring Web MVC: HttpMessageConverters
    Spring/Spring boot 2020. 6. 17. 08:51
    반응형

    [HttpMessageConverters]

    HttpMessageConverters에 대한 reference site는 다음과 같습니다.

     

    HttpMessageConverters는 Spring framework에서 제공하는 interface이고 Spring MVC의 일부분입니다. Http request body를 객체로 변환하거나, 객체를 Http response body로 변환할 때 사용합니다. (HTTP reqeust, response 참고) HttpMessageConverters를 사용하기 위한 annotation은 아래와 같습니다.

    • @RequestBody
    • @ResponseBody

    (위의 두 가지 annotation에 대해 참고해볼 만한 읽을거리)

     

     

    request body의 data에 맞춰 여러 종류의 HttpMessageConverter 준비되어 있으며 body의 data에 따라 선택되는 HttpMessageConverter가 달라집니다. 예를 들어 JSON [각주:1] Reqeust의 body에 JSON data가 전달되었다면 JsonMessageConverter가 사용되어 JSON -> Java object 로의 변환이 진행됩니다.

     

    return type이 Composition type[각주:2]인 경우 response 할 때는 기본적으로 JsonMessageConverter가 사용됩니다. 만약 response에 사용할 return type이 String 또는 int와 같이 단독 type인 경우는 StringMessageConverter가 사용됩니다.

     

    class에 @RestController annotation이 붙어있는 경우에는 @ResponseBody를 생랼할 수 있습니다. 만약 @RestController 대신 @Controller를 사용하면서 response body에 data를 넣어 client로 전달하기 원하는 경우에는 method의 return type 앞에 반드시 @ResponseBody를 추가해야 합니다.

     

     

     


     

    [HttpMessageConverter 사용의 예]

    사용자를 생성하는 controller를 composition type의 bean으로 등록하여 사용하는 예제입니다.

     

    main class는 일반적인 형태로 작성합니다.

    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication app = new SpringApplication();
            app.setWebApplicationType(WebApplicationType.SERVLET);
            app.run(args);
        }
    }

     

    test code를 작성합니다. (항상 test code를 먼저 작성하는 습관이 중요합니다.)

    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 createUser_JSON() throws Exception {
            String userJson = "{\"username\":\"dave\", \"password\":\"123\"}";	//	③	
            mockMvc.perform(post("/users/create")	//	④
                    .contentType(MediaType.APPLICATION_JSON)	//	⑤
                    .accept(MediaType.APPLICATION_JSON)	//	⑥
                    .content(userJson))	//	⑦
                        .andExpect(status().isOk())	//	⑧
                        .andExpect(jsonPath("$.username", is(equalTo("dave"))))	//	⑧
                        .andExpect(jsonPath("$.password", is(equalTo("123"))));	//	⑧
    
        }
    }
    

    ① UserController bean에 대해 Web MVC test를 진행합니다.

    ② @WebMvcTest annotation을 통해 MockMvc type의 bean이 생성되어 있으므로 주입받을 수 있습니다.

    ③ request body에 들어갈 JSON data를 정의합니다.

    ④ MocKMvc bean을 사용하여 /users/create URI로 request를 던져줍니다.

    ⑤ response 시 Content-Type을 application/json으로 지정합니다.

    ⑥ request 시 client가 허용할 수 있는 MIME type을  application/json으로 지정합니다. Accept로 원하는 type을 보내면 서버가 header의 content를 설정하게 됩니다.

    ⑦ request body에 JSON data를 넣어줍니다.

    ⑧ 정상적으로 response되고, response 된 JSON data 중 username이라는 key의 value는 "dave", password라는 key의 value는 "123"이 될 것을 기대하는 test입니다.

     

     

    우선 test code를 실행해봅니다. 아직 "/users/create" URI에 post request를 처리할 수 있는 controller bean을 만들어 놓지 않은 상태이기 때문에 404 error를 보면서 test를 실패하게 됩니다.

     

     

    test를 통과하기 위해 UserController class에 다음과 같이 controller를 추가합니다.

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

     

    UserController에서 사용하는 User class는 다음과 같습니다.

    package me.dave.user;
    
    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;
        }
    }
    

     

    1. JavaScript Object Notation (javascript 객체 표기법) - 중괄호 안에 key와 value가 쌍으로 구성된 data로 { "key":"value"} 형태로 표현된다. [본문으로]
    2. 여러가지 type이 복합적으로 결합되어있는 type. 즉, 여러 가지 type의 member 변수를 가진 Object type을 말함 [본문으로]

    'Spring > Spring boot' 카테고리의 다른 글

    [13] Spring Web MVC : static resource 지원  (0) 2020.06.22
    [12] Spring Web MVC : ViewResolver  (0) 2020.06.21
    [10] Spring Web MVC: Introduction  (0) 2020.06.15
    [09] Test  (0) 2020.06.10
    [08] Spring boot logging  (0) 2020.06.05

    댓글

Designed by Tistory.