Подтвердить что ты не робот

Как представить даты без часового пояса с помощью Apache CXF?

У меня есть WSDL, который указывает тип элемента как xs: date.

Когда я использую Apache CXF для генерации классов Java, он отображает переменную как javax.xml.datatype.XMLGregorianCalendar(все до сих пор).

Когда CXF отображает XML-документ, содержащий это, он отображает его в этой форме (где -06: 00 представляет часовой пояс):

2000-01-18-06: 00

Как настроить CXF, чтобы не отображать часовой пояс?

4b9b3361

Ответ 1

По умолчанию wsdl xsd:date отображается на XMLGregorianCalendar. Если это не то, что вы хотите, то, если вы используете инструмент CXF wsdl to java, вы можете предоставить файл привязки, чтобы переопределить это сопоставление по умолчанию:

<jaxws:bindings wsdlLocation="YOUR_WSDL_LOCATION"
          xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
          xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <jaxws:bindings  node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='THE_NAMESPACE_OF_YOUR_SCHEMA']">
      <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <jxb:javaType name="java.util.Date" xmlType="xs:date"
                      parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDate"
                      printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDate"/>
      </jxb:globalBindings>
  </jaxws:bindings>
</jaxws:bindings>

Вы можете обратиться к разделу http://cxf.apache.org/docs/wsdl-to-java.html "Как сопоставить xsd: dateTime с java.util.Date?" для более подробной информации.

Ответ 2

GregorianCalendar gcal = new GregorianCalendar();
start = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal);
start.setTimezone(DatatypeConstants.FIELD_UNDEFINED);

Не спрашивайте меня, почему в каждом бите разумной логики - при сортировке XMLgregorianCalendar до xs: date он сохраняет часовой пояс.

Я всегда думал: часовой пояс может быть более применим к xs: dateTime, но то, что я знаю... о типах.

Для меня нет смысла иметь часовой пояс по умолчанию для типа xs: date, и это проблема в логике маршаллинга.

Ответ 3

Чтобы ответить Филиппу (спасибо ему!), возможно, это поможет некоторым из вас...

Мне пришлось объявить новый XmlAdapter в поле даты концерна с аннотацией @XmlJavaTypeAdapter

public class YourDTO {
   // ... 
   @XmlElement
   @XmlSchemaType(name = "dateTime")
   @XmlJavaTypeAdapter(type = XMLGregorianCalendar.class, value = XmlDateAdapter.class)
   public Date yourDate;
   // ...
}

Адаптер

public class XmlDateAdapter extends XmlAdapter<XMLGregorianCalendar, Date> {

@Override
public XMLGregorianCalendar marshal(Date date) throws Exception {
    GregorianCalendar gcal = new GregorianCalendar();
    gcal.setTime(date);
    XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal);
    xmlDate.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
    return xmlDate;
}
// ...

Формат даты сообщения SOAP перед

2017-04-18T00: 00: 00 + 02: 00

Формат даты SOAP после

2017-04-18T00: 00: 00

Ответ 4

Я нашел свой комментарий выше с 2012 года, и теперь я вынужден добавить ответ. Я вношу некоторые изменения в веб-службу, которая, к сожалению, должна продолжаться на Java 6. Мне было предложено отключить часть времени/смещения всех полей даты и времени в моих ответах XML. Я сделал это с помощью файла привязки JAXB и трех пар адаптивных методов для типов данных даты, времени и даты и времени. Обратите внимание: мое решение использует библиотеку JodaTime.

Вот мой файл привязки JAXB 2.1:

<?xml version="1.0" encoding="UTF-8"?>
<bindings 
        xmlns="http://java.sun.com/xml/ns/jaxb" 
        version="2.1"
        xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <globalBindings>
        <javaType 
            name="org.joda.time.DateTime"
            xmlType="xs:dateTime"
            parseMethod="com.jimtough.jaxb.DataTypeCondapter.parseDateTime"
            printMethod="com.jimtough.jaxb.DataTypeCondapter.printDateTime" />
        <javaType 
            name="org.joda.time.DateTime"
            xmlType="xs:date"
            parseMethod="com.jimtough.jaxb.DataTypeCondapter.parseDate"
            printMethod="com.jimtough.jaxb.DataTypeCondapter.printDate" />
        <javaType 
            name="org.joda.time.LocalTime"
            xmlType="xs:time"
            parseMethod="com.jimtough.jaxb.DataTypeCondapter.parseTime"
            printMethod="com.jimtough.jaxb.DataTypeCondapter.printTime" />
    </globalBindings>
</bindings>

Вот мой класс совместимости с Java 6 с адаптерами:

package com.jimtough.jaxb;

import java.util.Date;

import javax.xml.bind.DatatypeConverter;

import org.joda.time.DateTime;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

/**
 * My bizarrely named 'condapter' is a blend of the Java {@code DatatypeConverter}
 * and the Apache CXF {@code DataTypeAdapter} that provides Jodatime {@code DateTime}
 * support instead of {@code java.util.Date}.
 * 
 * @author jtough
 */
public class DataTypeCondapter {

    private DataTypeCondapter() {}

    // Jim Tough - 2017-02-22
    // JodaTime formatters claim to be threadsafe
    private static final DateTimeFormatter DTF_DATE = ISODateTimeFormat.date();
    private static final DateTimeFormatter DTF_DATETIME = ISODateTimeFormat.dateHourMinuteSecondMillis();
    private static final DateTimeFormatter DTF_TIME = ISODateTimeFormat.hourMinuteSecondMillis();

    public static DateTime parseDate(String s) {
        if (s == null) {
            return null;
        }
        Date date = DatatypeConverter.parseDate(s).getTime();
        return new DateTime(date);
    }

    public static String printDate(DateTime dt) {
        if (dt == null) {
            return null;
        }
        return DTF_DATE.print(dt);
    }

    public static LocalTime parseTime(String s) {
        if (s == null) {
            return null;
        }
        Date date = DatatypeConverter.parseTime(s).getTime();
        DateTime dt = new DateTime(date);
        return dt.toLocalTime();
    }

    public static String printTime(LocalTime lt) {
        if (lt == null) {
            return null;
        }
        return DTF_TIME.print(lt);
    }

    public static DateTime parseDateTime(String s) {
        if (s == null) {
            return null;
        }
        Date date = DatatypeConverter.parseDateTime(s).getTime();
        return new DateTime(date);
    }

    public static String printDateTime(DateTime dt) {
        if (dt == null) {
            return null;
        }
        return DTF_DATETIME.print(dt);
    }

}