【问题标题】:@XmlJavaTypeAdapter vs @XmlSchemaType with java.time.LocalDateTime@XmlJavaTypeAdapter 与 @XmlSchemaType 与 java.time.LocalDateTime
【发布时间】:2014-10-28 21:56:42
【问题描述】:

我正在 Netbeans (8) 中开发 EJB 模块和 JAVAFX 客户端中的 JAXWS(部署在 Glassfish 4.0 上)。我正在使用 IDE 从 Java 类方向构建我的 WS。我正在努力通过 WS 传递 java.time.LocalDateTime 并在客户端获取 LocalDateTime。

重要的是,我需要/希望一起开发服务器和客户端!如果我更改 WS,则 WSDL 会更改,它应该由 Netbeans(通过 JAXWS)立即传播到客户端源代码(类型安全)...,但它在某种程度上不适用于 java.time( .localdate)..

为什么 WS 在编组过程中没有将任何内容写入 LocalDateTime 字段。为什么? 这是我使用的好方法吗?我错过了什么吗?谢谢。

如果我在 WebService 中使用 @XmlJavaTypeAdapter 来处理 LocalDateTime 编组到字符串,XSD 生成会将 xs:string 放入我的 localDateTime 字段...所以 @XMLSchemaType 被 @XmlJavaTypeAdapter 覆盖。 我该如何解决这个问题?

服务器端,在WebService中,我使用的是package level

    @XmlSchemaTypes({
      @XmlSchemaType(name="date", type=LocalDate.class)
      ,@XmlSchemaType(name="dateTime", type=LocalDateTime.class)
      ,@XmlSchemaType(name="time", type=LocalTime.class)
    })

这使 IDE 生成正确的 XSD 元素,例如包含

    <xs:element name="validTo" type="xs:dateTime" minOccurs="0"/>

服务器上的XmlADapter:(如果我用@XmlJavaTypeAdapter (String, LocalDateTime) 注入它,那么XSD 生成会从LocalDateTime 创建String。)

    public class LocalDateTimeAdapter
        extends XmlAdapter<String, LocalDateTime>{
        @Override
        public LocalDateTime unmarshal(String v) throws Exception {
            return LocalDateTime.parse(v,DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        }
        @Override
        public String marshal(LocalDateTime v) throws Exception {
            return v.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        }
    }

在客户端,我附上了WS,让IDE生成类。 我向附加的 Web 服务和一个 Adapter 类添加了一个外部 绑定文件 来处理 LocalDateTime 字段:

绑定文件:

            <jxb:globalBindings>
                <jxb:javaType name="java.time.LocalDateTime" xmlType="xs:dateTime"
                      parseMethod="test.app.utils.JaxBDateConverter.parseDateTime"
                      printMethod="test.app.utils.JaxBDateConverter.printDateTime" />
                <jxb:javaType name="java.time.LocalDate" xmlType="xs:date"
                      parseMethod="test.app.utils.JaxBDateConverter.parseDate"
                      printMethod="test.app.utils.JaxBDateConverter.printDate" />
                <jxb:javaType name="java.time.LocalTime" xmlType="xs:time"
                      parseMethod="test.app.utils.JaxBDateConverter.parseTime"
                      printMethod="test.app.utils.JaxBDateConverter.printTime" />

            </jxb:globalBindings>

        </jxb:bindings> 
    </jxb:bindings>

客户端上的适配器类: 打包 test.app.client;

    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
    import java.time.format.DateTimeFormatter;

    public class JaxBDateConverter {

    static final DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
    static final DateTimeFormatter df = DateTimeFormatter.ISO_LOCAL_DATE;
    static final DateTimeFormatter tf = DateTimeFormatter.ISO_LOCAL_TIME;

    public static LocalDateTime parseDateTime(String s) {
        try {
            if (s.trim().isEmpty()) {
                return null;
            } else {
            }
            LocalDateTime r = LocalDateTime.parse(s, dtf);
            return r;
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    public static String printDateTime(LocalDateTime d) {
        try {
            if (d == null)
                return null;
            return d.format(dtf);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    public static LocalDate parseDate(String s) {
        try {
            if (s.trim().isEmpty()) {
                return null;
            } else {
            }
            LocalDate r = LocalDate.parse(s, df);
            return r;
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    public static String printDate(LocalDate d) {
        try {
            if (d == null)
                return null;
            return d.format(df);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }
    public static LocalTime parseTime(String s) {
        try {
            if (s.trim().isEmpty()) {
                return null;
            } else {
            }
            LocalTime r = LocalTime.parse(s, tf);
            return r;
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    public static String printTime(LocalTime d) {
        try {
            if (d == null)
                return null;
            return d.format(tf);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    }

【问题讨论】:

    标签: web-services netbeans jaxb glassfish jax-ws


    【解决方案1】:

    为什么 WS 不向 LocalDateTime 字段写入任何内容 在编组期间。为什么?这是我创建的好方法吗?我想念吗 某物?谢谢。

    自最新的 JAXB (JSR-222) 发布以来,已添加 java.time.LocalDateTime 类型,因此现在您需要 XmlAdapter 来处理转换。


    如果我在 WebService 中使用 @XmlJavaTypeAdapter 来处理 LocalDateTime 编组,XSD 生成将 xs:string 放入我的 localDateTime 字段...所以@XMLSchemaType 被@XmlJavaTypeAdapter 覆盖。如何 我可以解决这个问题吗?

    @XmlJavaTypeAdapter 不会覆盖 @XmlSchemaType。相反,引用的XmlAdapterLocalDateTime 转换为String。现在就 JAXB 而言,它现在是 String 属性,因此 @XmlSchemaType 不再适用。


    我该如何解决这个问题?

    您可以直接在适应的LocalDateTime 属性上使用@XmlSchemaType 注释。

    @XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
    @XmlSchemaType(name="dateTime")
    public LocalDateTime getMyLocalDateTime() {
        return myLocalDateTime;
    }
    

    【讨论】:

    • 改编的 LocalDateTime 是什么意思?我已经有了 XmlSchemaType。我究竟应该怎么做?是的,我在服务器端尝试了 XMLAdapter: XmlAdapter (我忘了把它放到帖子中)
    • @AttilaKuti - 可能最容易让这个问题集中在服务器端部分并删除客户端方面(或使其成为自己的问题)。
    • 是的,它有点复杂,但它是相关且重要的,我需要/愿意一起开发服务器和客户端!如果我更改 WS,它将立即传播到客户端(类型安全)...或者应该是,但它在某种程度上不适用于 java.time(.localdate)...
    • @AttilaKuti - 我已经更新了我的答案以解决您的第一条评论。
    • 我猜你的意思是LocalDateTime。我已经尝试在字段级别以及 getter 方法上添加注释......它与包级别的工作方式相同。 (我想这不是问题..)我可能必须“稳定”我的 WSDL,然后在服务器上应用 XmlAdapters ......在这种情况下,GF 服务器不会更新 WS 的 WSDL ......如果我更改 WS,那么我必须禁用 XmlAdapters 并手动必须让服务器刷新 WSDL ......等等(我猜......仍然没有测试)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 2019-10-22
    • 2014-07-26
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多