2020-7-7 스프링 MVC(4) 메세지 컨버터
HTTP 메세지 컨버터
- 요청 본문에서 메세지를 읽어들이거나(@RequestBody), 응답본문에 메세지를 작성할때(@ResponseBody)를 사용
- @RestController 이하의 모든 메서드에는 자동적으로 @RequestBody, @ResponseBody가 적용된다.
- 기본컨버터 : 바이트배열컨버터, 문자열컨버터, Resource컨버터, Form컨버터… (Jackson, Gson, Atom…) 등이 pom.xml에 등록되어있으면 등록된다.
- 여러개의 컨버터들이 등록되어있는데, 요청헤더의 Content-Type을 보고서 컨버터를 결정한다.
-
@GetMapping(“/message”) @ResponseBody public String message(@RequestBody String body) { return body; }
@Test public void stringMessage() throws Exception { this.mockMvc.perform(get(“/message”) .content(“hello”)) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().string(“hello”)); } -
-
- 설정방법
- 기본으로 등록해주는 컨버터에 새로운 컨버터 추가 : extendMessageConverters
- 기본등록하는 컨버터 다 무시하고 새로운 컨버터 설정 : configureMessageConverters
- 의존성추가로 컨버터 등록(추천) : maven, gradle에 의존성을 추가하면 자동으로 컨버터가 등록, WebMvcConfigureSupport.class에 등록 SpringMvc에서 제공하는 클래스
JSON HTTP 메세지 컨버터
- 스프링부트 사용 : 기본적으로 JacksonJSON 2가 의존성에 등록. => JSON용 컨버터가 등록되어있다.
- 부트사용 안할때 : 사용하고 싶은 JSON라이브러리 의존성추가(GSON, jacksonJSON, jacksonJSON2)
-
@Test public void jsonMessage() throws Exception { Person person = new Person(“jimmy”); person.setId(100L); String jsonString = objectMapper.writeValueAsString(person); this.mockMvc.perform(get(“/jsonMessage”) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(jsonString)) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath(“$.id”).value(100)) .andExpect(jsonPath(“$.name”).value(“jimmy”)); }
@GetMapping(“/jsonMessage”) @ResponseBody public Person jsonMessage(@RequestBody Person person) { return person; }
//Request Headers = [Content-Type:”application/json;charset=UTF-8”, Accept:”application/json”, Content-Length:”25”] Body = {“id”:100,”name”:”jimmy”}
//Response Status = 200 Error message = null Headers = [Content-Type:”application/json”] Content type = application/json Body = {“id”:100,”name”:”jimmy”}
- 요청에 대한 모든 정보는 perform()안에 들어가야한다.
- contentType은 어떤 형태로 데이터를 보내겠다. accept는 어떤 형태로 데이터를 받겠다라는 것을 명시한다.
- 스프링은 contentType을 확인하고 이 정보를 바탕으로 메세지컨버터를 선택한다.
- JSONPath를 이용해서 JSON값들을 테스트할 수 있다.
XML 컨버터
- 스프링이 지원하는 OXM(Object-XML-Mapper)추가 => JAXB, JacksonXML
-
스프링부트는 기본적으로 XML의존성을 추가하지 않는다. 의존성만 추가하면 알아서 등록해준다.
javax.xml.bind jaxb-api org.glassfish.jaxb jaxb-runtime org.springframework spring-oxm -
Jamb-api => 인터페이스, runtime => 구현체, oxm : 객체 => xml, xml => 객체를 마샬링, 언마샬링이라 한다. 추상화
@Configuration public class WebConfig implements WebMvcConfigurer { @Bean public Jaxb2Marshaller jaxb2Marshaller() { Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller(); jaxb2Marshaller.setPackagesToScan(Person.class.getPackage().getName()); return jaxb2Marshaller; } … }
@XmlRootElement public class Person { … }
@Test public void xmlMessage() throws Exception { Person person = new Person(“xml”); person.setId(1L);
StringWriter stringWriter = new StringWriter(); Result result = new StreamResult(stringWriter); marshaller.marshal(person, result); String xmlString = stringWriter.toString(); this.mockMvc.perform(get("/jsonMessage") .contentType(MediaType.APPLICATION_ATOM_XML) .accept(MediaType.APPLICATION_ATOM_XML) .content(xmlString)) .andDo(print()) .andExpect(status().isOk()) .andExpect(xpath("person/name").string("xml")) .andExpect(xpath("person/id").string("1")); } //Request Headers = [Content-Type:"application/atom+xml;charset=UTF-8", Accept:"application/atom+xml", Content-Length:"98"] Body = <?xml version="1.0" encoding="UTF-8" standalone="yes"?><person><id>1</id><name>xml</name></person>
//Response Headers = [Content-Type:”application/atom+xml”] Content type = application/atom+xml Body = <?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?>
1 xml - @XmlRootElement를 알려줘야한다. 그래야 JAXB가 변환할 수 있다.
정리
- @EnableWebMvc를 사용하면 기본적인 스프링MVC를 사용하겠다.
- 스프링부트에 기본적인것만 쓸거면 안붙인다.
- 추가적인 등록이 필요하면 implement WebConfigurer를 오버라이드하면 되지만 이 방법보다 application.properties에서 spring.mvc….의 설정들을 활용해보자.