使用jackson将json数组反序列化为单个java对象(代码片段)

author author     2022-12-29     706

关键词:

我的想法是,我想将JSON数组["foo", "bar"]转换为Java对象,因此我需要通过索引将每个数组元素映射到property。

假设我有以下JSON:


  "persons": [
    [
      "John",
      "Doe"
    ],
    [
      "Jane",
      "Doe"
    ]
  ]

正如您所看到的,每个人只是一个数组,其中第一个名称是索引为0的元素,而最后一个名称是索引为1的元素。

我想将它反序列化为List<Person>。我使用mapper如下:

mapper.getTypeFactory().constructCollectionType(List.class, Person.class)

其中Person.class是:

public class Person 
    public final String firstName;
    public final String lastName;

    @JsonCreator
    public Person(@JsonProperty() String firstName, @JsonProperty String lastName) 
        this.firstName = firstName;
        this.lastName = lastName;
    

我想知道我是否可以某种方式将数组索引指定为@JsonProperty参数而不是它的关键名称?

答案

感谢bureaquete建议使用自定义反序列化器。但它更适合我用SimpleModule而不是@JsonDeserialize注释注册它。下面是完整的JUnit测试示例:

@RunWith(JUnit4.class)
public class MapArrayToObjectTest 
    private static ObjectMapper mapper;

    @BeforeClass
    public static void setUp() 
        mapper = new ObjectMapper();
        SimpleModule customModule = new SimpleModule("ExampleModule", new Version(0, 1, 0, null));
        customModule.addDeserializer(Person.class, new PersonDeserializer());
        mapper.registerModule(customModule);
    

    @Test
    public void wrapperDeserializationTest() throws IOException 
        //language=JSON
        final String inputJson = "\"persons\": [[\"John\", \"Doe\"], [\"Jane\", \"Doe\"]]";
        PersonsListWrapper deserializedList = mapper.readValue(inputJson, PersonsListWrapper.class);
        assertThat(deserializedList.persons.get(0).lastName, is(equalTo("Doe")));
        assertThat(deserializedList.persons.get(1).firstName, is(equalTo("Jane")));
    

    @Test
    public void listDeserializationTest() throws IOException 
        //language=JSON
        final String inputJson = "[[\"John\", \"Doe\"], [\"Jane\", \"Doe\"]]";
        List<Person> deserializedList = mapper.readValue(inputJson, mapper.getTypeFactory().constructCollectionType(List.class, Person.class));
        assertThat(deserializedList.get(0).lastName, is(equalTo("Doe")));
        assertThat(deserializedList.get(1).firstName, is(equalTo("Jane")));
    


class PersonsListWrapper 
    public List<Person> persons;


class Person 
    final String firstName;
    final String lastName;

    Person(String firstName, String lastName) 
        this.firstName = firstName;
        this.lastName = lastName;
    


class PersonDeserializer extends JsonDeserializer<Person> 
    @Override
    public Person deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException 
        JsonNode node = jp.readValueAsTree();
        return new Person(node.get(0).getTextValue(), node.get(1).getTextValue());
    

请注意,如果您不需要包装器对象,则可以使用mapper将JSON数组[["John", "Doe"], ["Jane", "Doe"]]直接反序列化为List<Person>,如下所示:

List<Person> deserializedList = mapper.readValue(inputJson, mapper.getTypeFactory().constructCollectionType(List.class, Person.class));
另一答案

它很容易序列化,但不容易以这种方式反序列化;

可以使用@JsonValue将以下类序列化为字符串数组;

public class Person 

    private String firstName;
    private String lastName;

    //getter,setter,constructors

    @JsonValue
    public List<String> craeteArr() 
        return Arrays.asList(this.firstName, this.lastName);
    

但是要反序列化,我必须创建一个包装类,并使用@JsonDeserialize自定义反序列化;

public class PersonWrapper 

    @JsonDeserialize(using = CustomDeserializer.class)
    private List<Person> persons;

    //getter,setter,constructors

和自定义反序列化器本身;

