有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java通用响应为Json

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

我的JSON来自服务器:

{
  "totalsize": 5,
  "data" : [
             {"name":1},
             {"name":2}
           ]
}

结果中的MyJava对象:

public class ResponseTo<T> {

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

在这种情况下(可能是其他GET请求中的任何内容)

public class Item {
    public int name;
}

在这种情况下TItem

如何将JSON有效负载反序列化到此对象结构中:
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 );
}

ResponseTo<Item> responseTo = stringToObject( <json-string>, Item.class );

我只接收com.google.gson.internal.LinkedTreeMap作为数据对象

我能做些什么使它工作我是不是走错了路


共 (3) 个答案

  1. # 1 楼答案

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

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

  2. # 2 楼答案

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

    Type typeToken = new TypeToken<ResponseTo<Item>>() { }.getType();
    ResponseTo<Item> responseTo = stringToObject( <json-string>, typeToken );
    
  3. # 3 楼答案

    格森

    您可以使用内部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 +
                    '}';
        }
    }
    

    以上代码打印:

    ResponseTo{totalsize=5, data=[Item{name=1}, Item{name=2}]}
    

    杰克逊

    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);
        }
    }