How to handle java.util.Date with MOXy bindings file

I am new to MOXy and JaxB in general, and I am having trouble converting java.util.Date.

I decrypted an XML file (which I do not control) for objects using a mapping file (I can neither annotate existing classes manually nor modify them).

My XML mapping file is as follows:

<?xml version="1.0"?> <xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" version="2.1"> <java-types> <java-type name="Observation"> <xml-type prop-order="date theoricalTime ci ch cr type" /> <java-attributes> <xml-element java-attribute="date" xml-path="Date/text()" /> <xml-element java-attribute="theoricalTime" xml-path="TheoricalTime/text()" /> <xml-element java-attribute="ci" xml-path="CIPR/text()" /> <xml-element java-attribute="ch" xml-path="CHPR/text()" /> <xml-element java-attribute="cr" xml-path="CRPR/text()" /> <xml-element java-attribute="type" xml-path="Type/text()" /> </java-attributes> </java-type> </java-types> </xml-bindings> 

In the class that I am compiling, the "date" and "theoricalTime" properties are of type java.util.Date.

The values ​​from the xml that I collect are strings with the following format: "dd / MM / yyyy HH: mm: ss" ("05/01/2012 16:36:24"). I also have fields with only the time value "HH: mm: ss" ("14:17:33").

Here is the stack I get when unmarshalling a file:

 Exception in thread "main" Local Exception Stack: Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ConversionException Exception Description: The object [22/01/2009 20:56:29], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[date-->Date/text()]] with descriptor [XMLDescriptor(Observation --> [DatabaseTable(Observation)])], could not be converted to [class java.util.Calendar]. at org.eclipse.persistence.exceptions.ConversionException.incorrectDateTimeFormat(ConversionException.java:127) at org.eclipse.persistence.exceptions.ConversionException.incorrectDateTimeFormat(ConversionException.java:133) at org.eclipse.persistence.internal.oxm.XMLConversionManager.convertStringToXMLGregorianCalendar(XMLConversionManager.java:703) at org.eclipse.persistence.internal.oxm.XMLConversionManager.convertStringToDate(XMLConversionManager.java:1111) at org.eclipse.persistence.internal.oxm.XMLConversionManager.convertObjectToUtilDate(XMLConversionManager.java:804) at org.eclipse.persistence.internal.oxm.XMLConversionManager.convertObject(XMLConversionManager.java:165) at org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform.convertObject(DatasourcePlatform.java:160) at org.eclipse.persistence.oxm.mappings.XMLDirectMapping.getAttributeValue(XMLDirectMapping.java:293) at org.eclipse.persistence.internal.oxm.XMLDirectMappingNodeValue.endElement(XMLDirectMappingNodeValue.java:182) at org.eclipse.persistence.oxm.record.UnmarshalRecord.endElement(UnmarshalRecord.java:823) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1774) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2930) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522) at org.eclipse.persistence.internal.oxm.record.XMLReader.parse(XMLReader.java:157) at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:753) at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:333) at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:320) at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:280) at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:306) at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:115) at Main.Test(Main.java:97) at Main.main(Main.java:35) 

My question is: is it possible to specify conversion types inside a mapping file using MOXy external metadata? How can I process the date and time with the above formats and match them with the Date fields?

(I secretly hope that Blaze Dohan reads this.)

Thanks in advance for your help!

+4
source share
1 answer

The following shows how you can use the XmlAdapter with a MOXy external cartographic document to achieve the results you are looking for:

Dateadapter

Since the date / time data is in the following format dd/MM/yyyy HH:mm:ss , you need to use the XmlAdapter , as shown below:

 package forum8745305; import java.text.SimpleDateFormat; import java.util.Date; import javax.xml.bind.annotation.adapters.XmlAdapter; public class DateAdapter extends XmlAdapter<String, Date> { private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); @Override public String marshal(Date v) throws Exception { return dateFormat.format(v); } @Override public Date unmarshal(String v) throws Exception { return dateFormat.parse(v); } } 

oxm.xml

