2011-02-24 54 views
12

如何編寫JAX-WS服務,以使我的@WebMethod的@WebParam是類似DateTime的Joda-Time類?請問@XmlTypeAdapter參數是否工作?我正在部署到GlassFish 2.1。JAX-WS和Joda-Time?

讓我澄清一下這個問題,因爲到目前爲止答案都集中在將自定義類型綁定到現有的JAXB類上,而這些JAXB類是相關的,但並非我提出的問題。如何使以下@WebService接受joda DateTime對象作爲參數?

import javax.jws.WebMethod; 
import javax.jws.WebParam; 
import javax.jws.WebService; 
import javax.jws.soap.SOAPBinding; 
import org.joda.time.DateTime; 

@WebService 
@SOAPBinding(style = SOAPBinding.Style.RPC) 
public interface Resender { 
    @WebMethod 
    void resend(
      @WebParam(name = "start") DateTime start, 
      @WebParam(name = "end") DateTime end 
    ); 

} 

回答

2

你必須標註該參數直接,如下面(我利用XSDDateTimeMarshaller由@DennisTemper寫成的一個回答你的問題,但隨意替換另一個...):

@WebService 
@SOAPBinding(style = SOAPBinding.Style.RPC) 
public interface Resender { 
    @WebMethod 
    void resend(
     @WebParam(name = "start") @XmlJavaTypeAdapter(type = DateTime.class, value = XSDDateTimeMarshaller.class) DateTime start, 
     @WebParam(name = "end") @XmlJavaTypeAdapter(type = DateTime.class, value = XSDDateTimeMarshaller.class) DateTime end 
    ); 
} 
9

首先編寫簡單的轉換器(在這個例子中Calendar,但可以很容易地改變喬達時間):

public class XsdDateTimeConverter { 

    public static Calendar unmarshal(String dateTime) { 
     final GregorianCalendar calendar = new GregorianCalendar(); 
     calendar.setTime(DatatypeConverter.parseDate(dateTime).getTime()); 
     return calendar; 
    } 

    public static String marshal(Calendar calendar) { 
     return DatatypeConverter.printDate(calendar); 
    } 

} 

接下來要介紹的轉換器,以JAXB(xjb文件):

<globalBindings> 

    <javaType 
      name="java.util.Calendar" 
      xmlType="xs:dateTime" 
      parseMethod="XsdDateTimeConverter.unmarshal" 
      printMethod="XsdDateTimeConverter.marshal" 
      /> 
    <javaType 
      name="java.util.Calendar" 
      xmlType="xs:date" 
      parseMethod="XsdDateTimeConverter.unmarshal" 
      printMethod="XsdDateTimeConverter.marshal" 
      /> 
</globalBindings> 

xjc產生以下注釋所生成的JAXB機型:

@XmlJavaTypeAdapter(Adapter2.class) 
@XmlSchemaType(name = "date") 
protected Calendar date; 

其中Adapter2.class是一個生成的適配器,它包裝了POJO轉換器。正如你所見,Calendar被用來代替笨拙的javax.xml.datatype.XMLGregorianCalendar。如果您將此示例調整爲Joda-Time,請與我們分享。

+1

由於我正在用JAXB註釋手動編寫Java類,我假設沒有任何問題在相反的方向進行,並且一起跳過xjb文件? – jaxzin 2011-03-01 17:06:29

+0

還有一點,您重申了映射JAXB類字段的簡單實例,但我的問題是關於通過JAX-WS註釋公開爲SOAP服務的方法的參數。在這種情況下,您有任何JAXB類型適應的經驗或例子嗎? – jaxzin 2011-03-01 17:09:00

3

以下遠高於

1.溶液模板)創建一個XSML適配器

import java.util.Date; 

import javax.xml.bind.annotation.XmlTransient; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 

import org.joda.time.DateTime; 

@XmlTransient 
public class XSDDateTimeMarshaller extends XmlAdapter<Date, DateTime> { 

    @Override 
    public DateTime unmarshal(Date date) throws Exception { 
     return new DateTime(date.getTime()); 
    } 

    @Override 
    public Date marshal(DateTime dateTime) throws Exception { 
     return new Date(dateTime.getMillis()); 
    } 

} 

2.)與註釋(snipet從一個實體類)jodatime屬性:

... 

@XmlRootElement(name="MyEntity", namespace="http://www.mycompany.com/module") 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(propOrder={"...", "...", "timeStamp", "...", "..."}) 
public class MyEntity 

...  

    @XmlElement(namespace="http://www.mysite.com/module") 
    @XmlJavaTypeAdapter(XSDDateTimeMarshaller.class) 

    @NotNull 
    @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime") 
    @Column(name="TIME_STAMP") 
    private DateTime timeStamp; 

... 

} 

