How to use of XmlGregorianCalendar with fromJson and toJson methods of gson?

13,233

Solution 1

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.

You could use MOXy to handle both the XML and JSON binding aspects of this use case. As I mentioned in my comment MOXy supports the XMLGregorianCalendar type. The Metadata would look like:

EmpRequest

package forum7725188;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="EmpRequest")
@XmlAccessorType(XmlAccessType.FIELD)
public class EmpRequest {

    @XmlElement(name="EmplIn")
    private EmplIn emplIn;

}

EmplIn

package forum7725188;

import javax.xml.bind.annotation.*;
import javax.xml.datatype.XMLGregorianCalendar;

@XmlAccessorType(XmlAccessType.FIELD)
public class EmplIn {

    @XmlElement(name="EmpID")
    private long empId;

    @XmlElement(name="Empname")
    private String name;

    @XmlElement(name="Designation")
    private String designation;

    @XmlElement(name="DOJ")
    private XMLGregorianCalendar doj;

}

package-info

@XmlSchema(namespace="http://java.com/Employee", elementFormDefault=XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
package forum7725188;

import javax.xml.bind.annotation.*;

Demo

You can configure the MOXy implementation of Marshaller to output JSON by setting the eclipselink.media-type property to be application/json.

package forum7725188;

import java.io.File;   
import javax.xml.bind.*;
import javax.xml.namespace.QName;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(EmpRequest.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum7725188/input.xml");
        EmpRequest empRequest = (EmpRequest) unmarshaller.unmarshal(xml);

        JAXBElement<EmpRequest> jaxbElement = new JAXBElement<EmpRequest>(new QName(""), EmpRequest.class, empRequest);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty("eclipselink.media-type", "application/json");
        marshaller.marshal(jaxbElement, System.out);
    }

}

input.xml

<?xml version="1.0" encoding="UTF-8"?>
<EmpRequest xmlns="http://java.com/Employee">
    <EmplIn>
        <EmpID>12</EmpID>
        <Empname>sara</Empname>
        <Designation>SA</Designation>
        <DOJ>2002-05-30T09:30:10+06:00</DOJ>
    </EmplIn>
</EmpRequest>

Output

{"EmplIn" : 
   {"EmpID" : "12",
   "Empname" : "sara",
   "Designation" : "SA",
   "DOJ" : "2002-05-30T09:30:10+06:00"}}

For More Information

Solution 2

Hopefully, This can fix my issue of using google-gson.

(The following should be added in where we create the object of Gson)

Step 1:

    Gson gson =
        new GsonBuilder().registerTypeAdapter(XMLGregorianCalendar.class,
                                              new XGCalConverter.Serializer()).registerTypeAdapter(XMLGregorianCalendar.class,
                                                                                                   new XGCalConverter.Deserializer()).create();

Step 2: And we need to create the XGCalConverter Class as like the following.

 import com.google.gson.JsonDeserializationContext;
 import com.google.gson.JsonDeserializer;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonPrimitive;
 import com.google.gson.JsonSerializationContext;
 import com.google.gson.JsonSerializer;

 import java.lang.reflect.Type;

 import javax.xml.datatype.DatatypeFactory;
 import javax.xml.datatype.XMLGregorianCalendar;

  public class XGCalConverter
  {
   public static class Serializer implements JsonSerializer
   {
    public Serializer()
    {
     super();
    }

    public JsonElement serialize(Object t, Type type,
                             JsonSerializationContext jsonSerializationContext)
    {
     XMLGregorianCalendar xgcal=(XMLGregorianCalendar)t;
     return new JsonPrimitive(xgcal.toXMLFormat());
    }
  }
    public static class Deserializer implements JsonDeserializer
    {

      public Object deserialize(JsonElement jsonElement, Type type,
                               JsonDeserializationContext jsonDeserializationContext)
      {
          try
           {
              return DatatypeFactory.newInstance().newXMLGregorianCalendar(jsonElement.getAsString());
           }
           catch(Exception ex)
           {
               ex.printStackTrace();
               return null;
           }
         }
       }
     }
Share:
13,233
Harish Raj
Author by

Harish Raj

Updated on June 04, 2022

Comments

  • Harish Raj
    Harish Raj almost 2 years

    The theme of my project is to give XML format of data and get Json format using google-gson and I have JAXB generated java POJOs from XML schema in which I have a variable of XMLGregorianCalendar datatype.

    I give the following input of XML and get the json format from the gson.toJson() method;

    <?xml version="1.0" encoding="UTF-8"?>
    <EmpRequest xmlns="http://java.com/Employee">
    <EmplIn>
    <EmpID>12</EmpID>
    <Empname>sara</Empname>
    <Designation>SA</Designation>
    <DOJ>2002-05-30T09:30:10+06:00</DOJ>
    </EmplIn>
    </EmpRequest>
    

    But in the output, I got the following.

    {"emplIn":{"empID":"12","empname":"sara","designation":"SA","doj":{}}}
    

    I surfed google and got the suggestion of adding in the xml schema and changing the XmlGregorianCalendar datatype with string. But I dont want to achieve it from both the ways.

    I mean how to get the proper output with the XmlGregorianCalendar datatype through fromJson and toJson methods of gson?

    Thank you so much, Harish Raj.

  • Harish Raj
    Harish Raj over 12 years
    Thank you so much, Blaise. But sounds I need GAXB generated Java Pojos to be used for getting other resources of my application. Is theer any possiblity to use it with the GAXB generated Pojos?
  • bdoughan
    bdoughan over 12 years
    @harish.raj - By GAXB do you mean JAXB? If so then yes. There isn't a real difference between generated classes or classes you annotate yourself as far as a JAXB runtime is concerned.
  • Harish Raj
    Harish Raj over 12 years
    Blaise, I use Jdeveloper. and I get the following error. Exception in thread "main" javax.xml.bind.PropertyException: name: eclipselink.media-type value: application/json at org.eclipse.persistence.jaxb.JAXBMarshaller.setProperty(JAXB‌​Marshaller.java:520) at com.moxy.employee.Test.main(Test.java:18) Can you tell me how I can install/configure EclipseLink JAXB (MOXy) so that it would be working fine.
  • bdoughan
    bdoughan over 12 years
    @harish.raj - You need to use EclipseLink 2.4. You can obtain a milestone release from: eclipse.org/eclipselink/downloads/milestones.php
  • Oleksi
    Oleksi almost 12 years
    I am also getting this exception, but I'm using 2.4.0-SNAPSHOT. Any suggestions?
  • osoblanco
    osoblanco almost 8 years
    This method makes my serialized epoch times wrapped in quotes. Any ideas to get them as working numbers?