-
[Spring Boot] REST API 만들기(11) - JSON Root Element 추가Spring Boot/2.4.x - REST API 만들기 2020. 5. 20. 16:07반응형
JSON과 XML 두 방식을 모두 사용하는 경우 기본적으로 JSON은 Root Element룰 사용하지 않아 데이터 형식이 다른 경우가 있습니다. 게시글 목록 조회 시에 JSON으로 응답받는 경우 Root Element가 적용되지 않은 것을 확인할 수 있습니다.
게시글 목록 조회 시(http://localhost:8080/board) JSON, XML 응답
JSON
더보기12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879{"boards": [{"board_seq": 1,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자1","board_subject": "게시글 제목1","board_content": "게시글 내용1","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null},{"board_seq": 2,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자2","board_subject": "게시글 제목2","board_content": "게시글 내용2","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null},{"board_seq": 3,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자3","board_subject": "게시글 제목3","board_content": "게시글 내용3","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null},{"board_seq": 4,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자4","board_subject": "게시글 제목4","board_content": "게시글 내용4","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null},{"board_seq": 5,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자5","board_subject": "게시글 제목5","board_content": "게시글 내용5","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null}]}cs XML
더보기1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768<?xml version="1.0" encoding="UTF-8" standalone="yes"?><boards><board><board_seq>1</board_seq><board_re_ref>0</board_re_ref><board_re_lev>0</board_re_lev><board_re_seq>0</board_re_seq><board_writer>게시글 작성자1</board_writer><board_subject>게시글 제목1</board_subject><board_content>게시글 내용1</board_content><board_hits>0</board_hits><del_yn>N</del_yn><ins_user_id>TEST</ins_user_id><ins_date>2020-05-19 18:30:24</ins_date></board><board><board_seq>2</board_seq><board_re_ref>0</board_re_ref><board_re_lev>0</board_re_lev><board_re_seq>0</board_re_seq><board_writer>게시글 작성자2</board_writer><board_subject>게시글 제목2</board_subject><board_content>게시글 내용2</board_content><board_hits>0</board_hits><del_yn>N</del_yn><ins_user_id>TEST</ins_user_id><ins_date>2020-05-19 18:30:24</ins_date></board><board><board_seq>3</board_seq><board_re_ref>0</board_re_ref><board_re_lev>0</board_re_lev><board_re_seq>0</board_re_seq><board_writer>게시글 작성자3</board_writer><board_subject>게시글 제목3</board_subject><board_content>게시글 내용3</board_content><board_hits>0</board_hits><del_yn>N</del_yn><ins_user_id>TEST</ins_user_id><ins_date>2020-05-19 18:30:24</ins_date></board><board><board_seq>4</board_seq><board_re_ref>0</board_re_ref><board_re_lev>0</board_re_lev><board_re_seq>0</board_re_seq><board_writer>게시글 작성자4</board_writer><board_subject>게시글 제목4</board_subject><board_content>게시글 내용4</board_content><board_hits>0</board_hits><del_yn>N</del_yn><ins_user_id>TEST</ins_user_id><ins_date>2020-05-19 18:30:24</ins_date></board><board><board_seq>5</board_seq><board_re_ref>0</board_re_ref><board_re_lev>0</board_re_lev><board_re_seq>0</board_re_seq><board_writer>게시글 작성자5</board_writer><board_subject>게시글 제목5</board_subject><board_content>게시글 내용5</board_content><board_hits>0</board_hits><del_yn>N</del_yn><ins_user_id>TEST</ins_user_id><ins_date>2020-05-19 18:30:24</ins_date></board></boards>cs JSON Root Element 추가
1. pom.xml 의존성 추가
pom.xml에 Jackson 어노테이션 대안으로 JAXB 어노테이션을 사용할수 있도록 지원하는 jackson-module-jaxb-annotations를 추가하세요.
pom.xml
더보기12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.8</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.api</groupId><artifactId>board</artifactId><version>0.0.1-SNAPSHOT</version><name>board</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-configuration-processor --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4.1 --><dependency><groupId>org.bgee.log4jdbc-log4j2</groupId><artifactId>log4jdbc-log4j2-jdbc4.1</artifactId><version>1.16</version></dependency><!-- JUnit4 사용하기 위해서 Vintage Engine 모듈을 제외 --><dependency><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.hamcrest</groupId><artifactId>hamcrest-core</artifactId></exclusion></exclusions></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-oxm --><dependency><groupId>org.springframework</groupId><artifactId>spring-oxm</artifactId></dependency><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.module/jackson-module-jaxb-annotations --><dependency><groupId>com.fasterxml.jackson.module</groupId><artifactId>jackson-module-jaxb-annotations</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>cs 2. WebMvcConfig.java 수정
application/json 형태로 응답 시 @XmlRootName 애노테이션을 적용하려면, ObjectMapper에 DeserializationFeature.UNWRAP_ROOT_VALUE, SerializationFeature.WRAP_ROOT_VALUE 옵션을 추가한 후 JaxbAnnotationModule을 모듈로 등록하세요.
WebMvcConfig.java
더보기123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960package com.api.board.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.ComponentScan.Filter;import org.springframework.context.annotation.Configuration;import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;import org.springframework.http.converter.xml.MarshallingHttpMessageConverter;import org.springframework.oxm.jaxb.Jaxb2Marshaller;import org.springframework.stereotype.Controller;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import com.api.board.interceptor.BoardInterceptor;import com.fasterxml.jackson.databind.DeserializationFeature;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.SerializationFeature;import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;@ComponentScan(basePackages = {"com.api.board.controller"}, useDefaultFilters = false, includeFilters = {@Filter(Controller.class)})@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new BoardInterceptor()).addPathPatterns("/**").excludePathPatterns("/sample/**");}@Beanpublic MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();ObjectMapper objectMapper = converter.getObjectMapper();objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);JaxbAnnotationModule module = new JaxbAnnotationModule();objectMapper.registerModule(module);return converter;}@Beanpublic MarshallingHttpMessageConverter marshallingHttpMessageConverter() {MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();converter.setMarshaller(jaxb2Marshaller());converter.setUnmarshaller(jaxb2Marshaller());return converter;}@Beanpublic Jaxb2Marshaller jaxb2Marshaller() {Jaxb2Marshaller marshaller = new Jaxb2Marshaller();marshaller.setPackagesToScan(new String[] { "com.api.board.domain" });return marshaller;}}cs 3. JSON Root Element 확인
게시글 목록 조회 시에 JSON으로 응답받는 경우 Root Element가 적용된 것을 확인할 수 있습니다.
게시글 목록 조회 시(http://localhost:8080/board) JSON 응답
JSON
더보기123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081{"boards": {"board": [{"board_seq": 1,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자1","board_subject": "게시글 제목1","board_content": "게시글 내용1","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null},{"board_seq": 2,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자2","board_subject": "게시글 제목2","board_content": "게시글 내용2","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null},{"board_seq": 3,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자3","board_subject": "게시글 제목3","board_content": "게시글 내용3","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null},{"board_seq": 4,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자4","board_subject": "게시글 제목4","board_content": "게시글 내용4","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null},{"board_seq": 5,"board_re_ref": 0,"board_re_lev": 0,"board_re_seq": 0,"board_writer": "게시글 작성자5","board_subject": "게시글 제목5","board_content": "게시글 내용5","board_hits": 0,"del_yn": "N","ins_user_id": "TEST","ins_date": "2020-05-19 18:30:24","upd_user_id": null,"upd_date": null}]}}cs 소스 코드는 Github Repository - https://github.com/tychejin1218/api-board_v1 (branch : section11) 를 참조하세요.
Github에서 프로젝트 가져오기 - https://tychejin.tistory.com/33
반응형'Spring Boot > 2.4.x - REST API 만들기' 카테고리의 다른 글
[Spring Boot] REST API 만들기(13) - 예외 처리 및 테스트 (0) 2020.05.21 [Spring Boot] REST API 만들기(12) - Content Negotiation 설정 (0) 2020.05.20 [Spring Boot] REST API 만들기(10) - XML 요청/응답 구현 및 테스트 (0) 2020.05.19 [Spring Boot] REST API 만들기(9) - Controller 구현 및 테스트(Junit4) (0) 2020.05.10 [Spring Boot] REST API 만들기(8) - Service 구현 및 테스트(Junit4) (0) 2020.05.09