【问题标题】:Marshalling LocalDate using JAXB使用 JAXB 编组 LocalDate
【发布时间】:2021-05-28 02:54:22
【问题描述】:

我正在构建一系列链接的类,我希望能够将其实例编组为 XML,以便我可以将它们保存到文件中并稍后再次读取它们。

目前我正在使用以下代码作为测试用例:

import javax.xml.bind.annotation.*;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import java.time.LocalDate;

public class LocalDateExample
{
  @XmlRootElement
  private static class WrapperTest {
    public LocalDate startDate;
  }

  public static void main(String[] args) throws JAXBException
  {
    WrapperTest wt = new WrapperTest();
    LocalDate ld = LocalDate.of(2016, 3, 1);
    wt.startDate = ld;
    marshall(wt);
  }

  public static void marshall(Object jaxbObject) throws JAXBException
  {
    JAXBContext context = JAXBContext.newInstance(jaxbObject.getClass());
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    marshaller.marshal(jaxbObject, System.out);
  }
}

XML 输出为:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wrapperTest>
    <startDate/>
</wrapperTest>

startDate 元素为空是否有原因?我希望它包含日期的字符串表示形式(即toString())。为了做到这一点,我需要自己编写一些代码吗?

java -version 的输出为:

openjdk version "1.8.0_66-internal"
OpenJDK Runtime Environment (build 1.8.0_66-internal-b17)
OpenJDK 64-Bit Server VM (build 25.66-b17, mixed mode)

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    您必须像这样创建XmlAdapter

    public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {
        public LocalDate unmarshal(String v) throws Exception {
            return LocalDate.parse(v);
        }
    
        public String marshal(LocalDate v) throws Exception {
            return v.toString();
        }
    }
    

    并使用

    注释您的字段
     @XmlJavaTypeAdapter(value = LocalDateAdapter.class)
    

    如果您想在包级别定义适配器,另请参阅javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters

    【讨论】:

    【解决方案2】:

    http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html 描述了孔设置。

    Joda-Time 提供了 Java SE 当前提供的 Date 和 Calendar 类的替代方案。由于它们是在单独的库中提供的,因此 JAXB 不为这些类提供默认映射。

    为包中的所有文件注册适配器。您可以在要注册的包中添加 package-info.java。

    @XmlJavaTypeAdapters({
        @XmlJavaTypeAdapter(type=LocalDate.class, 
            value=LocalDateAdapter.class),
    })
    package PACKAGE_NAME;
    
    import java.time.LocalDate;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
    

    适配器看起来像:

    import javax.xml.bind.annotation.adapters.XmlAdapter;
    import java.time.LocalDate;
    
    public class LocalDateAdapter extends XmlAdapter<String, LocalDate>{
    
        public LocalDate unmarshal(String v) throws Exception {
            return LocalDate.parse(v);
        }
    
        public String marshal(LocalDate v) throws Exception {
            return v.toString();
        }
    
    }
    

    【讨论】:

    • 我没有使用 Joda Time,我使用的是 java.time.* 类(看起来很相似,但它们是 Java 8 的一部分,因此不需要指定为依赖项) .
    • 你是对的。我只是在使用我的旧解决方案来测试您的解决方案。我会更新我的答案
    【解决方案3】:

    作为 Nikolay Antipov mentioned in this commment,已经有一个经过充分测试的 threetenprovides 14 type adapters(截至 2021 年 4 月 26 日)其中之一是:

    LocalDateXmlAdapter

    并且可以用于例如像这样在一些 Java 领域(虽然我通常不推荐):

    @XmlJavaTypeAdapter(value = LocalDateXmlAdapter.class) myLocalDt;
    

    相反,我会推荐 package-info.java 方法在包级别的每个包中隐式执行此操作,以便自动应用于例如所有包类中LocalDate类型的所有字段:

    • 创建一个名为src/java/my/xmlconv/classes/package-info.java的文件

    • 它的内容:

      @XmlJavaTypeAdapters({
        @XmlJavaTypeAdapter(value=LocalDateTimeXmlAdapter.class, type=LocalDateTime.class)
      })
      package my.xmlconv.classes;
      
      import java.time.LocalDateTime;
      import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
      import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
      import io.github.threetenjaxb.core.LocalDateTimeXmlAdapter;
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      • 1970-01-01
      • 1970-01-01
      • 2014-02-03
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多