public class CustomDeserializer extends JsonDeserializer<List<Person>> 

    @Override
    public List<Person> deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException 
        JsonNode node = jsonParser.readValueAsTree();
        ObjectMapper mapper = new ObjectMapper();
        return IntStream.range(0, node.size()).boxed()
                .map(i -> 
                    try 
                        List<String> values = mapper.readValue(node.get(i).toString(), List.class);
                        return new Person().setFirstName(values.get(0)).setLastName(values.get(1));
                     catch (IOException e) 
                        throw new RuntimeException();
                    
                ).collect(Collectors.toList());
    

您需要在反序列化器逻辑中进行适当的验证,以检查每个迷你数组是否包含正好两个值,但这很有效。

我宁愿使用这些步骤,也许隐藏@JsonDeserialize,我会做以下事情;

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonDeserialize(using = CustomDeserializer.class)
public @interface AcceptPersonAsArray 

所以你可以在PersonWrapper中使用一些自定义注释

public class PersonWrapper 

    @AcceptPersonAsArray
    private List<Person> persons;

    //getter,setter,constructors

如何使用 Jackson 将原始 JSON 反序列化为 Java 对象

】如何使用Jackson将原始JSON反序列化为Java对象【英文标题】:HowtodeserializerawJSONtoJavaobjectwithJackson【发布时间】:2021-05-2004:16:25【问题描述】:我有两个POJO:@lombok.ValuepublicclassFooStringfoo;Barbar;@lombok.ValuepublicclassBarStringbar;Stringbaz;我... 查看详情

使用 Jackson 和 Spring 将 JavaScript 数组反序列化为 Java LinkedHashSet 不会删除重复项

】使用Jackson和Spring将JavaScript数组反序列化为JavaLinkedHashSet不会删除重复项【英文标题】:DeserializationofJavaScriptarraytoJavaLinkedHashSetusingJacksonandSpringdoesn\'tremoveduplicates【发布时间】:2017-05-1508:53:09【问题描述】:假设我有这个客户... 查看详情

使用 Jackson 将 JSON 反序列化为 ArrayList<POJO>

】使用Jackson将JSON反序列化为ArrayList<POJO>【英文标题】:DeserializeJSONtoArrayList<POJO>usingJackson【发布时间】:2012-04-0710:26:03【问题描述】:我有一个Java类MyPojo,我有兴趣从JSON反序列化。我配置了一个特殊的MixIn类,MyPojoDeMi... 查看详情

Jackson 使用枚举键、POJO 值反序列化为 Map

】Jackson使用枚举键、POJO值反序列化为Map【英文标题】:JacksondeserializingintoMapwithanEnumKey,POJOValue【发布时间】:2012-11-0414:05:05【问题描述】:我正在尝试使用Jackson将JSON反序列化为JavaPOJO。在不泄露机密信息的情况下,以下是ObjectM... 查看详情

Jackson 将额外字段反序列化为 Map

】Jackson将额外字段反序列化为Map【英文标题】:JacksondeserializeextrafieldsasMap【发布时间】:2017-01-0212:51:42【问题描述】:我希望将JSON对象中的任何未知字段反序列化为Map中的条目,它是POJO的成员。例如,这里是JSON:"knownField":5,"... 查看详情

Jackson 将日期字符串反序列化为 Long

】Jackson将日期字符串反序列化为Long【英文标题】:JacksondeserializedatestringtoLong【发布时间】:2022-01-0802:52:26【问题描述】:JavaJackson能否将json字符串日期反序列化为JavaLong字段(从纪元开始的毫秒数)?这是一个要反序列化的json... 查看详情

在将 json 反序列化为对象时,使用 jackson 将 asp.net / MS 专有 json Dateformat 转换为 java8 LocalDateTime

】在将json反序列化为对象时,使用jackson将asp.net/MS专有jsonDateformat转换为java8LocalDateTime【英文标题】:Convertasp.net/MSproprietaryjsonDateformattojava8LocalDateTimewithjacksonwhiledeserializingjsontoobject【发布时间】:2017-11-0923:53:52【问题描述】:我... 查看详情

无法使用 Jackson ObjectMapper 将 Json 序列化为 Java 对象

