Как представить даты без часового пояса с помощью Apache CXF?
У меня есть WSDL, который указывает тип элемента как xs: date.
Когда я использую Apache CXF для генерации классов Java, он отображает переменную как javax.xml.datatype.XMLGregorianCalendar(все до сих пор).
Когда CXF отображает XML-документ, содержащий это, он отображает его в этой форме (где -06: 00 представляет часовой пояс):
2000-01-18-06: 00
Как настроить CXF, чтобы не отображать часовой пояс?
Ответы
Ответ 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);
}
}