Mappingjackson2jsonview

 

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을 매핑할 수 있도록 UserUserRepository의 xml 매핑을 추가하겠습니다.

클래스를 Json Attribute로 변환하는 쉬운 방법 두 가지를 설명하도록 하겠습니다.

  1. @JsonProperty를 사용하여 속성값을 직접 바인딩
  2. @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>();
}