Mappingjackson2jsonview
Mappingjackson2jsonview는 org.springframework.web.servlet.view의 하위 클래스입니다.
이번에는 Mappingjackson2jsonview를 활용하여 View를 Json타입의 뷰로 변환하는데 사용해보도록 하겠습니다.
pom.xml
먼저 pom.xml을 열어 아래 두 의존성을 등록 하도록 합니다.
<dependencies>
<!-- 스프링 라이브러리 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
</dependencies>
라이브러리 등록을 완료 하였다면 이제 패키지로 가서 자바 설정 파일을 하나 만들어 두도록 하겠습니다.
ApplicationConfiguration
설정 파일명은 ApplicationConfiguration 로 생성하겠습니다.
public class ApplicationConfiguration { }
설정파일이 생성 되었다면 이제 초기화(initializer) 클래스를 생성하도록 하겠습니다.
초기화 클래스는 ApplicationInitializer 로 생성한 다음
스프링 이벤트 리스너인 AbstractAnnotationConfigDispatcherServletInitializer를 구현하여
이전 생성한 ApplicationConfiguration을 서블릿 설정 클래스와 서블릿 매핑 정보(“/”)를 등록합니다.
public class ApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { ApplicationConfiguration.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
UserRepository와 User
이제 저장소(Repository)와 POJO클래스를 생성하겠습니다.
저장소는 UserRepository POJO 클래스로는 User로 생성하겠습니다.
public class User { }
public class UserRepository { }
POJO클래스의 속성값을 추가하도록 하겠습니다.
속성값으로는 id, name, address 3항목을 추가한 다음 setter를 추가 하겠습니다.
public class User {
public User(String id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
private String id;
private String name;
private String address;
}
이제 저장소의 사용자를 등록하고 조회 하는 기능을 추가하겠습니다.
특정 사용자를 조회하기 위하여 findUser, 전체 사용자를 조회하기 위하여 findUserList 기능을 추가 하도록 하겠습니다.
public class UserRepository {
private Map<String, User> repository = new LinkedHashMap<String, User>();
public User findUser(String id) {
return repository.get(id);
}
public UserRepository findUserList() {
return this;
}
}
UserRepository의 초기 사용자를 등록 하겠습니다.
public class UserRepository {
public UserRepository() {
User user1 = new User("admin", "관리자" , "서울 특별시 영등포구 여의도동");
User user2 = new User("dev01", "사용자1", "전라남도 부안군 청수리");
User user3 = new User("dev02", "사용자2", "대전광역시 이수군 기립동");
User user4 = new User("dev03", "사용자3", "대구광역시 중구 동인동");
this.repository.put("admin", user1);
this.repository.put("dev01", user2);
this.repository.put("dev02", user3);
this.repository.put("dev03", user4);
}
public UserRepository findUserList() {
return this;
}
public List<User> findUserList() {
return new ArrayList<User>(repository.values());
}
private Map<String, User> repository = new LinkedHashMap<String, User>();
}
이제 준비는 끝났습니다.
이제 Mappingjackson2jsonview를 활용하여 model(Object)를 json으로 된 view로 변환하여 보도록 하겠습니다.
(BeanNameViewResolver를 사용하는 이유는 후에 컨트롤러에서 ViewResolver를 jsonView로 뷰를 매핑하기 위합입니다.)
또한 @ComponentScan을 사용하여 빈 스캐닝을 자동으로 하도록 처리합니다.
@ComponentScan(basePackageClasses = ApplicationConfiguration.class)
public class ApplicationConfiguration {
@Bean
public View jsonView() {
MappingJackson2JsonView view = new MappingJackson2JsonView();
view.setPrettyPrint(true);
return view;
}
@Bean
public ViewResolver viewResolver() {
return new BeanNameViewResolver();
}
}
AppController
이제 사용자의 요청을 받아 처리 해보도록 하겠습니다
사용자의 요청을 받아 처리하는 곳을 웹 레이어(웹 프리젠테이션 - 컨트롤러)라고 하며
웹 애플리케이션에서는 이 웹 레이어를 각각 모듈별로 엔트리 포인트로 분리하여 처리하기도 합니다.
그러며 먼저 AppController클래스를 하나 선언하고 요청을 받을 수 있는 요청 매핑(RequestMapping)을 하나 추가 하겠습니다.
(“jsonView”을 뷰 네임으로 매핑하는 것은 ApplicationConfiguration에서 MappingJackson2JsonView로 처리하여서 가능합니다.)
@Controller
public class AppController {
private UserRepository repository = new UserRepository();
@RequestMapping(value= {"/", "/{id}"})
public String home(Model mv, @PathVariable(name="id",required=false) String id) throws JsonProcessingException {
if(Objects.isNull(id)) {
mv.addAttribute(repository.findUserList());
} else {
User user = repository.findUser(id);
if(Objects.isNull(user)) {
mv.addAttribute(new User("none","none","none"));
} else {
mv.addAttribute(user);
}
}
return "jsonView";
}
}
JSON 매핑
마지막으로 JSON을 매핑할 수 있도록 User와 UserRepository의 xml 매핑을 추가하겠습니다.
클래스를 Json Attribute로 변환하는 쉬운 방법 두 가지를 설명하도록 하겠습니다.
- @JsonProperty를 사용하여 속성값을 직접 바인딩
- @JsonAutoDetect를 사용하여 내부 field/getter값 자동 바인딩
먼저 @JsonProperty를 사용하여 User를 바인딩 해 보도록 하겠습니다.
public class User{
public User() { }
public User(String id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
@JsonProperty(value="_id")
private String id;
@JsonProperty(value="_name")
private String name;
@JsonProperty(value="_address")
private String address;
}
다음 UserRepository에서는 @JsonAutoDetect를 사용하여 List로 된 필드를 자동 검색 하도록 하겠습니다.
@JsonAutoDetect(fieldVisibility=Visibility.ANY)
public class UserRepository {
public UserRepository() {
User user1 = new User("admin", "관리자", "서울 특별시 영등포구 여의도동");
User user2 = new User("dev01", "사용자1", "전라남도 부안군 청수리");
User user3 = new User("dev02", "사용자2", "대전광역시 이수군 기립동");
User user4 = new User("dev03", "사용자3", "대구광역시 중구 동인동");
this.repository.put("admin", user1);
this.repository.put("dev01", user2);
this.repository.put("dev02", user3);
this.repository.put("dev03", user4);
}
public User findUser(String id) {
return repository.get(id);
}
public UserRepository findUserList() {
return this;
}
private Map<String, User> repository = new LinkedHashMap<String, User>();
}
만일 특정 값을 직렬화 대상에서 제거 하고 싶을 때에는 @JsonIgnoreProperties를 사용하여 직렬화 대상에서 배제 할수 있습니다.
@JsonAutoDetect(fieldVisibility=Visibility.ANY)
@JsonIgnoreProperties(value= {"tagName"})
public class UserRepository {
public UserRepository() {
User user1 = new User("admin", "관리자", "서울 특별시 영등포구 여의도동");
User user2 = new User("dev01", "사용자1", "전라남도 부안군 청수리");
User user3 = new User("dev02", "사용자2", "대전광역시 이수군 기립동");
User user4 = new User("dev03", "사용자3", "대구광역시 중구 동인동");
this.repository.put("admin", user1);
this.repository.put("dev01", user2);
this.repository.put("dev02", user3);
this.repository.put("dev03", user4);
}
public User findUser(String id) {
return repository.get(id);
}
public UserRepository findUserList() {
return this;
}
private String tagName = "Repository";
private Map<String, User> repository = new LinkedHashMap<String, User>();
}