【问题标题】:How to use of XmlGregorianCalendar with fromJson and toJson methods of gson?如何将 XmlGregorianCalendar 与 gson 的 fromJson 和 toJson 方法一起使用?
【发布时间】:2011-10-11 11:18:22
【问题描述】:

我的项目的主题是提供 XML 格式的数据并使用 google-gson 获取 Json 格式,并且我有 JAXB 从 XML 模式生成的 java POJO,其中我有一个 XMLGregorianCalendar 数据类型的变量。

我给出以下XML的输入,并从gson.toJson()方法中得到json格式;

<?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>

但在输出中,我得到了以下内容。

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

我在 google 上冲浪,得到了添加 xml 架构并使用字符串更改 XmlGregorianCalendar 数据类型的建议。但我不想从这两种方式来实现它。

我的意思是如何通过 gson 的 fromJson 和 toJson 方法使用 XmlGregorianCalendar 数据类型获得正确的输出?

非常感谢, 哈里什·拉吉。

【问题讨论】:

  • 您可以使用 EclipseLink JAXB (MOXy) 将您的对象转换为 XML 和 JSON。如果您对这种方法感兴趣,请告诉我:blog.bdoughan.com/2011/08/…
  • 是的,Blaise,如果它适用于具有 XmlGregorianCalendar 数据类型的 ,我很乐意。
  • Blaise,你能用一个例子进一步解释一下,以便我实现它吗?我对您提供的如何实现它感到困惑。 :(
  • 我添加了一个答案,演示如何使用 MOXy 来实现您的用例。

标签: jaxb gson


【解决方案1】:

希望这可以解决我使用google-gson 的问题。

(在我们创建Gson对象的地方应该添加以下内容)

第一步:

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

第 2 步:我们需要创建 XGCalConverter 类,如下所示。

 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;
           }
         }
       }
     }

【讨论】:

  • 此方法使我的序列化纪元时间用引号括起来。有什么想法可以让它们成为工作数字吗?
【解决方案2】:

注意:我是EclipseLink JAXB (MOXy) 的负责人,也是JAXB 2 (JSR-222) 专家组的成员。

您可以使用 MOXy 来处理此用例的 XML 和 JSON 绑定方面。正如我在评论中提到的那样,MOXy 支持 XMLGregorianCalendar 类型。元数据看起来像:

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;

}

包裹信息

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

import javax.xml.bind.annotation.*;

演示

您可以通过将eclipselink.media-type 属性设置为application/json 来配置Marshaller 的MOXy 实现以输出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>

输出

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

更多信息

【讨论】:

  • 非常感谢,布莱斯。但听起来我需要 GAXB 生成的 Java Pojos 来获取我的应用程序的其他资源。是否有可能将它与 GAXB 生成的 Pojos 一起使用?
  • @harish.raj - GAXB 是指JAXB 吗?如果是这样,那么是的。就 JAXB 运行时而言,生成的类或您自己注释的类之间没有真正的区别。
  • 布莱斯,我使用 Jdeveloper。我收到以下错误。线程“主”javax.xml.bind.PropertyException 中的异常:名称:eclipselink.media-type 值:com.moxy 的 org.eclipse.persistence.jaxb.JAXBMarshaller.setProperty(JAXBMarshaller.java:520) 的 application/json。 employee.Test.main(Test.java:18) 你能告诉我如何安装/配置 EclipseLink JAXB (MOXy) 以便它可以正常工作。
  • @harish.raj - 您需要使用 EclipseLink 2.4。您可以从以下位置获取里程碑版本:eclipse.org/eclipselink/downloads/milestones.php
  • 我也遇到了这个异常,但我使用的是 2.4.0-SNAPSHOT。有什么建议吗?
猜你喜欢
  • 1970-01-01
  • 2023-02-08
  • 1970-01-01
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-25
相关资源
最近更新 更多