java JAX-WS 和 Joda-Time?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5106987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JAX-WS and Joda-Time?
提问by jaxzin
How do I write a JAX-WS service so the @WebParam of my @WebMethod is a Joda-Time class like DateTime? Will @XmlTypeAdapter on a parameter work? I'm deploying to GlassFish 2.1.
如何编写 JAX-WS 服务,以便我的 @WebMethod 的 @WebParam 是像 DateTime 这样的 Joda-Time 类?参数上的@XmlTypeAdapter 会起作用吗?我正在部署到 GlassFish 2.1。
Let me clarify the question because both answers so far have focused on binding custom types to existing JAXB classes, which is related but not the question I'm asking. How do I make the following @WebService accept joda DateTime objects as parameters?
让我澄清一下这个问题,因为到目前为止,这两个答案都集中在将自定义类型绑定到现有的 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
);
}
采纳答案by dulon
You have to annotate the parameter directly such as below (I am making use of XSDDateTimeMarshaller written by @DennisTemper as one of the answers to your question but feel free to substitute with another one...) :
您必须直接注释参数,如下所示(我正在使用@DennisTemper 编写的 XSDDateTimeMarshaller 作为您问题的答案之一,但可以随意替换为另一个...):
@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
);
}
回答by Tomasz Nurkiewicz
First write simple converter (to Calendar
in this example, but can be easily changed to Joda-Time):
首先编写简单的转换器(Calendar
在本例中为 to ,但可以轻松更改为 Joda-Time):
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);
}
}
Next you have to introduce your converter to JAXB (xjb
file):
接下来,您必须将转换器引入 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>
In the generated JAXB models xjc
produced the following annotation:
在生成的 JAXB 模型中xjc
生成了以下注释:
@XmlJavaTypeAdapter(Adapter2.class)
@XmlSchemaType(name = "date")
protected Calendar date;
Where Adapter2.class
is a generated adapter that wraps your POJO converter. As you can see Calendar
is used instead of clumsy javax.xml.datatype.XMLGregorianCalendar
. If you adjust this example to Joda-Time, please share it with us.
Adapter2.class
包装 POJO 转换器的生成适配器在哪里。如您所见Calendar
,使用的是代替 clumsy javax.xml.datatype.XMLGregorianCalendar
。如果您将此示例调整为 Joda-Time,请与我们分享。
回答by DennisTemper
Well following solution template above
很好地遵循上面的解决方案模板
1.) Create an XSML Adapter
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.) Annotate jodatime attribute with (snipet from an entity class):
2.) 使用(来自实体类的片段)注释 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.) add type bindings to your myentity.xsd
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>
回答by Ed J
Here's a non-annotation Joda solution. We have generated objects from xsd's and want them to use Joda instead of XmlGregorianCalendar.
这是一个非注释的 Joda 解决方案。我们已经从 xsd 生成了对象,并希望它们使用 Joda 而不是 XmlGregorianCalendar。
Note: When I tried to pass a proper XmlGregorianCalendar object to the unmarshal methods in the classes, I got JaxB compiler errors that said it required type String, not XmlGregorianCalendar. Tested with String, and it appears to be working fine. Quick and dirty error handling here, so fix that up as you please.
注意:当我尝试将正确的 XmlGregorianCalendar 对象传递给类中的解组方法时,我收到了 JaxB 编译器错误,指出它需要类型 String,而不是 XmlGregorianCalendar。用字符串测试,它似乎工作正常。在这里处理快速而肮脏的错误,所以请随意修复。
Hope this helps.
希望这可以帮助。
Maven pom plugin snippet:
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-custom-bindings.xml file:
jaxb-custom-bindings.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;
}
}