Buscar este blog

domingo, 8 de julio de 2018

JAXB - XMLGregorianCalendar - Blank date value

When you work with web services or other schema-based objects, date fields are interpreted as XMLGregorianCalendar.

For example if you have this schema:
<xs:simpleType name="timeStamp">
 <xs:annotation>
  <xs:documentation>timeStamp</xs:documentation>
 </xs:annotation>
 <xs:restriction base="dateTime" />
</xs:simpleType>

You will end with this POJO:
   @XmlSchemaType(name = "dateTime")
   protected XMLGregorianCalendar timeStamp;

The problem here is that when you want to transform this POJO in XML (marshalling), the timestamp value will always be empty.

I found this problem working with Camel and CXF. Clients connect to the Camel route throught a SOAP web service by using only simple data types (a string wich contains an XML), while inside the route this XML is transformed into a java object and sent to a second web service. The response run throught the inverse process.

Something like this:
   final JaxbDataFormat jaxb = new JaxbDataFormat("xxx.xxxx.xxxx.xxx");
   jaxb.setEncoding("UTF-8");      

   from("cxf:bean:simpleServiceProvider") 
   .unmarshal(jaxb) 
   .to("cxf:bean:complexServiceClient")
   .setBody().simple("${body[0]}")
   .marshal(jaxb)
   .convertBodyTo(String.class, "UTF-8");

In this case the solution is to use java.util.Date instead XMLGregorianCalendar, so marshal step works fine.
As I posted before in Eclipse - Maven - Configure wsdl2java and wsdl2java - Use java.util.Date instead of XMLGregorianCalendar, you build your POJOs directly from the WSDL file. Besides, you can force wsdl2java to use Date instead XMLGregorianCalendar, so you should not have any problems.

Actually, in my new task, the WSDL file was a bit more complex, and schema files were external. In this case you have to configure the binding at schema-level instead WSDL-level:
<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0" 
 schemaLocation="dct.xsd"
 xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
 jaxb:extensionBindingPrefixes="xjc">
 
 <jaxb:globalBindings>
  <jaxb:serializable uid="1" />
  
   <jaxb:javaType name="java.util.Date" xmlType="xsd:dateTime"
    parseMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime"
    printMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.printDateTime" />
        
 </jaxb:globalBindings>
</jaxb:bindings>

The schema file it is called dtc.xsd, with is referenced from schemalocation attribute.

No hay comentarios:

Publicar un comentario