How to use of XmlGregorianCalendar with fromJson and toJson methods of gson?
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
- http://blog.bdoughan.com/2011/08/binding-to-json-xml-geocode-example.html
- http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html
- http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
- http://blog.bdoughan.com/2011/09/mapping-objects-to-multiple-xml-schemas.html
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;
}
}
}
}
Harish Raj
Updated on June 04, 2022Comments
-
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 over 12 yearsThank 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 over 12 years@harish.raj - By
GAXB
do you meanJAXB
? 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 over 12 yearsBlaise, 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(JAXBMarshaller.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 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 almost 12 yearsI am also getting this exception, but I'm using 2.4.0-SNAPSHOT. Any suggestions?
-
osoblanco almost 8 yearsThis method makes my serialized epoch times wrapped in quotes. Any ideas to get them as working numbers?