【问题标题】:jaxb marshalling LocalDate with custom date formatjaxb 使用自定义日期格式编组 LocalDate
【发布时间】:2019-07-05 14:04:05
【问题描述】:

我在这里关注了一个主题,但它没有回答我的问题。 我希望肥皂响应将本地日期格式化为肥皂请求中的相同本地日期。

例如:我的本地日期请求:10/10/1990 响应必须是 10/10/1990 但我总是得到 1990-10-10 因为 toString 以这种方式格式化它......

我的代码:

public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {

public DateTimeFormatter dateFormat() {
    //DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[MM/dd/yyyy][MM-dd-yyyy][yyyy/MM/dd][yyyy-MM-dd]");    

    DateTimeFormatter mmddyyyySlash = DateTimeFormatter.ofPattern("MM/dd/yyyy");
    DateTimeFormatter mmddyyyy = DateTimeFormatter.ofPattern("MM-dd-yyyy"); 
    DateTimeFormatter yyyymmdd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    DateTimeFormatter yyyymmddSlash = DateTimeFormatter.ofPattern("yyyy/MM/dd");    

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendOptional(mmddyyyySlash)
            .appendOptional(mmddyyyy)
            .appendOptional(yyyymmdd)
            .appendOptional(yyyymmddSlash)
            .toFormatter();

    return formatter;
}

public LocalDate unmarshal(String v) throws Exception {
    DateTimeFormatter formatter = dateFormat();
    return LocalDate.parse(v, formatter);
}

public String marshal(LocalDate v) throws Exception {
    return v.toString();
}
}

我该如何解决? 我试图:

public String marshal(LocalDate v) throws Exception {
    DateTimeFormatter formatter = dateFormat();
    String ld = v.format(formatter);

    return ld;
}

但是结果: 05/05/199005-05-19901990-05-051990/05/05 :(

【问题讨论】:

    标签: java jaxb localdate


    【解决方案1】:

    尝试使用您的dateFormat() 方法。你可以运行它来看看它是如何工作的。我把它简化了一点。

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.time.format.DateTimeFormatterBuilder;
    
    public class LocalDateAdapter {
    
        public DateTimeFormatter dateFormat() {
            DateTimeFormatter mmddyyyySlash = DateTimeFormatter.ofPattern("MM/dd/yyyy");
            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                 .appendOptional(mmddyyyySlash).toFormatter();
            return formatter;
        }
    
        public LocalDate unmarshal(String v) throws Exception {
            DateTimeFormatter formatter = dateFormat();
            return LocalDate.parse(v, formatter);
        }
    
        public String marshal(LocalDate v) {
            return v.format(dateFormat());
        }
    
        public static void main(String[] args) {
            LocalDate date = LocalDate.now();
    
            LocalDateAdapter adapter = new LocalDateAdapter();
            String dateAsString = adapter.marshal(date);
            System.out.println("Date as String: " + dateAsString);
    
            LocalDate dateAsDate = adapter.unmarshal(dateAsString);
            System.out.println("Date back as LocalDate: " + adapter.marshal(dateAsDate));
    
        }
    }
    

    编辑

    已更新以显示如何使用 marshall()unmarshall() 来指示日期信息的正确保存。

    现在打印出来了:

    Date as String: 07/05/2019
    Date back as LocalDate: 07/05/2019
    

    更新

    下面是一个示例,说明如何使用 @XmlJavaTypeAdapter 来区分何时使用一种适配器类型与另一种适配器类型来处理不同的日期格式。

    在不了解更广泛的系统上下文的情况下,这是一种强制使用哪种格式化程序的方法。

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    
    import javax.xml.bind.annotation.adapters.XmlAdapter;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    
    class DateWithSlashAdapter extends XmlAdapter<String, LocalDate> {
    
        public DateTimeFormatter dateFormat() {
            return DateTimeFormatter.ofPattern("MM/dd/yyyy");
        }
    
        @Override
        public LocalDate unmarshal(String v) {
            DateTimeFormatter formatter = dateFormat();
            return LocalDate.parse(v, formatter);
        }
    
        @Override
        public String marshal(LocalDate v) {
            return v.format(dateFormat());
        }
    }
    
    class DateWithHyphenAdapter extends XmlAdapter<String, LocalDate> {
    
        public DateTimeFormatter dateFormat() {
            return DateTimeFormatter.ofPattern("MM-dd-yyyy");
        }
    
        @Override
        public LocalDate unmarshal(String v) {
            DateTimeFormatter formatter = dateFormat();
            return LocalDate.parse(v, formatter);
        }
    
        @Override
        public String marshal(LocalDate v) {
            return v.format(dateFormat());
        }
    }
    
    /** Example of a class representing your SOAP payload */
    class SoapRequestExample {
        @XmlJavaTypeAdapter(DateWithSlashAdapter.class)
        LocalDate someDateWithSlashes;
    
        @XmlJavaTypeAdapter(DateWithHyphenAdapter.class)
        LocalDate someDateWithHyphens;
    }
    

    【讨论】:

    • 仅适用于一种格式...如果我添加另一种格式,例如: DateTimeFormatter mmddyyyy = DateTimeFormatter.ofPattern("MM-dd-yyyy");并将其附加到“格式化程序”我会得到:05/05/199005-05-1990 :(
    • @TiagoMachado 在原始帖子中,marshal() 始终是 ISO-8601 格式的结果,因为它只是在日期返回 toString()。您需要使用与所需格式相对应的格式化程序以使其以不同的方式打印。但是,您的评论表明您有更高级别的要求来跟踪原始日期格式以用于决定要格式化的输出。这涉及更多一点,并且取决于您处理这些消息的周围环境。但我会想出一个简单的例子来说明我的意思。
    • 这是一个很好的答案,但有一个问题,我有 1 个字段:私人 LocalDate 生日;所以,当我提出请求时,我可以输入我想要的任何日期格式。当我使用该服务从具有生日的人那里获取数据时,它应该以我所做的请求的格式给我。它应该只使用 1 个字段... :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多