cxf 客户端 Date XMLGregorianCalendar

来源:互联网 发布:网络敏感词库 编辑:程序博客网 时间:2024/05/22 12:54

cxf ant客户端生成

 

<?xml version="1.0"?>
<project name="cxf wsdl2java" basedir=".">
    <property name="cxf.home" location="F:\Tools\apache-cxf-2.5.0" />

    <path id="cxf.classpath">
        <fileset dir="${cxf.home}/lib">
            <include name="*.jar" />
        </fileset>
    </path>

    <target name="cxfWSDLToJava">
        <java classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
            <arg value="-client" />
            <arg value="-p" />
            <arg value="com.yododo.ws.search.hotel.client" />
            <arg value="-b" />
            <arg value="jaxb-binding-date.xml" />
            <arg value="-d" />
            <arg value="src" />
            <arg value="http://localhost:8088/ws/hotelSearchEngine?wsdl" />
            <classpath>
                <path refid="cxf.classpath" />
            </classpath>
        </java>
    </target>
</project>

下面的文件是将日期生成Java的Date类型配置
<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings wsdlLocation="http://localhost:8088/ws/hotelSearchEngine?wsdl=HotelSearchEngine.wsdl"
  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='http://search.ws.yododo.com/']">
        <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> 


wsdlLocation="http://localhost:8088/ws/hotelSearchEngine?

 

在利用CXF的wsdl2java生成客户端时,默认情况下java的Date类型会自动转换成XMLGregorianCalendar,如果想生成Date类型,该怎样处理?答案如下:

   1.生成配置文件(一般取名为jaxb-binding-date.xml,可放在任意路径下,只是在运行wsdl2java时使用):

<jaxws:bindings          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      <SPAN style="COLOR: #ff0000"> [@targetNamespace='http://service.test.com/']"></SPAN>      <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>


  这里需要注意的一点是:targetNamespace需要替换成自己的目标命名空间(可以在wsdl服务中看到)

 

   2.然后再在cmd下运行wsdl2java:

wsdl2java -p com.jd.crm.service.webserviceclient.complaintdetails -b D:\cxf\jaxb-binding-date.xml -d D:\cxf  http://localhost:9090/services/complaintDetails?wsdl


参数说明:

    -p: 生成的客户端代码所在的包路径

    -b: jaxb-binding-date.xml文件的路径

    -d: 生成的客户端代码的本地存放路径

     http://localhost:9090/services/complaintDetails?wsdl    ----  webservice服务端wsdl访问路径

 

 

-------------------------------

 

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

private XMLGregorianCalendar convertToXMLGregorianCalendar(Date date) {

        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(date);
        XMLGregorianCalendar gc = null;
        try {
            gc = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
        } catch (DatatypeConfigurationException e) {
            LOG
                    .debug(
                            "There are some error for convert java.util.Date to XMLGregorianCalendar",
                            e);
        }
        return gc;
    }

Remark:
            由于在使用CXF的 wsdl2java 生成Java客户端时,JAXB(默认)把java.util.Date类型解释为 XMLGregorianCalendar,所以在客户端调用的时候,也需要传入XMLGregorianCalendar参数来对应Date类型,此上是一种解决办法。


----------------------------------------------------------------------------------------------



默认情况下,JAXB将xsd:date, xsd:time, 和xsd:dateTime映射为XMLGregorianCalendar , 对于从java开始构建service的人,很少会直接用到这个类, 一般情况下我们都是用java.util.Date或者java.util.Calendar, 调用apache cxfjava2wsdl, 我们得到的wsdl 的schema部分是xsd:dateTime, 当你再次调用wsdl2java来生产impl的时候,你会发现这个impl根本无法编译, 因为impl里是用的是XMLGregorianCalendar , 而SEI则是java.util.Date或者java.util.Calendar
那么如何才能使得wsdl2java生产的impl里,也是java.util.Date或者java.util.Calendar呢?

答案就是使用jaxws/jaxb 的customization。 jaxb允许我们做数据类型的转换,类javax.xml.bind.DatatypeConverter, 就是用来做这个的。
但是,jaxb只为我们做了xsd:datejava.util.Calendar, java.util.Date需要自己来完成,好在我已经把这个代码放到了apachecxf里org.apache.cxf.tools.common.DataTypeAdapter

