json 문자열이 있는데 다음 클래스로 직렬화 해제해야합니다.
class Data <T> {
int found;
Class<T> hits
}
어떻게합니까? 이것은 일반적인 방법입니다
mapper.readValue(jsonString, Data.class);
그러나 T가 의미하는 것을 어떻게 언급합니까?
답변
사용하는 TypeReference
각 제네릭 형식에 대한 개체 를 생성하고 역 직렬화에 사용해야합니다. 예를 들어-
mapper.readValue(jsonString, new TypeReference<Data<String>>() {});
답변
그렇게 할 수 없습니다 :과 같이 완전히 해결 된 유형을 지정해야합니다 Data<MyType>
. T
변수 일 뿐이며 의미가 없습니다.
그러나 그것이 T
정적으로 알려진 것이 아니라는 것을 의미한다면 , TypeReference
동적으로 동등한 것을 만들어야합니다 . 언급 된 다른 질문은 이미 이것을 언급 할 수 있지만 다음과 같이 보일 것입니다.
public Data<T> read(InputStream json, Class<T> contentClass) {
JavaType type = mapper.getTypeFactory().constructParametricType(Data.class, contentClass);
return mapper.readValue(json, type);
}
답변
먼저 직렬화를 수행 한 다음 직렬화 해제를 수행 할 수 있습니다.
따라서 직렬화를 수행 할 때 @JsonTypeInfo
Jackson이 클래스 정보를 json 데이터에 쓰도록 해야합니다 . 당신이 할 수있는 일은 다음과 같습니다
Class Data <T> {
int found;
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
Class<T> hits
}
그런 다음 deserialize하면 Jackson이 변수 적중이 실제로 런타임에 클래스로 데이터를 deserialize 한 것을 알 수 있습니다.
답변
클래스 Data <>
ObjectMapper mapper = new ObjectMapper();
JavaType type = mapper.getTypeFactory().constructParametrizedType(Data.class, Data.class, Parameter.class);
Data<Parameter> dataParam = mapper.readValue(jsonString,type)
답변
Util 클래스에서 정적 메소드를 작성하십시오. 파일에서 Json을 읽고 있습니다. 당신은 또한 readValue에 문자열을 줄 수 있습니다
public static <T> T convertJsonToPOJO(String filePath, Class<?> target) throws JsonParseException, JsonMappingException, IOException, ClassNotFoundException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(new File(filePath), objectMapper .getTypeFactory().constructCollectionType(List.class, Class.forName(target.getName())));
}
용법:
List<TaskBean> list = Util.<List<TaskBean>>convertJsonToPOJO("E:/J2eeWorkspaces/az_workspace_svn/az-client-service/dir1/dir2/filename.json", TaskBean.class);
답변
일반 유형의 유형을 알고있는 다른 클래스로 랩핑 할 수 있습니다.
예 :
class Wrapper {
private Data<Something> data;
}
mapper.readValue(jsonString, Wrapper.class);
여기에 구체적인 유형이 있습니다. 당신은 reified type마다 wrapper가 필요합니다. 그렇지 않으면 Jackson은 어떤 객체를 만들지 알지 못합니다.
답변
역 직렬화해야하는 JSON 문자열에는 parameter에 대한 유형 정보가 포함되어야합니다 T
.
Jackson이 매개 변수 유형에 대한 유형 정보 를 JSON 문자열에서 읽거나 쓸 수 있도록 매개 변수 T
로 클래스에 전달할 수있는 모든 클래스에 Jackson 주석을 넣어야 합니다.Data
T
T
추상 클래스를 확장하는 모든 클래스가 될 수 있다고 가정 해 봅시다 Result
.
class Data <T extends Result> {
int found;
Class<T> hits
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@JsonSubTypes.Type(value = ImageResult.class, name = "ImageResult"),
@JsonSubTypes.Type(value = NewsResult.class, name = "NewsResult")})
public abstract class Result {
}
public class ImageResult extends Result {
}
public class NewsResult extends Result {
}
매개 변수로 전달 될 수있는 각 클래스 (또는 공통 수퍼 타입) T
에 주석을 달면 Jackson은 매개 변수 T
에 대한 정보를 JSON에 포함합니다. 그런 다음 T
컴파일 타임에 매개 변수 를 몰라도 이러한 JSON을 직렬화 해제 할 수 있습니다 .
이 Jackson 문서 링크 는 다형성 역 직렬화에 대해 설명하지만이 질문을 참조하는 데 유용합니다.