如何在通用列表中读取JSON [英] How to read JSON in list of generic
问题描述
我有一个调用REST Web服务的帮助程序类.该帮助程序类在定义为通用"R"的类中从Web服务接收信息.我可以轻松地使用GSON在POJO中读取我的JSON,但是我不知道如何给它提供一个List并正确地读取它.
I have a helper class calling a REST web service. This helper class receives the information from the web service within a class defined as a generic "R". I can easily use GSON to read my JSON in a POJO, but I can't figure out how to give it a List and read it properly.
到目前为止,我已经尝试提取变量中R的类型并将其传递给List,但没有成功.我已经尝试过将Jackson与它的TypeFactory一起使用,但也没有成功,它不会将R作为其参数.
So far I have tried to extract the type of R in a variable and pass it to the List without success. I have tried using Jackson with its TypeFactory, also without success, it won't take R as its parameter.
我想做的是这样的:
resource = new GsonBuilder().create().fromJson(response,List<R>)
或与杰克逊
resource = mapper.readValue(response, List<R>);
响应"是我的JSON字符串,是我要返回的List实例的资源.
"response" being my JSON string and resource the instance of List I want to return.
我可以使用GSON或Jackson.我一直在尝试使用这两种方法,因为某些事情似乎在另一种情况下更有可能.
I can use either GSON or Jackson. I have been trying with both since some things looked more possible with one or the other.
我能够使它与非泛型一起使用,但是我所获得的只是一个JSON字段的Map列表的列表.基本上是忽略R的类型.
I was able to make it work with a non generic, but all I get with a generic is a list of list of Map of the JSON fields. It's basically ignoring the type of R.
此外,R是从称为BaseResource的类扩展而来的,所以我知道R始终是BaseResource的子级,但是我需要的字段位于该子级中.
Also, R is extended from a class called BaseResource, so I know R will always be a child of BaseResource, but the fields I need are in the child.
奖金:我真正的最终目标是让我的通用R成为特定对象的列表.因此,如果我可以拥有:
Bonus: my true end goal is to have my generic R be a list of a specific object. So if I could instead have :
resource = new GsonBuilder().create().fromJson(response,R)
和R可以是BaseResource或List.我已经使它适用于BaseResource,但是我需要通过使其大部分复制并明确声明它是List或将List传递给R来使其以某种方式使其适用于List.
and R can be either a BaseResource or a List. I already made it work for BaseResource, but I need it to make it work for List somehow either by my duplicating most of it and explicitely states it's a List or passing List to R.
我们当前的解决方法是拥有一个包含列表的包装器:
Our current workaround is to have a wrapper that contains a list:
private class Result{
private List<BaseResource> result;
}
但是我们希望Web服务返回列表,而不是像这样的包装器.
but we want the web service to return lists instead of wrappers like that.
推荐答案
听到描述了一个类似的问题,也许它将仍然可以帮助您
a similar problem is described hear maybe it will still help you
如果要反序列化泛型列表,则必须正确创建Type
You must create correctly Type if you want deserialize List of generic
public static <T> List<T> deserialize(String json, Class<T> clazz) {
Type type = TypeToken.getParameterized(List.class,clazz).getType();
return new Gson().fromJson(json, type);
}
OR
Type myType = new TypeToken<List<DTO1>>() {}.getType();
List<DTO1> deserialize = new Gson().fromJson(json, myType);
OR
您的解决方法-对我来说很好
Yours workaround -- for me is good
问题是T,因为Java不知道我的种类并生成T的类型
problem is T because Java does not know what i kind and generate Type of T
public static <T> List<T> sec(String json, Class<T> clazz) {
Type type1 = new TypeToken<List<T>>() {}.getType();
Type type2 = new TypeToken<List<DTO1>>() {}.getType();
Type type = TypeToken.getParameterized(List.class, clazz).getType();
System.out.println(type1); //==>....*List<T>
System.out.println(type2); //==>....*List<....DTO1> --> this declaration In Java
System.out.println(type); //==>....*List<....DTO1>
return new Gson().fromJson(json, type);
}
测试
这是测试更多示例以纠正运行情况
Testing
this is test for more example to correct run
package pl.jac.litsofgeneriric;
import java.lang.reflect.Type;
import java.util.List;
import java.util.UUID;
import org.junit.Assert;
import org.junit.Test;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
public class DeserializeListGenericTest {
@Test
public void deserializeDTO1() {
//given
String json = "[{\"id\":1,\"name\":\"test1\"},{\"id\":2,\"name\":\"test2\"}]";
//when
List<DTO1> deserialize = DeserializeListGeneric.deserialize(json, DTO1.class);
//then
Assert.assertEquals("test1", deserialize.get(0).name);
}
@Test
public void deserializeDTO2() {
//given
String json = "[{\"uuid\":\"97e98a6d-aae8-42cb-8731-013c207ea384\",\"name\":\"testUUID1\"},{\"uuid\":\"36c60080-7bb2-4c71-b4d8-c5a0a5fa47a2\",\"name\":\"testUUID1\"}]";
//when
List<DTO2> deserialize = DeserializeListGeneric.deserialize(json, DTO2.class);
//then
Assert.assertEquals("testUUID1", deserialize.get(0).name);
}
@Test
public void deserializeMyType() {
//given
String json = "[{\"id\":1,\"name\":\"test1\"},{\"id\":2,\"name\":\"test2\"}]";
//when
Type myType = new TypeToken<List<DTO1>>() {
}.getType();
List<DTO1> deserialize = new Gson().fromJson(json, myType);
//then
Assert.assertEquals("test1", deserialize.get(0).name);
}
@Test
public void deserializeGsonBuilder() {
//given
String json = "[{\"id\":1,\"name\":\"test1\"},{\"id\":2,\"name\":\"test2\"}]";
//when
Type myType = new TypeToken<List<DTO1>>() {
}.getType();
List<DTO1> deserialize = new GsonBuilder().create().fromJson(json, myType);
//then
Assert.assertEquals("test1", deserialize.get(0).name);
}
@Test
public void useSystemOut() {
//given
String json = "[{\"id\":1,\"name\":\"test1\"},{\"id\":2,\"name\":\"test2\"}]";
//when
List<DTO1> deserialize = sec(json, DTO1.class);
//then
Assert.assertEquals("test1", deserialize.get(0).name);
}
public static <T> List<T> sec(String json, Class<T> clazz) {
Type type1 = new TypeToken<List<T>>() {}.getType();
Type type2 = new TypeToken<List<DTO1>>() {}.getType();
Type type = TypeToken.getParameterized(List.class, clazz).getType();
System.out.println(type1); //==>....*List<T>
System.out.println(type2); //==>....*List<....DTO1> --> this declaration In Java
System.out.println(type); //==>....*List<....DTO1>
return new Gson().fromJson(json, type);
}
public static class DTO1 {
public Long id;
public String name;
}
public static class DTO2 {
public UUID uuid;
public String name;
}
}
和类DeserializeListGeneric
and class DeserializeListGeneric
package pl.jac.litsofgeneriric;
import java.lang.reflect.Type;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class DeserializeListGeneric {
public static <T> List<T> deserialize(String json, Class<T> clazz) {
Type type = TypeToken.getParameterized(List.class,clazz).getType();
return new Gson().fromJson(json, type);
}
}
这篇关于如何在通用列表中读取JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!