This is usually indicated in your domain model using the @XmlJavaTypeAdapter annotation, but since you are using the MOXy external metadata document, you can specify it as follows. I pointed it out at the package level so that it applies to all fields / properties of the java.util.Date type that belong to the domain classes in this package:

 <?xml version="1.0"?> <xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" version="2.1" package-name="forum8745305"> <xml-java-type-adapters> <xml-java-type-adapter value="forum8745305.DateAdapter" type="java.util.Date"/> </xml-java-type-adapters> <java-types> <java-type name="Observation"> <xml-type prop-order="date theoricalTime ci ch cr type" /> <xml-root-element/> <java-attributes> <xml-element java-attribute="date" xml-path="Date/text()"/> <xml-element java-attribute="theoricalTime" xml-path="TheoricalTime/text()" /> <xml-element java-attribute="numeroTrain" xml-path="NumeroTrain/text()" /> <xml-element java-attribute="ci" xml-path="CIPR/text()" /> <xml-element java-attribute="ch" xml-path="CHPR/text()" /> <xml-element java-attribute="cr" xml-path="CRPR/text()" /> <xml-element java-attribute="type" xml-path="Type/text()" /> </java-attributes> </java-type> </java-types> </xml-bindings> 

Observation

According to your question below, your domain class will look like:

 package forum8745305; import java.util.Date; public class Observation { private Date date; private Date theoricalTime; private String numeroTrain; private String ci; private String ch; private String cr; private String type; public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Date getTheoricalTime() { return theoricalTime; } public void setTheoricalTime(Date theoricalTime) { this.theoricalTime = theoricalTime; } public String getNumeroTrain() { return numeroTrain; } public void setNumeroTrain(String numeroTrain) { this.numeroTrain = numeroTrain; } public String getCi() { return ci; } public void setCi(String ci) { this.ci = ci; } public String getCh() { return ch; } public void setCh(String ch) { this.ch = ch; } public String getCr() { return cr; } public void setCr(String cr) { this.cr = cr; } public String getType() { return type; } public void setType(String type) { this.type = type; } } 

Demo

To run the example, you can use the following code:

 package forum8745305; import java.io.File; import java.util.HashMap; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import org.eclipse.persistence.jaxb.JAXBContextFactory; public class Demo { public static void main(String[] args) throws Exception { Map<String, Object> properties = new HashMap<String, Object>(1); properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum8745305/oxm.xml"); JAXBContext jc = JAXBContext.newInstance(new Class[] {Observation.class}, properties); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum8745305/input.xml"); Observation observation = (Observation) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(observation, System.out); } } 

Input Output

 <?xml version="1.0" encoding="UTF-8"?> <observation> <Date>05/01/2012 16:36:24</Date> <TheoricalTime>01/02/2012 12:34:45</TheoricalTime> </observation> 

Additional Information

UPDATE

You can also specify XmlAdapters at the property level. This means that you could have a different XmlAdapter for each of your Date properties, if you wish.

 <?xml version="1.0"?> <xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" version="2.1" package-name="forum8745305"> <java-types> <java-type name="Observation"> <xml-type prop-order="date theoricalTime ci ch cr type" /> <xml-root-element/> <java-attributes> <xml-element java-attribute="date" xml-path="Date/text()"> <xml-java-type-adapter value="forum8745305.DateAdapter"/> </xml-element> <xml-element java-attribute="theoricalTime" xml-path="TheoricalTime/text()"> <xml-java-type-adapter value="forum8745305.DateAdapter"/> </xml-element> <xml-element java-attribute="numeroTrain" xml-path="NumeroTrain/text()" /> <xml-element java-attribute="ci" xml-path="CIPR/text()" /> <xml-element java-attribute="ch" xml-path="CHPR/text()" /> <xml-element java-attribute="cr" xml-path="CRPR/text()" /> <xml-element java-attribute="type" xml-path="Type/text()" /> </java-attributes> </java-type> </java-types> </xml-bindings> 
+6
source

Source: https://habr.com/ru/post/1389500/


All Articles