简体   繁体   English

Jackson,将纯JSON数组反序列化为单个Java对象

[英]Jackson, deserialize plain JSON array to a single Java object

An external service is providing a JSON array with plain/primitive elements (so without field names, and without nested JSON objects). 外部服务提供了一个具有简单/原始元素的JSON数组(因此没有字段名,也没有嵌套的JSON对象)。 For example: 例如:

["Foo", "Bar", 30]

I would like to convert this to an instance of the following Java class using Jackson: 我想使用Jackson将其转换为以下Java类的实例:

class Person {
    private String firstName;
    private String lastName;
    private int age;

    Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
}

(This class can be adapted if needed.) (如果需要,可以修改该类。)

Question: is it possible to deserialize this JSON to Java using something like this? 问题:是否可以使用类似的方法将此JSON反序列化为Java?

Person p = new ObjectMapper().readValue(json, Person.class);

Or is this only possible by writing a custom Jackson deserializer for this Person class? 还是只能通过为此Person类编写自定义的Jackson解串器来实现?

I did try the following, but that didn't work: 我确实尝试了以下方法,但是没有用:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    @JsonCreator
    public Person(
            @JsonProperty(index = 0) String firstName, 
            @JsonProperty(index = 1) String lastName, 
            @JsonProperty(index = 2) int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public static void main(String[] args) throws IOException {
        String json = "[\"Foo\", \"Bar\", 30]";
        Person person = new ObjectMapper().readValue(json, Person.class);
        System.out.println(person);
    }
}

Result: Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Argument #0 of constructor [constructor for Person, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator at [Source: (String)"["Foo", "Bar", 30]"; line: 1, column: 1] 结果: Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Argument #0 of constructor [constructor for Person, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator at [Source: (String)"["Foo", "Bar", 30]"; line: 1, column: 1] Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Argument #0 of constructor [constructor for Person, annotations: {interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator at [Source: (String)"["Foo", "Bar", 30]"; line: 1, column: 1]

You don't need @JsonCreator , just use @JsonFormat(shape = JsonFormat.Shape.ARRAY) 您不需要@JsonCreator ,只需使用@JsonFormat(shape = JsonFormat.Shape.ARRAY)

@JsonFormat(shape = JsonFormat.Shape.ARRAY)
public static class Person {
    @JsonProperty
    private String firstName;
    @JsonProperty
    private String lastName;
    @JsonProperty
    private int age;
}

And use @JsonPropertyOrder({"firstName", "lastName", "age" } ) if you need to preserve some alternative field declaration order in your bean. 如果需要在bean中保留一些替代字段声明顺序,请使用@JsonPropertyOrder({"firstName", "lastName", "age" } )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM