Как сказать Apache CXF использовать java.util.Date в Spring Configuration - PullRequest
6 голосов
/ 10 октября 2010

Я использую CXF для размещения веб-служб в контексте Spring , что делает JAX-WS привязкой по умолчанию. И я использую Java-First, что означает аннотированные интерфейсы и классы конечных точек.

Поскольку привязка по умолчанию для JAX-WS использует класс XMLGregorianCalendar для дат, когда я вызываю свой веб-сервис, передавая java.util.Date, он преобразуется в XMLGregorianCalendar на сервере.

Существует множество постов и документации о том, как изменить это значение для привязки даты к java.util.Date, но все они связаны с инструментом wsdl2java, например:

<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:dateTime"
                      parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDateTime"
                      printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDateTime"/>
      </jxb:globalBindings>
  </jaxws:bindings>
</jaxws:bindings>

Поскольку я использую Spring, я ищу способ сделать это в файлах конфигурации контекста Spring (или файлах конфигурации CXF). Фрагмент моего файла:

<jaxws:endpoint id="jaxwsDocumentGroupWsEndpoint" implementor="#documentGroupWsEndpoint" address="/documentGroup">
<!-- SOMETHING TO WRITE HERE TO TELL CXF TO USE java.util.Date ??? -->
</jaxws:endpoint>

1 Ответ

5 голосов
/ 20 декабря 2011

Решение вашей проблемы скрыто в генерации классов.

Вы должны сгенерировать ваши классы со следующей привязкой:

<jaxb:globalBindings generateMixedExtensions="true">
        <jaxb:javaType 
            name="java.util.Calendar" 
            xmlType="xs:dateTime"           
            parseMethod="com.test.DataTypeBinder.unmarshalDateTime" 
            printMethod="com.test.DataTypeBinder.marshalDateTime" />

</jaxb:globalBindings>

и включить в путь к классу следующий класс:

public class DataTypeBinder {
private static DateFormat dateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 
    private static DateFormat date = new SimpleDateFormat("yyyy-MM-dd"); 

    public static Calendar unmarshalDate(String value) {
        if (value == null || value.length() == 0) {
            return null;
        }
        Date d = null;

        try {
            d = date.parse(value);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } 
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c;
    }

    public static  String marshalDate(Calendar value) {
        if (value == null) {
            return null;
        }

        return date.format(value.getTime());
    }   


    public static Calendar unmarshalDateTime(String value) {
        if (value == null || value.length() == 0) {
            return null;
        }
        Date d = null;

        try {
            d = dateTime.parse(value);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } 
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c;
    }

}

Тогда JAXB собирается включить в ваши сгенерированные классы следующее объявление типа:

@XmlElement(type = String.class)
@XmlJavaTypeAdapter(Adapter1 .class)
@XmlSchemaType(name = "dateTime")
protected Calendar transactionDate;
...