본문 바로가기

Spring

[JSON] Json에 클래스 상속 적용하기 (JsonSubType)

728x90

상속받은 클래스에 대한 JSON 처리를 하려면 JsonSubType을 활용해야합니다.

클래스 구조

활용방법을 위한 클래스가 다음과 같이 있다고 가정하겠습니다.

package me.oofbird.vo;

public class MainClass {
	private String type;
    
    public void setType(String type) {
    	this.type = type;
	}
    
    public String getType() {
    	return this.type;
	}
}
package me.oofbird.vo.sub1;

import me.oofbird.vo.MainClass;

public class Sub1MainClass extends MainClass {
	Sub1MainClass() {
		this.setType("Sub1");
	}
}
package me.oofbird.vo.sub2;

import me.oofbird.vo.MainClass;

public class Sub2MainClass extends MainClass {
	Sub1MainClass() {
		this.setType("Sub2");
	}
}

MixIn 정의

@JsonTypeInfo와 @JsonSubTypes를 활용하여 하위 타입을 정의합니다.

package me.oofbird.mapper;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import me.oofbird.vo.MainClass;
import me.oofbird.vo.sub1.Sub1MainClass;
import me.oofbird.vo.sub2.Sub2MainClass;

@JsonTypeInfo(
	use = JsonTypeInfo.Id.NAME,
	include = JsonTypeInfo.As.EXISTING_PROPERTY,
	property = "type",
	visible = true,
	defaultImpl = MainClass.class
)
@JsonSubTypes({
	@JsonSubTypes.Type(value = Sub1MainClass.class, name = "Sub1"),
	@JsonSubTypes.Type(value = Sub2MainClass.class, name = "Sub2")
})
public interface MainClassMixIn {
}

여기서, @JsonTypeInfo와 @JsonSubTypes를 MainClass에 정의해도 무방합니다.

단, 위와 같이 패키지가 다를 경우에는 Cyclic Dependency 가 발생됩니다.

  • me.oofbird.vo > me.oofbird.vo.sub1 > me.oofbird.vo
  • me.oofbird.vo > me.oofbird.vo.sub2 > me.oofbird.vo

이것을 해결하기 위하여 다른 패키지에 MixIn을 정의합니다.

ObjectMapper에 MixIn 설정

ObjectMapper에 구성한 클래스와 MixIn을 서로 연결합니다.

아래의 경우 Configuration으로 구성하고 Bean으로 등록된 ObjectMapper에 설정하는 것 입니다.

package me.oofbird.mapper

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;

import me.oofbird.vo.MainClass;

@Configuration
public class ObjectMapperConfiguration {
	private final ObjectMapper objectMapper;
    
	public ObjectMapperConfiguration(ObjectMapper objectMapper) {
		this.objectMapper = objectMapper;
	}
    
	@PostConstruct
	public void init() {
		this.objectMapper.addMixIn(MainClass.class, MainClassMixIn.class);
	}
}   

 

반응형