Как мне представить даты без часового пояса, используя Apache CXF? - PullRequest
16 голосов
/ 26 мая 2011

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

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

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

2000-01-18-06: 00

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

Ответы [ 4 ]

64 голосов
/ 18 августа 2011
GregorianCalendar gcal = new GregorianCalendar();
start = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal);
start.setTimezone(DatatypeConstants.FIELD_UNDEFINED);

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

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

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

5 голосов
/ 19 апреля 2016

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

Мне пришлось объявить новый 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 голосов
/ 26 мая 2011

По умолчанию 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>

."Как сопоставить xsd: dateTime с java.util.Date?"для более подробной информации.

0 голосов
/ 23 февраля 2017

Я нашел свой комментарий выше с 2012 года, и теперь я чувствую себя обязанным добавить ответ. Я делаю некоторые изменения в веб-сервисе, который, к сожалению, должен продолжать работать на Java 6. Меня попросили подавить часть часового пояса / смещения всех полей даты и времени в моих ответах XML. Я сделал это с помощью файла привязки JAXB и 3 пар методов адаптера для типов XML даты, времени и даты и времени. Обратите внимание, что мое решение использует библиотеку 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);
    }

}
...