如何使用Jackson对一系列对象进行反序列化

Oll*_*rds 711 java json jackson

杰克逊的数据绑定的文档表明,杰克逊支持deserialising"所有支持类型的数组",但我想不通这个确切的语法.

对于单个对象,我会这样做:

//json input
{
    "id" : "junk",
    "stuff" : "things"
}

//Java
MyClass instance = objectMapper.readValue(json, MyClass.class);
Run Code Online (Sandbox Code Playgroud)

现在对于一个数组我想这样做:

//json input
[{
    "id" : "junk",
    "stuff" : "things"
},
{
    "id" : "spam",
    "stuff" : "eggs"
}]

//Java
List<MyClass> entries = ?
Run Code Online (Sandbox Code Playgroud)

有人知道是否有一个神奇的缺失命令?如果没有那么解决方案是什么?

Pro*_*uce 1524

首先创建一个映射器:

import com.fasterxml.jackson.databind.ObjectMapper;// in play 2.3
ObjectMapper mapper = new ObjectMapper();
Run Code Online (Sandbox Code Playgroud)

作为数组:

MyClass[] myObjects = mapper.readValue(json, MyClass[].class);
Run Code Online (Sandbox Code Playgroud)

如清单:

List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){});
Run Code Online (Sandbox Code Playgroud)

另一种指定List类型的方法:

List<MyClass> myObjects = mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(List.class, MyClass.class));
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一下,`List <MyClass> myObjects = Arrays.asList(mapper.readValue(json,MyClass [] .class))`比TypeRefence快10倍. (224认同)
  • 另外需要注意的是,如果在解析时遇到错误,例如`JsonMappingException:没有为类型找到合适的构造函数`那么这意味着你需要在你的类中添加一个默认构造函数,添加一个私有的无参数构造函数来修复它. (40认同)
  • 如果你有一个显式的构造函数,@ SyntaxRules添加显式构造函数是必要的 - 如果没有,编译器会自动创建公共的"空"构造函数.好点子.另一个常见问题是内部类需要是"静态" - 否则它们永远不会有零参数构造函数. (11认同)
  • 我正在寻找一个通用类型的版本. (5认同)
  • 针对我上面的评论,首先将 json 字符串解析为 jsonNode,然后像这样访问数组的属性:```JsonNode jsonNode = MAPPER.readTree(json); String arrayString = jsonNode.get("data").toString();``` 然后按照上面@Programmer Bruce 的说明进行操作。```List&lt;Source&gt; sources = MAPPER.readValue(arrayString, new TypeReference&lt;List&lt;Source&gt;&gt;() {});``` (3认同)
  • 我想知道如何做同样的事情,但使用像这样的嵌套数组: `{ "data": [ {...}, {...}, {...} ] }` 我花了现在花了几个小时试图弄清楚如何将其应用于我的情况。 (2认同)
  • @SyntaxRules 您应该将其添加为附加答案,因为这对我的案例有帮助。 (2认同)

Mar*_*hym 170

来自Eugene Tskhovrebov

List<MyClass> myObjects = Arrays.asList(mapper.readValue(json, MyClass[].class))
Run Code Online (Sandbox Code Playgroud)

这个解决方案对我来说似乎是最好的

  • 或者`List <MyClass> myObjects = Arrays.asList(mapper.treeToValue(jsonNode.get("fieldName"),MyClass [] .class))` (3认同)
  • 或`Arrays.asList(Json.fromJson(json.get(“ fieldName”),MyClass []。class))` (2认同)

小智 48

尝试这个

List<MyClass> list = mapper.readerForListOf(MyClass.class).readValue(json)
Run Code Online (Sandbox Code Playgroud)

  • 这个答案对我有用:Java 11,Jackson 2.10.5。 (2认同)

Obi*_*Jha 30

对于通用实现:

public static <T> List<T> parseJsonArray(String json,
                                         Class<T> classOnWhichArrayIsDefined) 
                                         throws IOException, ClassNotFoundException {
   ObjectMapper mapper = new ObjectMapper();
   Class<T[]> arrayClass = (Class<T[]>) Class.forName("[L" + classOnWhichArrayIsDefined.getName() + ";");
   T[] objects = mapper.readValue(json, arrayClass);
   return Arrays.asList(objects);
}
Run Code Online (Sandbox Code Playgroud)

  • Class <T []>的好构造.从未见过这个.你在哪里找到有关这方面的信息? (4认同)

