Java 8 如何使用com.fasterxml.jackson.databind.ObjectMapper将json字符串解析为相应的JAXB对象
背景:Java 8 如何使用com.fasterxml.jackson.databind.ObjectMapper将json字符串解析为相应的JAXB对象,java-8,xsd,jaxb,jackson-databind,Java 8,Xsd,Jaxb,Jackson Databind,背景: - - - [INFO] --- exec-maven-plugin:1.2.1:exec (default-cli) @ thingtst --- com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class javax.xml.bind.JAXBElement<javax.xml.datatype.XMLGregorianCal
-
-
-
[INFO] --- exec-maven-plugin:1.2.1:exec (default-cli) @ thingtst ---
com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class javax.xml.bind.JAXBElement<javax.xml.datatype.XMLGregorianCalendar>] from String value ('2017-10-18T00:00:00.000-04:00'); no single-String constructor/factory method
at [Source: {"Thing":[{"ThingNbr":"33333333","ThingDt":"2017-10-18T00:00:00.000-04:00"}]}; line: 1, column: 33] (through reference chain: aaa.bbb.ccc.generated.ThingList["Thing"]->java.util.ArrayList[0]->aaa.bbb.ccc.generated.ThingType["ThingDt"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:878)
at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:281)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:284)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1176)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:145)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:136)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:217)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:25)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2726)
at aaa.bbb.ccc.jar.Thingtst.main(Thingtst.java:18) -
-
-
(注意,date元素——即带有“nillable”属性的元素——似乎导致了“com.fasterxml.jackson.databind.JsonMappingException”)
问题:
-
-
-
[INFO] --- exec-maven-plugin:1.2.1:exec (default-cli) @ thingtst ---
com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class javax.xml.bind.JAXBElement<javax.xml.datatype.XMLGregorianCalendar>] from String value ('2017-10-18T00:00:00.000-04:00'); no single-String constructor/factory method
at [Source: {"Thing":[{"ThingNbr":"33333333","ThingDt":"2017-10-18T00:00:00.000-04:00"}]}; line: 1, column: 33] (through reference chain: aaa.bbb.ccc.generated.ThingList["Thing"]->java.util.ArrayList[0]->aaa.bbb.ccc.generated.ThingType["ThingDt"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:878)
at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:281)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:284)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1176)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:145)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:136)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:217)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:25)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2726)
at aaa.bbb.ccc.jar.Thingtst.main(Thingtst.java:18) -
-
-
如何使用com.fasterxml.jackson.databind.ObjectMapper将json字符串解析为相应的JAXB对象形式(参见下面的示例代码)
非常简单的模式如下所示(注意带有“nillable”属性的date元素):
*
*
*
*列表中允许以下类型的对象
*{@link ThingType}
*
*
*/
公共列表getThing(){
if(thing==null){
thing=newarraylist();
}
归还这个东西;
}
}
ThingType.java
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.6.3</version>
</dependency>
Thingtst.java现在看起来像这样:
JavaTimeModule module = new JavaTimeModule();
om.registerModule(module);
包aaa.bbb.ccc.jar;
导入aaa.bbb.ccc.生成。*;
导入com.fasterxml.jackson.databind.JsonMappingException;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.datatype.jsr310.*;
导入java.io.IOException;
公共类事物{
公共静态void main(字符串[]args)引发JsonMappingException{
ObjectMapper om=新的ObjectMapper();
om.setPropertyNamegstrategy(新的PreservePropertyNameStrategy());//在jackson 2.6.3:PropertyNamegstrategy.UPPER_中不可用);
registerModule(新的JavaTimeModule());
字符串jsonString=“{\'Thing\”:[{\'ThingNbr\”:\'33333333\,\'ThingDt\“:\'2017-10-18T00:00:00.000-04:00\”}”;
试试{
ThingList tl=om.readValue(jsonString,ThingList.class);//您可以尝试以下更改
Jax B的变化
1.创建一个日期时间适配器,将xs:date类型映射到java 8时间类
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-modules-java8</artifactId>
<dependency>
2.添加一个xjb文件(binding.xjb)来控制类的生成,并将其放在src/xjb下
注册适配器以在生成类时将xsd日期映射到ZonedDateTime
卸下JAXBElement包装
2.在pom中添加java时间模块
com.fasterxml.jackson.module
jackson-modules-java8
谢谢,Veeram。-我很快会尝试一下您的更改,然后回复您。:-)使用非常小的MOD(例如,依赖项名称和文件夹位置),效果很好!谢谢,Veeram!
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>aaa.bbb.ccc</groupId>
<artifactId>thingtst</artifactId>
<version>1</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.17.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jackson</artifactId>
<version>2.17.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>2.17.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<sources>
<source>src/main/resources/xsd/Thing.xsd</source>
</sources>
<packageName>aaa.bbb.ccc.generated</packageName>
<verbose default-value="false">${xjc.verbose}</verbose>
</configuration>
</plugin>
</plugins>
</build>
</project>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.6.3</version>
</dependency>
<jxb:bindings version="2.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<jxb:bindings schemaLocation="../resources/xsd/Thing.xsd">
<jxb:globalBindings generateElementProperty="false">
<jxb:javaType
name="java.time.ZonedDateTime"
xmlType="xs:date"
parseMethod="aaa.bbb.ccc.jar.DateTimeAdapter.parseDateTime"
printMethod="aaa.bbb.ccc.jar.DateTimeAdapter.formatDateTime" />
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>
package aaa.bbb.ccc.jar;
import java.time.ZonedDateTime;
public class DateTimeAdapter {
public static String formatDateTime(ZonedDateTime dateTime) {
return dateTime.toString();
}
public static ZonedDateTime parseDateTime(String dateTime) {
return ZonedDateTime.parse(dateTime);
}
}
package aaa.bbb.ccc.jar;
import aaa.bbb.ccc.generated.*;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.*;
import java.io.IOException;
public class Thingtst {
public static void main(String[] args) throws JsonMappingException {
ObjectMapper om = new ObjectMapper();
om.setPropertyNamingStrategy(new PreservePropertyNameStrategy()); //not available in jackson 2.6.3: PropertyNamingStrategy.UPPER_CASE);
om.registerModule(new JavaTimeModule());
String jsonString = "{\"Thing\":[{\"ThingNbr\":\"33333333\",\"ThingDt\":\"2017-10-18T00:00:00.000-04:00\"}]}";
try {
ThingList tl = om.readValue(jsonString, ThingList.class); //<== causes JsonMappingException!!!
System.out.println("ThingNbr=" + tl.getThing().get(0).getThingNbr() + "...ThingDt=" + tl.getThing().get(0).getThingDt());
} catch (IOException e) {
e.printStackTrace();
}
}
}
package aaa.bbb.ccc.jar;
import java.time.ZonedDateTime;
public class DateTimeAdapter {
public static String formatDateTime(ZonedDateTime dateTime) {
return dateTime.toString();
}
public static ZonedDateTime parseDateTime(String dateTime) {
return ZonedDateTime.parse(dateTime);
}
}
<jxb:bindings version="2.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<jxb:bindings schemaLocation="../resources/Thing.xsd">
<jxb:globalBindings generateElementProperty="false">
<jxb:javaType name="java.time.ZonedDateTime" xmlType="xs:date" parseMethod="aaa.bbb.ccc.jar.DateTimeAdapter.parseDateTime" printMethod="aaa.bbb.ccc.jar.DateTimeAdapter.formatDateTime" />
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>
JavaTimeModule module = new JavaTimeModule();
om.registerModule(module);
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-modules-java8</artifactId>
<dependency>