Java 一般反应<;T>;作为Json

Java 一般反应<;T>;作为Json,java,json,spring,gson,fasterxml,Java,Json,Spring,Gson,Fasterxml,我正在努力反序列化由通用结果结构包装的JSON对象: 来自服务器的MyJSON: { "totalsize": 5, "data" : [ {"name":1}, {"name":2} ] } 结果中的MyJava对象: public class ResponseTo<T> { public Long totalsize = null; public final List<T&

我正在努力反序列化由通用结果结构包装的
JSON
对象:

来自服务器的My
JSON

{
  "totalsize": 5,
  "data" : [
             {"name":1},
             {"name":2}
           ]
}
结果中的My
Java
对象:

public class ResponseTo<T> {

    public Long totalsize = null;
    public final List<T> data = new ArrayList<>();
}
在这种情况下,
T
是一个

如何使用:
GSON
和/或
com.fasterxml.jackson

我想要一个静态方法,如:

public static <T> ResponseTo<T> stringToObject(String jsonString, Class<T> clazz ) {
    final Gson gson = new Gson();
    // do some typeadapter function magic
    return gson.fromJson( jsonString, ResponseTo.class );
}
对stringToObject的公共静态响应(字符串jsonString,类clazz){
最终Gson Gson=新Gson();
//做一些typeadapter函数魔术
返回gson.fromJson(jsonString,ResponseTo.class);
}

ResponseTo<Item> responseTo = stringToObject( <json-string>, Item.class );
ResponseTo ResponseTo=stringToObject(,Item.class);
我只接收
com.google.gson.internal.LinkedTreeMap
作为数据对象


我能做些什么使它工作我这样做的方式不对吗?

您需要使用类型标记来处理泛型情况,因为Java编译器将删除
T
的类型信息,而Gson不知道要将
T
还原到什么类型

Type typeToken = new TypeToken<ResponseTo<Item>>() { }.getType();
ResponseTo<Item> responseTo = stringToObject( <json-string>, typeToken );
Type-typeToken=new-typeToken(){}.getType();
ResponseTo ResponseTo=stringToObject(,typeToken);
Gson 您可以使用internal
com.google.gson.internal.$gson$Types
类来实现以下功能:

import com.google.gson.Gson;
import com.google.gson.internal.$Gson$Types;

import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

public class GsonApp {

    public static void main(String[] args) {
        String json = "{\n" +
                "  \"totalsize\": 5,\n" +
                "  \"data\": [\n" +
                "    {\n" +
                "      \"name\": 1\n" +
                "    },\n" +
                "    {\n" +
                "      \"name\": 2\n" +
                "    }\n" +
                "  ]\n" +
                "}\n";

        System.out.println(stringToObject(json, Item.class));
    }

    static <T> ResponseTo<T> stringToObject(String jsonString, Class<T> clazz) {
        final Gson gson = new Gson();
        // do some typeadapter function magic
        ParameterizedType parameterizedType = $Gson$Types.newParameterizedTypeWithOwner(ResponseTo.class, ResponseTo.class, clazz);
        return gson.fromJson(jsonString, parameterizedType);
    }
}

class ResponseTo<T> {

    public Long totalsize = null;
    public final List<T> data = new ArrayList<>();

    @Override
    public String toString() {
        return "ResponseTo{" +
                "totalsize=" + totalsize +
                ", data=" + data +
                '}';
    }
}

class Item {
    public int name;

    @Override
    public String toString() {
        return "Item{" +
                "name=" + name +
                '}';
    }
}
杰克逊 在
Jackson
中,您可以执行类似的方法:

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        String json = "{\n" +
                "  \"totalsize\": 5,\n" +
                "  \"data\": [\n" +
                "    {\n" +
                "      \"name\": 1\n" +
                "    },\n" +
                "    {\n" +
                "      \"name\": 2\n" +
                "    }\n" +
                "  ]\n" +
                "}\n";

        System.out.println(stringToObject(json, Item.class));
    }

    static <T> ResponseTo<T> stringToObject(String jsonString, Class<T> clazz) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        // do some typeadapter function magic
        JavaType responseType = mapper.getTypeFactory().constructParametricType(ResponseTo.class, clazz);
        return mapper.readValue(jsonString, responseType);
    }
}
import com.fasterxml.jackson.databind.JavaType;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入java.io.IOException;
公共类JsonApp{
公共静态void main(字符串[]args)引发异常{
字符串json=“{\n”+
“totalsize\”:5\n+
“\“数据\”:[\n”+
“{\n”+
“\“name\”:1\n”+
},\n+
“{\n”+
“\“name\”:2\n”+
“}\n”+
“]\n”+
“}\n”;
System.out.println(stringToObject(json,Item.class));
}
对stringToObject(字符串jsonString,类clazz)的静态响应引发IOException{
ObjectMapper mapper=新的ObjectMapper();
//做一些typeadapter函数魔术
JavaType responseType=mapper.getTypeFactory().ConstructParameterType(ResponseTo.class,clazz);
返回mapper.readValue(jsonString,responseType);
}
}

如果对象中有一个类型鉴别器(即每个示例中具有唯一值的公共字段),那么Jackson
@JsonTypeInfo(JsonTypeInfo.As.EXISTING_属性…)
将允许您定义查找位置,并且初始化可以使用
ObjectMapper.registerSubtypes(Item.class)预注册所有可能的类
。杰克逊将选择正确的一个


如果要实例化哪种类型的规则比“查找字段X”更复杂,那么您必须编写自己的
@jsontypesolver
来实现所述逻辑(非常重要)

谢谢你的快速回复。是的,我得到了删除类型信息的要点。然后,每次使用另一个响应时,我都必须编写一个反序列化程序,即使默认情况下每个元素项都是可对象的(jsonstring->object)。这感觉是不对的。我不知道GSON的情况;但我知道Jackson支持多态序列化。它们通过向序列化的JSON添加一个属性来实现,该属性帮助反序列化程序自动选择正确的类。当然,这只有在序列化和反序列化都用Jackson完成的情况下才能起作用。你解决这个问题了吗?下面的答案有用吗?
ResponseTo{totalsize=5, data=[Item{name=1}, Item{name=2}]}
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        String json = "{\n" +
                "  \"totalsize\": 5,\n" +
                "  \"data\": [\n" +
                "    {\n" +
                "      \"name\": 1\n" +
                "    },\n" +
                "    {\n" +
                "      \"name\": 2\n" +
                "    }\n" +
                "  ]\n" +
                "}\n";

        System.out.println(stringToObject(json, Item.class));
    }

    static <T> ResponseTo<T> stringToObject(String jsonString, Class<T> clazz) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        // do some typeadapter function magic
        JavaType responseType = mapper.getTypeFactory().constructParametricType(ResponseTo.class, clazz);
        return mapper.readValue(jsonString, responseType);
    }
}