关键词:
我的想法是,我想将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... 查看详情