使用Jackson将JSON字符串数组映射到List <String>

Sri*_*vas 8 json jackson

我有从服务器返回的以下JSON.

 String json = {
    "values": ["name","city","dob","zip"]
 };
Run Code Online (Sandbox Code Playgroud)

我想用来ObjectMapper返回List<String>值.就像是:

List<String> response = mapper.readValue(json, List.class)
Run Code Online (Sandbox Code Playgroud)

我尝试了几种方法,但没有一种方法可行.任何帮助表示赞赏.


编辑:我不想要额外的包装器对象.我想马上List<String>离开.

Gyo*_*ely 23

Jackson中的TypeFactory允许直接映射到集合和其他复杂类型:

String json = "[ \"abc\", \"def\" ]";
ObjectMapper mapper = new ObjectMapper();

List<String> list = mapper.readValue(json, TypeFactory.defaultInstance().constructCollectionType(List.class, String.class));
Run Code Online (Sandbox Code Playgroud)

  • 这是最直接的方法,无需使用不必要的包装器或诉诸低级树 API。当然,它也适用于复杂的类,而不仅仅是字符串。 (3认同)
  • 这不是OP想要的。不适用于JSON数组字段,仅适用于顶级字段。 (2认同)

cas*_*lin 7

您可以定义一个包装器类,如下所示:

public class Wrapper {

    private List<String> values;

    // Default constructor, getters and setters omitted
}
Run Code Online (Sandbox Code Playgroud)

然后使用:

Wrapper wrapper = mapper.readValue(json, Wrapper.class);
List<String> values = wrapper.getValues();
Run Code Online (Sandbox Code Playgroud)

如果要避免包装类,请尝试以下操作:

JsonNode valuesNode = mapper.readTree(json).get("values");

List<String> values = new ArrayList<>();
for (JsonNode node : valuesNode) {
    values.add(node.asText());
}
Run Code Online (Sandbox Code Playgroud)


Ksa*_*err 5

您可能会对另一种方式感兴趣,部分类似于已接受的答案,但可以写成一行(换行符应该有助于理解)。

输入 JSON:

{
    "values": ["name", "city", "dob", "zip"]
}
Run Code Online (Sandbox Code Playgroud)

代码片段:

String json = "{\"values\":[\"name\",\"city\",\"dob\",\"zip\"]}";
ObjectMapper mapper = new ObjectMapper();

List<String> list = Arrays.asList(
    mapper.convertValue(
        mapper.readTree(json).get("values"),
        String[].class
    )
);

list.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

此代码片段输出以下内容:

name
city
dob
zip
Run Code Online (Sandbox Code Playgroud)

请注意,Arrays.asList()返回一个固定大小的列表,因为它由给定的数组支持。要获得可调整大小的列表,只需将其包装起来即可:

List<String> resizableList = new ArrayList<>(
    Arrays.asList(new String[] {"a", "b", "c"})
);
Run Code Online (Sandbox Code Playgroud)

当然,这个解决方案可以适应更复杂的情况,而不仅仅是Strings。

例如,对于给定的 POJO User

class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return String.format(
            "[User = {id: %d, name: \"%s\"}]",
            id,
            name
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

并输入 JSON:

{
    "values": [{
            "id": 1,
            "name": "Alice"
        }, {
            "id": 2,
            "name": "Bob"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

以下代码片段:

ObjectMapper mapper = new ObjectMapper();
String json = "{\"values\":[{\"id\":1,\"name\":\"Alice\"},{\"id\":2,\"name\":\"Bob\"}]}";

List<User> list = Arrays.asList(
    mapper.convertValue(
        mapper.readTree(json).get("values"),
        User[].class
    )
);

list.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

[User = {id: 1, name: "Alice"}]
[User = {id: 2, name: "Bob"}]
Run Code Online (Sandbox Code Playgroud)