如何在通用列表中读取JSON [英] How to read JSON in list of generic

查看:57
本文介绍了如何在通用列表中读取JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个调用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