这里给出一个简单的例子,注意jaxb customzation部分是嵌入在schema里的

<xs schema elementformdefault="qualified" version="1.0" xmlns xs="http://www.w3.org/2001/XMLSchema" jaxb="http://java.sun.com/xml/ns/jaxb" version="2.0" targetnamespace="calendar-schemalet">  <xs annotation>  <xs appinfo>    <jaxb globalbindings>      <jaxb javatype name="java.util.Calendar" xmltype="xs:date" parsemethod="javax.xml.bind.DatatypeConverter.parseDate" printmethod="javax.xml.bind.DatatypeConverter.printDate" />    </jaxb globalbindings>  </xs appinfo></xs annotation></xs schema> 

那么上面这段代码就可以把xsd:date转换为java.util.Calendar了,而且是全局替换
如果你需要转换的schema类型是dateTime, 那么parseMethod 的parseDate就得改成parseDateTime, printMethod 也是类似。
这里再给一个java.util.Date的例子, 假设我们需要映射xsd:time 到java.util.Date,那么我们可以这些写:

<xs schema elementformdefault="qualified" version="1.0" xmlns xs="http://www.w3.org/2001/XMLSchema" jaxb="http://java.sun.com/xml/ns/jaxb" version="2.0" targetnamespace="calendar-schemalet">  <xs annotation>  <xs appinfo>    <jaxb globalbindings>      <jaxb javatype name="java.util.Date" xmltype="xs:time" parsemethod="org.apache.cxf.tools.common.DataTypeAdapter.parseTime" printmethod="org.apache.cxf.tools.common.DataTypeAdapter.printTime" />    </jaxb globalbindings>  </xs appinfo></xs annotation></xs schema>

 

CXF基本使用(2011-10-16)
背景说明
CXF版本:apache-cxf-2.3.6
JDK版本:jdk1.6.0_15
引入CXF
从官网下载最新jar包,地址:http://cxf.apache.org/download.html
并把下载的jar文件引入到对应的项目工程里面。
为简单起见,我把lib目录下的所有文件引入到我对应目录里面。
如果用CXF开发客户端,那么CXF的引入就到此为止了。
如果用CXF开发服务端,那么需要在web.xml配置CXF的servlet过滤器。
对应代码:
<!-- cxf 服务端配置-->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<!--过滤cxf路径下所有的请求-->
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>
简单DEMO
服务端
IHelloService.java
package com.tds.ws.service;

import javax.jws.WebParam;
import javax.jws.WebService;
import com.tds.ws.vo.Customer;

@WebService
public interface IHellowService {
/**
* 服务器段
* @param c1
* @param c2
* @return
*/
public Customer selectMaxLongNameCustomer(@WebParam(name = "c1") Customer c1, @WebParam(name = "c2") Customer c2);

public Customer selectMaxAgeStudent(@WebParam(name = "c1") Customer c1, @WebParam(name = "c2") Customer c2);

}


@WebService注解告诉CXF,该方法将作为WEB服务方步出去(可指定别名)。
@WebParam注解告诉CXF,该方法在客户端生成时,参数名称。
HelloServiceJImpl.java
package com.tds.ws.service.impl;

import javax.jws.WebService;
import com.tds.ws.service.IHellowService;
import com.tds.ws.vo.Customer;
@WebService
public class HellowServiceImpl implements IHellowService{
@Override
public Customer selectMaxAgeStudent(Customer c1, Customer c2) {
Customer c=null;
if(c1==null || c2==null){
c=new Customer();
System.out.println("输入参数为空");
c.setName("输入参数为空");//为测试方步
return c;
}
c=c1.getAge()>c2.getAge()?c1:c2;
return c;
}

@Override
public Customer selectMaxLongNameCustomer(Customer c1, Customer c2) {

if(c1==null || c2==null){
return null;
}
return c1.getName().length()>c2.getName().length()?c1:c2;
}

}


Customer.java:
package com.tds.ws.vo;