】无法使用JacksonObjectMapper将Json序列化为Java对象【英文标题】:Can\'tserializeJsontoJavaobjectusingJacksonObjectMapper【发布时间】:2019-08-2123:12:30【问题描述】:我正在编写一个可以导出/导入数据的Javaspringbootmvc应用程序。我写了一个包... 查看详情

使用 SwiftyJSON 将 JSON 数组反序列化为 Swift 对象

】使用SwiftyJSON将JSON数组反序列化为Swift对象【英文标题】:DeserializeJSONarraytoSwiftobjectsusingSwiftyJSON【发布时间】:2016-03-2203:37:21【问题描述】:鉴于此JSON:"id":1,"name":"Bananas","rating":4,"id":2,"name":"Tacos","rating":3,"id":3,"name":"Apple","r 查看详情

使用 Jackson XmlMapper 将 XML 反序列化为 POJO

】使用JacksonXmlMapper将XML反序列化为POJO【英文标题】:XMLdeserializationtoPOJOusingJacksonXmlMapper【发布时间】:2014-10-2218:39:50【问题描述】:使用JacksonXmlMapper注释,我如何将此XML反序列化为pojo?<?xmlversion="1.0"encoding="UTF-8"?><open>... 查看详情

杰克逊将单个项目反序列化为列表

...【发布时间】:2016-05-1401:34:51【问题描述】:我正在尝试使用一项服务,该服务为我提供了一个实体,该实体具有一个字段,它是一个数组。"id":"23233","items":["name":"item1","name":"item2"]但是当数组包含单个项目时,返回项目本身,... 查看详情

Jackson - 将内部对象列表反序列化为更高级别的列表

】Jackson-将内部对象列表反序列化为更高级别的列表【英文标题】:Jackson-deserializeinnerlistofobjectstolistofonehigherlevel【发布时间】:2019-06-2218:55:45【问题描述】:使用SpringBoot和Jackson,如何将包装/内部列表直接反序列化为外部级别... 查看详情

使用 Jackson 反序列化重复键以列出

】使用Jackson反序列化重复键以列出【英文标题】:DeserializeduplicatekeystolistusingJackson【发布时间】:2020-08-1503:26:27【问题描述】:我正在尝试将json反序列化为对象。但是,json有重复的键。我无法更改json,我想使用Jackson将重复键... 查看详情

使用 Jackson 将文件类型从 Angular 反序列化为 Java

】使用Jackson将文件类型从Angular反序列化为Java【英文标题】:DeserializationofFiletypefromAngulartoJavausingJackson【发布时间】:2018-02-2614:37:06【问题描述】:在我使用SpringBoot和Angular开发的REST应用程序中,我需要向SpringBoot后端发送一个RE... 查看详情

使用 Jackson 将通用 java 对象序列化为 JSON

】使用Jackson将通用java对象序列化为JSON【英文标题】:SerializinggenericjavaobjecttoJSONusingJackson【发布时间】:2011-12-2317:37:50【问题描述】:当我尝试将以下类实例转换为JSON(使用Jackson)时publicclassRPCRespond<Result>privateintcode;private... 查看详情

使用 Jackson 反序列化对象列表

】使用Jackson反序列化对象列表【英文标题】:DeserializealistofobjectswithJackson【发布时间】:2022-01-2222:49:52【问题描述】:我有一个对象列表,每个对象都有指定的字段(变量类型),所以我想我将创建一个主类(超类),其中包... 查看详情

在scala中使用jackson反序列化json

】在scala中使用jackson反序列化json【英文标题】:Deserializationofjsonusingjacksoninscala【发布时间】:2021-06-1122:23:14【问题描述】:我正在尝试使用jacksonjsonapi将以下json字符串反序列化为scala对象"Domain1":"data-file":"dataFile1","filter":“受影... 查看详情

jackson学习

Jackson是一个能够将java对象序列化为JSON字符串,也能够将JSON字符串反序列化为java对象的框架。 无论是序列化还是反序列化,Jackson都提供了三种方式:1.JSON<-->JavaObject 2.JSON<-->JsonNodeTree(类似于XML的DOM树)3. J... 查看详情