Simple conversion between java.util.Date and XMLGregorianCalendar

后端 未结 7 1169
夕颜
夕颜 2020-12-02 04:25

I\'m looking for a simple method of converting between java.util.Date and javax.xml.datatype.XMLGregorianCalendar in both directions.

Here is the code that

相关标签:
7条回答
  • 2020-12-02 05:03

    Customizing the Calendar and Date while Marshaling

    Step 1 : Prepare jaxb binding xml for custom properties, In this case i prepared for date and calendar

    <jaxb:bindings version="2.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jaxb:globalBindings generateElementProperty="false">
    <jaxb:serializable uid="1" />
    <jaxb:javaType name="java.util.Date" xmlType="xs:date"
        parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDate"
        printMethod="com.stech.jaxb.util.CalendarTypeConverter.printDate" />
    <jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime"
        parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime"
        printMethod="com.stech.jaxb.util.CalendarTypeConverter.printCalendar" />
    


    Setp 2 : Add custom jaxb binding file to Apache or any related plugins at xsd option like mentioned below

    <xsdOption>
      <xsd>${project.basedir}/src/main/resources/tutorial/xsd/yourxsdfile.xsd</xsd>
      <packagename>com.tutorial.xml.packagename</packagename>
      <bindingFile>${project.basedir}/src/main/resources/xsd/jaxbbindings.xml</bindingFile>
    </xsdOption>
    

    Setp 3 : write the code for CalendarConverter class

    package com.stech.jaxb.util;
    
    import java.text.SimpleDateFormat;
    
    /**
     * To convert the calendar to JaxB customer format.
     * 
     */
    
    public final class CalendarTypeConverter {
    
        /**
         * Calendar to custom format print to XML.
         * 
         * @param val
         * @return
         */
        public static String printCalendar(java.util.Calendar val) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
            return simpleDateFormat.format(val.getTime());
        }
    
        /**
         * Date to custom format print to XML.
         * 
         * @param val
         * @return
         */
        public static String printDate(java.util.Date val) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            return simpleDateFormat.format(val);
        }
    }
    

    Setp 4 : Output

      <xmlHeader>
       <creationTime>2014-09-25T07:23:05</creationTime> Calendar class formatted
    
       <fileDate>2014-09-25</fileDate> - Date class formatted
    </xmlHeader>
    
    0 讨论(0)
  • 2020-12-02 05:07

    Why not use an external binding file to tell XJC to generate java.util.Date fields instead of XMLGregorianCalendar?

    Also see How do I map xs:date to java.util.Date? Blog

    0 讨论(0)
  • 2020-12-02 05:15

    From java.util.Date to XMLGregorianCalendar you can simply do:

    import javax.xml.datatype.XMLGregorianCalendar;
    import javax.xml.datatype.DatatypeFactory;
    import java.util.GregorianCalendar;
    ......
    GregorianCalendar gcalendar = new GregorianCalendar();
    gcalendar.setTime(yourDate);
    XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcalendar);
    

    Code edited after the first comment of @f-puras, by cause i do a mistake.

    0 讨论(0)
  • 2020-12-02 05:15

    You can use the this customization to change the default mapping to java.util.Date

    <xsd:annotation>
    <xsd:appinfo>
        <jaxb:globalBindings>
            <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>
    </xsd:appinfo>
    

    0 讨论(0)
  • 2020-12-02 05:20

    I too had this kind of headache. Got rid of of it by simply representing time fields as primitive long in my POJO. Now the generation of my WS client code handle everything correctly and no more XML-to-Java crap. And of course dealing with millis on the Java side is simple and painless. KISS principle rocks!

    0 讨论(0)
  • 2020-12-02 05:25

    I had to make some changes to make it work, as some things seem to have changed in the meantime:

    • xjc would complain that my adapter does not extend XmlAdapter
    • some bizarre and unneeded imports were drawn in (org.w3._2001.xmlschema)
    • the parsing methods must not be static when extending the XmlAdapter, obviously

    Here's a working example, hope this helps (I'm using JodaTime but in this case SimpleDate would be sufficient):

    import java.util.Date;
    import javax.xml.bind.DatatypeConverter;
    import javax.xml.bind.annotation.adapters.XmlAdapter;
    import org.joda.time.DateTime;
    
    public class DateAdapter extends XmlAdapter<Object, Object> {
        @Override
        public Object marshal(Object dt) throws Exception {
            return new DateTime((Date) dt).toString("YYYY-MM-dd");
        }
    
        @Override
            public Object unmarshal(Object s) throws Exception {
            return DatatypeConverter.parseDate((String) s).getTime();
        }
    }
    

    In the xsd, I have followed the excellent references given above, so I have included this xml annotation:

    <xsd:appinfo>
        <jaxb:schemaBindings>
            <jaxb:package name="at.mycomp.xml" />
        </jaxb:schemaBindings>
        <jaxb:globalBindings>
            <jaxb:javaType name="java.util.Date" xmlType="xsd:date"
                  parseMethod="at.mycomp.xml.DateAdapter.unmarshal"
              printMethod="at.mycomp.xml.DateAdapter.marshal" />
        </jaxb:globalBindings>
    </xsd:appinfo>
    
    0 讨论(0)
提交回复
热议问题