【问题标题】:How to tell Apache CXF to use java.util.Date in Spring Configuration如何告诉 Apache CXF 在 Spring 配置中使用 java.util.Date
【发布时间】:2011-04-23 12:27:04
【问题描述】:

我正在使用 CXF 来托管 Web 服务在 Spring 上下文中,这使得 JAX-WS 成为默认绑定。而且我使用的是 Java-First,这意味着带注释的端点接口和类。

由于 JAX-WS 的默认绑定使用 XMLGregorianCalendar 类作为日期,当我调用我的 Web 服务并传递 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 配置文件)中执行此操作的方法。我的文件的 sn-p:

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

【问题讨论】:

  • 如果有人遇到同样的问题,我可以使用 JAXB 注释解决我的问题。看到这个问题:stackoverflow.com/questions/3953433/…
  • 您能否更具体一点,您要自定义什么工件?如果是 JAX-WS 工件 (SEI),则为接口提供 Java 代码。或者,如果那是 JAXB bean,请向我们展示生成的代码。

标签: java web-services jax-ws cxf


【解决方案1】:

您的问题的解决方案隐藏在类生成中。

您应该使用以下绑定生成您的类:

<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;

【讨论】:

  • 此解决方案可能有效,但可能值得注意的是 SimpleDateFormat 不是线程安全的...stackoverflow.com/questions/6840803
  • @Forge_7 有什么贸易安全的解决方案吗?
  • @kozla13 只需在使用 SimpleDateFormat 时将其实例化为局部变量,而不是将其存储为静态(或实例)变量。
猜你喜欢
  • 2015-12-13
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
相关资源
最近更新 更多