Gre*_*g D 10

首先创建一个线程安全的ObjectReader实例.

ObjectMapper objectMapper = new ObjectMapper();
ObjectReader objectReader = objectMapper.reader().forType(new TypeReference<List<MyClass>>(){});
Run Code Online (Sandbox Code Playgroud)

然后使用它:

List<MyClass> result = objectReader.readValue(inputStream);
Run Code Online (Sandbox Code Playgroud)


lbe*_*tto 9

我无法使用这个答案,因为我的 linter 不允许未经检查的强制转换。

这是您可以使用的替代方案。我觉得这实际上是一个更清洁的解决方案。

public <T> List<T> parseJsonArray(String json, Class<T> clazz) throws JsonProcessingException {
  var tree = objectMapper.readTree(json);
  var list = new ArrayList<T>();
  for (JsonNode jsonNode : tree) {
    list.add(objectMapper.treeToValue(jsonNode, clazz));
  }
  return list;
}
Run Code Online (Sandbox Code Playgroud)


小智 7

try {
    ObjectMapper mapper = new ObjectMapper();
    JsonFactory f = new JsonFactory();
    List<User> lstUser = null;
    JsonParser jp = f.createJsonParser(new File("C:\\maven\\user.json"));
    TypeReference<List<User>> tRef = new TypeReference<List<User>>() {};
    lstUser = mapper.readValue(jp, tRef);
    for (User user : lstUser) {
        System.out.println(user.toString());
    }

} catch (JsonGenerationException e) {
    e.printStackTrace();
} catch (JsonMappingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)


Ola*_*röm 7

使用 ArrayList,这些不同的语法都对我有用:

ArrayList<MyClass> arrayList = ...
Run Code Online (Sandbox Code Playgroud)

使用objectMapper.getTypeFactory().constructCollectionType

objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, MyClass.class));
Run Code Online (Sandbox Code Playgroud)

使用new TypeReference

objectMapper.readValue(json, new TypeReference<ArrayList<MyClass>>(){});
Run Code Online (Sandbox Code Playgroud)

使用new ArrayList<>(Arrays.asList)

new ArrayList<>(Arrays.asList(objectMapper.readValue(json, MyClass[].class)));
Run Code Online (Sandbox Code Playgroud)

我不能说哪一个最好用,但我最终使用了最后一个:

ArrayList<MyClass> arrayList = new ArrayList<>(Arrays.asList(objectMapper.readValue(json, MyClass[].class)));
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的答案! (2认同)

Tia*_*ici 5

这是一个实用程序,可以转换 json2object 或 Object2json,无论您的 pojo(实体 T)如何

import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * 
 * @author TIAGO.MEDICI
 * 
 */
public class JsonUtils {

    public static boolean isJSONValid(String jsonInString) {
        try {
            final ObjectMapper mapper = new ObjectMapper();
            mapper.readTree(jsonInString);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    public static String serializeAsJsonString(Object object) throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper objMapper = new ObjectMapper();
        objMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        StringWriter sw = new StringWriter();
        objMapper.writeValue(sw, object);
        return sw.toString();
    }

    public static String serializeAsJsonString(Object object, boolean indent) throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper objMapper = new ObjectMapper();
        if (indent == true) {
            objMapper.enable(SerializationFeature.INDENT_OUTPUT);
            objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        }

        StringWriter stringWriter = new StringWriter();
        objMapper.writeValue(stringWriter, object);
        return stringWriter.toString();
    }

    public static <T> T jsonStringToObject(String content, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
        T obj = null;
        ObjectMapper objMapper = new ObjectMapper();
        obj = objMapper.readValue(content, clazz);
        return obj;
    }

    @SuppressWarnings("rawtypes")
    public static <T> T jsonStringToObjectArray(String content) throws JsonParseException, JsonMappingException, IOException {
        T obj = null;
        ObjectMapper mapper = new ObjectMapper();
        obj = mapper.readValue(content, new TypeReference<List>() {
        });
        return obj;
    }

    public static <T> T jsonStringToObjectArray(String content, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
        T obj = null;
        ObjectMapper mapper = new ObjectMapper();
        mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        obj = mapper.readValue(content, mapper.getTypeFactory().constructCollectionType(List.class, clazz));
        return obj;
    }
Run Code Online (Sandbox Code Playgroud)