반응형
Jackson 및 일반 유형 참조
다음과 같이 일반 메서드에 jackson json 라이브러리를 사용하고 싶습니다.
public MyRequest<T> tester() {
TypeReference<MyWrapper<T>> typeRef = new TypeReference<MyWrapper<T>>();
MyWrapper<T> requestWrapper = (MyWrapper<T>) JsonConverter.fromJson(jsonRequest, typeRef);
return requestWrapper.getRequest();
}
...
public class MyWrapper<T> {
private MyRequest<T> request;
public MyRequest<T> getRequest() {
return request;
}
public void setRequest(MyRequest<T> request) {
this.request = request;
}
}
public class MyRequest{
private List<T> myobjects;
public void setMyObjects(List<T> ets) {
this.myobjects = ets;
}
@NotNull
@JsonIgnore
public T getMyObject() {
return myobjects.get(0);
}
}
이제 문제는 요청 객체 jackson 내부에있는 getMyObject ()를 호출 할 때 중첩 된 사용자 정의 객체를 LinkedHashMap으로 반환한다는 것입니다. T 객체를 반환해야한다고 지정하는 방법이 있습니까? 예 : Customer 유형의 개체를 보낸 경우 해당 목록에서 Customer가 반환되어야합니까?.
감사.
이것은 Java 유형 삭제의 잘 알려진 문제입니다. T는 유형 변수 일 뿐이며 실제 클래스를 표시해야하며 일반적으로 Class 인수로 표시해야합니다. 이러한 정보가 없으면 할 수있는 최선의 방법은 경계를 사용하는 것입니다. 일반 T는 'T extends Object'와 거의 동일합니다. 그리고 Jackson은 JSON 객체를 맵으로 바인딩합니다.
이 경우 tester 메서드는 Class에 대한 액세스 권한이 있어야하며
JavaType type = mapper.getTypeFactory().
constructCollectionType(List.class, Foo.class)
그리고
List<Foo> list = mapper.readValue(new File("input.json"), type);
'JavaType'이 작동합니다! 나는 json String의 List를 ArrayList Java Objects로 unmarshall (deserialize)하려고했으며 며칠 이후로 해결책을 찾기 위해 고군분투했습니다.
아래는 마침내 나에게 해결책을 준 코드입니다. 암호:
JsonMarshallerUnmarshaller<T> {
T targetClass;
public ArrayList<T> unmarshal(String jsonString) {
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
mapper.getDeserializationConfig()
.withAnnotationIntrospector(introspector);
mapper.getSerializationConfig()
.withAnnotationIntrospector(introspector);
JavaType type = mapper.getTypeFactory().
constructCollectionType(
ArrayList.class,
targetclass.getClass());
try {
Class c1 = this.targetclass.getClass();
Class c2 = this.targetclass1.getClass();
ArrayList<T> temp = (ArrayList<T>)
mapper.readValue(jsonString, type);
return temp ;
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null ;
}
}
작업 예제를 포함 하도록 rushidesai1의 답변 을 수정 했습니다 .
JsonMarshaller.java
import java.io.*;
import java.util.*;
public class JsonMarshaller<T> {
private static ClassLoader loader = JsonMarshaller.class.getClassLoader();
public static void main(String[] args) {
try {
JsonMarshallerUnmarshaller<Station> marshaller = new JsonMarshallerUnmarshaller<>(Station.class);
String jsonString = read(loader.getResourceAsStream("data.json"));
List<Station> stations = marshaller.unmarshal(jsonString);
stations.forEach(System.out::println);
System.out.println(marshaller.marshal(stations));
} catch (IOException e) {
e.printStackTrace();
}
}
@SuppressWarnings("resource")
public static String read(InputStream ios) {
return new Scanner(ios).useDelimiter("\\A").next(); // Read the entire file
}
}
산출
Station [id=123, title=my title, name=my name]
Station [id=456, title=my title 2, name=my name 2]
[{"id":123,"title":"my title","name":"my name"},{"id":456,"title":"my title 2","name":"my name 2"}]
JsonMarshallerUnmarshaller.java
import java.io.*;
import java.util.List;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
public class JsonMarshallerUnmarshaller<T> {
private ObjectMapper mapper;
private Class<T> targetClass;
public JsonMarshallerUnmarshaller(Class<T> targetClass) {
AnnotationIntrospector introspector = new JacksonAnnotationIntrospector();
mapper = new ObjectMapper();
mapper.getDeserializationConfig().with(introspector);
mapper.getSerializationConfig().with(introspector);
this.targetClass = targetClass;
}
public List<T> unmarshal(String jsonString) throws JsonParseException, JsonMappingException, IOException {
return parseList(jsonString, mapper, targetClass);
}
public String marshal(List<T> list) throws JsonProcessingException {
return mapper.writeValueAsString(list);
}
public static <E> List<E> parseList(String str, ObjectMapper mapper, Class<E> clazz)
throws JsonParseException, JsonMappingException, IOException {
return mapper.readValue(str, listType(mapper, clazz));
}
public static <E> List<E> parseList(InputStream is, ObjectMapper mapper, Class<E> clazz)
throws JsonParseException, JsonMappingException, IOException {
return mapper.readValue(is, listType(mapper, clazz));
}
public static <E> JavaType listType(ObjectMapper mapper, Class<E> clazz) {
return mapper.getTypeFactory().constructCollectionType(List.class, clazz);
}
}
Station.java
public class Station {
private long id;
private String title;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return String.format("Station [id=%s, title=%s, name=%s]", id, title, name);
}
}
data.json
[{
"id": 123,
"title": "my title",
"name": "my name"
}, {
"id": 456,
"title": "my title 2",
"name": "my name 2"
}]
참고 URL : https://stackoverflow.com/questions/6846244/jackson-and-generic-type-reference
반응형
'programing' 카테고리의 다른 글
파이썬 패키지의 일부인 모든 모듈을 나열 하시겠습니까? (0) | 2020.08.30 |
---|---|
줄 번호로 분할하는 방법 (0) | 2020.08.30 |
자바에서 이니셜 라이저와 생성자의 사용 (0) | 2020.08.30 |
Spring의 순환 종속성 (0) | 2020.08.30 |
프로그래머는 SSIS를 사용해야하며, 그렇다면 그 이유는 무엇입니까? (0) | 2020.08.30 |