import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Customer")
public class Customer {

private long id;

private String name;

private Date birthday;

private int age;

private DataHandler imageData;


/**
* @return the imageData
*/
public DataHandler getImageData() {
return imageData;
}

/**
* @param imageData the imageData to set
*/
public void setImageData(DataHandler imageData) {
this.imageData = imageData;
}

/**
* @return the id
*/
public long getId() {
return id;
}

/**
* @param id the id to set
*/
public void setId(long id) {
this.id = id;
}

/**
* @return the name
*/
public String getName() {
return name;
}

/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}

/**
* @return the birthday
*/
public Date getBirthday() {
return birthday;
}

/**
* @param birthday the birthday to set
*/
public void setBirthday(Date birthday) {
this.birthday = birthday;
}

/**
* @return the age
*/
public int getAge() {
return age;
}

/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}

}


以上完成了服务端业务代码,接着使用code first方式发布WebService。
PublishHellService.java发布类:
package com.tds.ws.util;

import javax.xml.ws.Endpoint;
import org.apache.cxf.endpoint.Server
import com.tds.ws.service.impl.HellowServiceImpl;

public class PublishHellService {

/**
* @param args
*/
public static void main(String[] args) {
// 一般方法发布WS
Endpoint.publish("http://127.0.0.1:8080/webApp/cxf/helloService", new HellowServiceImpl());
}
}


运行main方法,并打开浏览器输入如下网址:
http://127.0.0.1:8080/webApp/cxf/helloService?wsdl查看页面,如果能出现xml格式的文件说明cxf发布成功了。
客户端
客户端使用CXF生成比较简单,可以通过命令的方式生成,也可以通过eclipse方式生成。
命令方式:切换到下载的cxf包下的bin目录。运行以下命令:
//在E盘的code文件夹下生成客户端,并指定客户端的包路径为com.tds.cxf ,服务端的wsdl
//地址为
wsdl2java -p com.tds.cxf -d E:\code
http://127.0.0.1:8080/webApp/cxf/helloService?wsdl
Eclipse默认使用axis构建ws客户端,在这里需配置选项方可。
方法:window-->preferences-->web Service-->Cxf2.Xpreferences指定cxf runtime的依赖库。


这里用eclipse方式生成
在自己的web项目中邮件New-->Web Service-->Web Service Client 并next。

在service definition中输入刚才的网址:http://127.0.0.1:8080/webApp/cxf/helloService?wsdl
并点击Finish结束。
此时会生成如下代码:

客户端代码:
package com.tds.ws.client.cxf.util;

import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.xml.datatype.XMLGregorianCalendar;

import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
import com.tds.ws.client.cxf.service.Customer;
import com.tds.ws.client.cxf.service.IHellowService;
import com.tds.ws.client.cxf.service.impl.HellowServiceImplService;

/**
* Ws一般调用方式
* @author Administrator
*
*/
public class BaseClient {

public static void main(String[] args) {
HellowServiceImplService service=new HellowServiceImplService();
IHellowService port = service.getHellowServiceImplPort();
Customer[] c=getCustomer();
port.selectMaxAgeStudent(c[0], c[1]);
}
private static Customer[] getCustomer() {
Customer c1 = new Customer();
c1.setAge(18);
GregorianCalendar x1 = (GregorianCalendar) GregorianCalendar.getInstance();
x1.set(Calendar.YEAR, 1985);

XMLGregorianCalendar r = new XMLGregorianCalendarImpl(x1);
c1.setBirthday(r);
c1.setId(11);
c1.setName("zhangsan");
Customer c2 = new Customer();
c2.setAge(20);
x1.set(Calendar.YEAR, 1986);
c2.setBirthday(r);
c2.setId(12);
c2.setName("lisi");
return new Customer[] { c1, c2 };
}
}

finally:

 

<?xml version="1.0" encoding="UTF-8"?><jaxws:bindings       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">      <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:javaType name="java.util.Date" xmlType="xs:date"                      parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDate"                      printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDate"/>      </jxb:globalBindings>  </jaxws:bindings></jaxws:bindings>


原创粉丝点击