如何为SOAP调用设置日期格式?Eclipse生成客户端遇格式不匹配问题
解决SOAP客户端日期格式不匹配问题
我帮你搞定这个SOAP客户端的日期格式问题!你遇到的情况很常见——Eclipse自动生成的JAX-WS客户端默认会把Date类型序列化成带毫秒和时区标识(比如.000Z)的格式,但服务器只接受不带这些的yyyy-MM-dd'T'HH:mm:ss格式。下面给你几种可行的解决方案:
方法一:用JAXB绑定文件自定义日期序列化(推荐)
这种方法最规范,能从生成客户端的源头控制日期格式,避免后续修改代码的麻烦:
创建JAXB绑定文件
新建一个binding.xml文件,指定TimeZ类里validFrom字段的日期适配器:<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.1"> <!-- 定位到TimeZ类型下的validFrom字段 --> <jaxws:bindings node="xsd:complexType[@name='TimeZ']//xsd:element[@name='validFrom']"> <jaxb:property> <jaxb:baseType> <jaxb:javaType name="java.util.Date" parseMethod="com.yourcompany.yourlibrary.DateAdapter.parseDate" printMethod="com.yourcompany.yourlibrary.DateAdapter.printDate"/> </jaxb:baseType> </jaxb:property> </jaxws:bindings> </jaxws:bindings>注意把
com.yourcompany.yourlibrary换成你项目实际的包路径。编写日期适配器类
创建对应的DateAdapter类,负责把Date转换成服务器需要的字符串格式:package com.yourcompany.yourlibrary; import java.text.SimpleDateFormat; import java.util.Date; import javax.xml.bind.annotation.adapters.XmlAdapter; public class DateAdapter extends XmlAdapter<String, Date> { // 用ThreadLocal避免SimpleDateFormat线程不安全问题 private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")); @Override public Date unmarshal(String dateStr) throws Exception { return DATE_FORMAT.get().parse(dateStr); } @Override public String marshal(Date date) throws Exception { return DATE_FORMAT.get().format(date); } }重新生成SOAP客户端
在Eclipse里右键点击WSDL文件,选择「Web Services > Generate client」,在向导的「Bindings」步骤中添加刚才创建的binding.xml文件,然后完成生成。新生成的客户端会自动使用你定义的日期格式序列化validFrom字段。
方法二:修改已生成的客户端代码
如果不想重新生成客户端,可以直接修改现有代码:
- 找到生成的
TimeZ.java类,找到validFrom字段的定义。 - 在该字段上添加
@XmlJavaTypeAdapter注解,指定我们写的DateAdapter:import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; // ...其他导入 public class TimeZ { // ...其他字段 @XmlJavaTypeAdapter(DateAdapter.class) protected Date validFrom; // ...getter和setter方法 } - 把
DateAdapter类放到项目的对应包下即可。
方法三:动态设置Marshaller属性(适合临时调试)
如果你只是想临时调整,不想修改代码或重新生成客户端,可以在创建客户端实例时,手动设置JAXB Marshaller的日期格式属性:
// 初始化你的SOAP客户端 YourService service = new YourService(); YourPortType port = service.getYourPort(); // 获取BindingProvider并设置Marshaller属性 BindingProvider bindingProvider = (BindingProvider) port; Map<String, Object> requestContext = bindingProvider.getRequestContext(); requestContext.put("jaxb.formatted.date", "yyyy-MM-dd'T'HH:mm:ss");
不过这种方法依赖具体的JAX-WS实现(比如Metro或CXF),兼容性可能不如前两种方法,只适合临时测试用。
内容的提问来源于stack exchange,提问作者owen gerig
相关产品推荐
相关产品推荐