3 。)將類型綁定添加到您的myentity.xsd中

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.w3.org/2001/XMLSchema http://www.w3.org/2001/XMLSchema.xsd" 
targetNamespace="http://www.mysite.com/module" 
xmlns:tns="http://www.mysite.com/module" 
attributeFormDefault="unqualified" 
elementFormDefault="qualified" 
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
jaxb:extensionBindingPrefixes="xjc" 
jaxb:version="2.1"> 
<xsd:annotation> 
    <xsd:appinfo> 
     <jaxb:globalBindings> 
      <jaxb:javaType name="org.joda.time.DateTime" 
       xmlType="xsd:dateTime" 
       parseMethod="com.mycompany.myproduct.marshaller.XSDDateTimeMarshaller.unmarshal" 
       printMethod="com.mycompany.myproduct.marshaller.XSDDateTimeMarshaller.marshal"/> 
      <jaxb:javaType name="org.joda.time.DateTime" 
       xmlType="tns:date" 
       parseMethod="com.mycompany.myproduct.marshaller.XSDDateTimeMarshaller.unmarshal" 
       printMethod="com.mycompany.myproduct.marshaller.XSDDateTimeMarshaller.marshal"/> 
     </jaxb:globalBindings> 
    </xsd:appinfo> 
</xsd:annotation> 

<xsd:element name="MyEntity" type="tns:MyEntity"/> 

<xsd:complexType name="MyEntity"> 
     <xsd:sequence> 
      ... 
      <xsd:element name="timeStamp" type="tns:date"/> 
      .... 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:simpleType name="date"> 
    <xsd:restriction base="xsd:dateTime" /> 
</xsd:simpleType> 

</xsd:schema> 
+0

請參閱我最新的問題,當我最初編寫它時,我認爲我沒有正確描述它。 – jaxzin 2011-03-02 15:47:10

1

以下是非註釋Joda解決方案。我們已經從xsd生成了對象,並希望它們使用Joda而不是XmlGregorianCalendar。

注意:當我試圖將正確的XmlGregorianCalendar對象傳遞給類中的unmarshal方法時,我得到JaxB編譯器錯誤,表示它需要類型String,而不是XmlGregorianCalendar。測試過的字符串,它似乎工作正常。快速和骯髒的錯誤處理在這裏,所以請解決這個問題。

希望這會有所幫助。

的Maven POM插件片段:

 <plugin> 
      <groupId>org.jvnet.jaxb2.maven2</groupId> 
      <artifactId>maven-jaxb2-plugin</artifactId> 
      <configuration> 
       <schemaDirectory>src/main/resources/schemas/</schemaDirectory> 
       <removeOldOutput>true</removeOldOutput> 
      <bindingIncludes> 
      <bindingInclude>jaxb-custom-bindings.xml</bindingInclude> 
      </bindingIncludes> 
      </configuration> 
      <executions> 
      <execution> 
       <goals> 
       <goal>generate</goal> 
       </goals> 
      </execution> 
      </executions> 
     </plugin> 

JAXB的自定義綁定。xml文件:

<?xml version="1.0" encoding="UTF-8"?> 
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
     version="2.0" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

<globalBindings> 
    <javaType 
      name="org.joda.time.DateTime" 
      xmlType="xs:dateTime" 
      parseMethod="com.yourcompanyname.XSDDateTimeToJodaDateTimeMarshaller.unmarshal" 
      printMethod="com.yourcompanyname.XSDDateTimeToJodaDateTimeMarshaller.marshal" 
      /> 
    <javaType 
      name="org.joda.time.LocalDate" 
      xmlType="xs:date" 
      parseMethod="com.yourcompanyname.XSDDateToJodaLocalDateMarshaller.unmarshal" 
      printMethod="com.yourcompanyname.XSDDateToJodaLocalDateMarshaller.marshal" 
      /> 
</globalBindings> 

public class XSDDateTimeToJodaDateTimeMarshaller { 

private static final Logger LOG = LoggerFactory.getLogger(XSDDateTimeToJodaDateTimeMarshaller.class); 

public static DateTime unmarshal(String xmlGregorianCalendar) { 
    DateTime result= new DateTime(xmlGregorianCalendar); 
    return result; 
} 

public static String marshal(DateTime dateTime) { 
    String result = "MARSHALLING_ERROR"; 
    try { 
     result = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTime.toGregorianCalendar()).toXMLFormat(); 
    } catch (DatatypeConfigurationException e) { 
     LOG.error("Error marshalling Joda DateTime to xmlGregorianCalendar",e); 
    } 
    return result; 
} 

}

public class XSDDateToJodaLocalDateMarshaller { 
private static final Logger LOG = LoggerFactory.getLogger(XSDDateToJodaLocalDateMarshaller.class); 


public static LocalDate unmarshal(String xmlGregorianCalendar) { 
    return new LocalDate(xmlGregorianCalendar); 
} 

public static String marshal(LocalDate localDate) { 
    String result = "MARSHALLING_ERROR"; 
    try { 
     result = DatatypeFactory.newInstance().newXMLGregorianCalendar(localDate.toDateTimeAtStartOfDay().toGregorianCalendar()).toXMLFormat(); 
    } catch (DatatypeConfigurationException e) { 
     LOG.error("Error marshalling Joda LocalDate to xmlGregorianCalendar",e); 
    } 
    return result; 
} 
} 
+0

謝謝你的嘗試,但我正在尋找一個問題的答案,如所述,一個(at)WebService可以接受Joda DateTime對象作爲(at)WebParams。 – jaxzin 2012-03-15 02:32:31

+0

標記位置錯誤,至少對於今天的maven插件來說。簽出[maven-cxf-codegen-plugin](https://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html)的工作示例。它進入內部,但多行xml不支持註釋。 – 2014-04-04 22:21:59