您的位置:首页 > 其它

用cxf发布和调用web service

2016-09-30 15:44 405 查看
用cxf发布和调用web service

http://cxf.apache.org/docs/jax-ws-configuration.html  官方API
helloword地址

 用CXF来做web service是比较简单的,本文就简单介绍一下如何一步步发布web service,以及调用现有的web service。另外如果系统已经使用了Spring MVC,那么引入CXF需要额外的步骤,见本人另外一篇博客http://kyfxbl.iteye.com/blog/1432920。如果展现层没有用spring
mvc,而是用struts2之类的,可以省去这一步 

首先介绍怎么发布web service: 

第1步是创建一个普通的java接口,然后用@WebService注解声明这是一个web service 

Java代码  


package com.huawei.framework.webservice;  

  

import javax.jws.WebService;  

  

import com.huawei.framework.model.User;  

  

@WebService  

public interface HelloWorld {  

  

    String sayHi(User user);  

  

}  

可以看到,这个接口非常普通,不需要继承什么额外的接口,只需要注解一个@WebService就可以 

第2步当然是需要给这个接口提供一个实现类 

Java代码  


package com.huawei.framework.webservice;  

  

import com.huawei.framework.model.User;  

  

public class HelloWorldImpl implements HelloWorld {  

  

    public String sayHi(User theUser) {  

        return "Hello " + theUser.getName() + " ,your age is "  

                + theUser.getAge();  

    }  

  

}  

这个类更加简单,连注解都省了,但是如果这个类实现了不止一个接口,那么就需要加上@WebService注解,不过一般不会这样 

第3步就到了cxf出场的时候了,需要在spring配置文件中加上cxf的配置 

Xml代码  


<?xml version="1.0" encoding="UTF-8"?>  

  

<beans xmlns="http://www.springframework.org/schema/beans"  

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"  

    xsi:schemaLocation="http://www.springframework.org/schema/beans  ;

                            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  ;

                            http://cxf.apache.org/jaxws   ;

                            http://cxf.apache.org/schemas/jaxws.xsd">  

  

    <import resource="classpath:META-INF/cxf/cxf.xml" />  

    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  

  

    <jaxws:endpoint id="helloWorld"  

        implementorClass="com.huawei.framework.webservice.HelloWorldImpl"  

        address="/HelloWorld" />  

  

</beans>  

这里只写了CXF所需的配置,spring配置文件的其他内容已省略。用到的元素是<jaxws:endpoint>,implementorClass属性就是我们提供的实现类,然后address属性是这个web service对外暴露的路径 

最后第4步是在web.xml中加载cxf 

Xml代码  


<?xml version="1.0" encoding="UTF-8"?>  

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

    xmlns="http://java.sun.com/xml/ns/javaee"  

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  

    id="MyFramework" version="3.0">  

      

    <display-name>MyFramework</display-name>  

      

    <context-param>  

        <param-name>contextConfigLocation</param-name>  

        <param-value>   

            WEB-INF/beans.xml,   

            WEB-INF/cxf.xml  

        </param-value>   

    </context-param>  

      

    <listener>    

        <listener-class>    

            org.springframework.web.context.ContextLoaderListener    

        </listener-class>    

    </listener>    

      

    <servlet>  

        <servlet-name>framework</servlet-name>  

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  

        <init-param>    

            <param-name>contextConfigLocation</param-name>    

            <param-value>WEB-INF/spring-mvc.xml</param-value>    

        </init-param>    

        <load-on-startup>1</load-on-startup>  

    </servlet>  

  

    <servlet-mapping>  

        <servlet-name>framework</servlet-name>  

        <url-pattern>/</url-pattern>  

    </servlet-mapping>  

      

    <servlet>    

        <servlet-name>CXFServlet</servlet-name>    

        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>    

        <load-on-startup>2</load-on-startup>    

    </servlet>    

    

    <servlet-mapping>    

        <servlet-name>CXFServlet</servlet-name>    

        <url-pattern>/webservice/*</url-pattern>    

    </servlet-mapping>   

      

</web-app>  

这里写的比较复杂,是为了兼容spring mvc。这里把/webservice/*作为对外暴露的路径,和上面的web service address要结合起来,比如说http://ip:port/app_name/webservice/HelloWorld,就会指向这个例子里声明的web
service接口 

=========================================================================================================
还有另一种配置方式

第3步  需要在applicationContext.xml配置文件中加上cxf的配置 

 <!-- ant提供给shopping的接口  2016-03-01 by 于瀚韬   这是对外发布 -->
   <cxf:server serviceClass="com.qianhui.ant.web.shoppingInterface.AddUserInAnt" address="/antInterface">
<cxf:serviceBean> 
<bean class="com.qianhui.ant.web.shoppingInterface.AddUserInAntImpl"></bean>
</cxf:serviceBean>
</cxf:server>
<!-- LiteratorsMarkWSInterface  这是接收外部接口 -->
    <cxf:client id="LiteratorsMarkWSInterface" 
    serviceClass="com.qianhui.ant.web.LiteratorsMarkWSInterface.neusoft.LiteratorsMarkWSInterface" 
    address="http://221.226.179.230/webservice/searchMarkWS"/>

第4步 在web.xml配置中加上

 <!-- cxf webService begin  -->
  <servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ant/*</url-pattern>
</servlet-mapping>
  <!-- cxf webService end  --> 

地址为:url-pattener + address
 

 
通过以上4步,就发布了一个web service,在浏览器里输入http://ip:port/app_name/webservice,就会看到这个sayHi的web
service了,并且cxf已经自动生成了wsdl文件
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

然后介绍一下怎么通过cxf调用已有的web service 

第一种 获得了wsdl地址

用wsdl2java命令,生成所需的java文件

wsdl2java http://xxxxxxxxxxxxxxxxxx? wsdl 

将生成文件导入工程即可

------------------------------------------------------------------------------------------------------------------------------------------------------------
第二种 获得了wsdl文件

1、首先用wsdl2java命令,生成所需的java文件,当然前提是已经得到了wsdl文件 

wsdl2java -p com.huawei.wfm.czekh.webservice.remedy -d ../../src/remedy -all fileName.wsdl 
用上面这个命令,就可以根据wsdl文件,生成所需的所有java文件,参数说明如下: 

-p 指定生成java文件的package name 
-d 生成java文件的存放路径 
-all 生成客户端和服务端代码,这里还可以用-client生成客户端,用-server生成服务端,不过实际上区别不大,只要用-all就可以了 
最后一个参数就是目标wsdl文件 

2、查看生成的文件列表,可以看到有以下文件: 



大部分都是model类,可以不管。以下文件是比较特殊的: 

ObjectFactory.java 
package-info.java 
这2个文件我也不知道是干嘛的,不过反正是不能删的 

以_Client结尾的那个文件,是一个客户端,没有用,可以删除 
以_Server结尾的那个文件,是启动服务端(貌似是内置的jetty),没有用,可以删除 

以Service结尾的那个文件,不但没有用,还要坏事,因为其中有以下代码: 

Java代码  


@WebServiceClient(name = "CIP-B2B_ServiceAssuranceWorkForceClientManagementService", wsdlLocation = "file:CIP-B2B_ServiceAssuranceWorkForceClientManagement.wsdl", targetNamespace = "http://cz.o2.com/systems/integrationinfrastructure/CIP-B2B/CIP-B2B_ServiceAssuranceWorkForceClientManagement/1.0")  

里面有一个"file:CIP-B2B_ServiceAssuranceWorkForceClientManagement.wsdl",因为这些类是根据一个本地的wsdl文件生成的,但是实际部署的时候一般不会放这个文件,所以在加载cxf配置的时候,是会出错的 
实际上试验发现,这个文件可以直接删掉 

以PortType结尾的文件,很关键,是接口类 

以PortTypeImpl结尾的文件,是接口类的实现类,其中也有一行注解: 

Java代码  


@javax.jws.WebService(  

                      serviceName = "CIP-B2B_ServiceAssuranceWorkForceClientManagementService",  

                      portName = "CIP-B2B_ServiceAssuranceWorkForceClientManagementPort",  

                      targetNamespace = "http://cz.o2.com/systems/integrationinfrastructure/CIP-B2B/CIP-B2B_ServiceAssuranceWorkForceClientManagement/1.0",  

                      wsdlLocation = "file:CIP-B2B_ServiceAssuranceWorkForceClientManagement.wsdl",  

                      endpointInterface = "com.huawei.wfm.czekh.webservice.remedy.CIPB2BServiceAssuranceWorkForceClientManagementPortType")  

要把这里的 

Java代码  


wsdlLocation = "file:CIP-B2B_ServiceAssuranceWorkForceClientManagement.wsdl",  

删除 

所以在用wsdl2java命令生成java类之后,只需要把XXXService.java、XXX_Client.java、XXX_Server.java删除,把XXXPortTypeImpl.java改一下,就能用了 

然后如果是要做客户端的话,就把除了XXXPortTypeImpl.java以外的所有文件拷贝到工程里;如果是做服务端的话,就把所有文件拷贝到工程里,然后根据实际情况修改XXXPortTypeImpl.java就可以了 

3、最后是cxf的配置文件,这里和http://kyfxbl.iteye.com/blog/1432952提到的方式是一样的,没有区别 

首先是服务端: 

Xml代码  


<?xml version="1.0" encoding="UTF-8"?>  

  

<beans xmlns="http://www.springframework.org/schema/beans"  

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  

    xmlns:jaxws="http://cxf.apache.org/jaxws"  

    xsi:schemaLocation="http://www.springframework.org/schema/beans  ;

                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  ;

                            http://www.springframework.org/schema/context   ;

                            http://www.springframework.org/schema/context/spring-context-3.0.xsd  ;

                            http://cxf.apache.org/jaxws   ;

                            http://cxf.apache.org/schemas/jaxws.xsd">  

  

    <context:component-scan base-package="com.huawei.wfm.czekh" />  

  

    <import resource="classpath:META-INF/cxf/cxf.xml" />  

    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />  

    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  

  

    <jaxws:endpoint id="remedy" implementor="#MyWebserviceServer"  

        address="/RemedyWebService" />  

  

</beans>  

Java代码  


@Component("MyWebserviceServer")  

@WebService(serviceName = "CIP-B2B_ServiceAssuranceWorkForceClientManagementService", portName = "CIP-B2B_ServiceAssuranceWorkForceClientManagementPort", targetNamespace = "http://cz.o2.com/systems/integrationinfrastructure/CIP-B2B/CIP-B2B_ServiceAssuranceWorkForceClientManagement/1.0", endpointInterface = "com.huawei.wfm.czekh.webservice.remedy.CIPB2BServiceAssuranceWorkForceClientManagementPortType")  

public class CIPB2BServiceAssuranceWorkForceClientManagementPortTypeImpl  

        implements CIPB2BServiceAssuranceWorkForceClientManagementPortType {  

  

    @Autowired  

    private Test test;  

  

        // 省略无关方法     

  

    public AcknowledgeResponse acknowledge(  

            AcknowledgeRequest body) {  

  

        test.sayHi("somebody");  

  

        AcknowledgeResponseBody responseBody = new AcknowledgeResponseBody();  

        responseBody.setStatus(true);  

        responseBody.setErrorDescription("wcnm");  

  

        AcknowledgeResponse result = new AcknowledgeResponse();  

        result.setResponseBody(responseBody);  

  

        return result;  

    }  

  

}  

可以看到,配置方式没有变化,也可以用spring进行依赖注入 

然后是客户端: 

Xml代码  


<?xml version="1.0" encoding="UTF-8"?>  

  

<beans xmlns="http://www.springframework.org/schema/beans"  

    xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

    xsi:schemaLocation="http://www.springframework.org/schema/beans   ;

                        http://www.springframework.org/schema/beans/spring-beans.xsd  ;

                        http://cxf.apache.org/jaxws   ;

                        http://cxf.apache.org/schemas/jaxws.xsd">  

  

    <bean id="propertyConfigurer"  

        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  

        <property name="locations">  

            <list>  

                <value>classpath:webservice_address.properties</value>  

            </list>  

        </property>  

    </bean>  

  

    <jaxws:client id="client"  

        serviceClass="com.huawei.wfm.remedy.CIPB2BServiceAssuranceWorkForceClientManagementPortType"  

        address="${remedy_address}" />  

  

</beans>  

Java代码  


public class Main {  

  

    public static void main(String[] args) {  

  

        ApplicationContext context = new ClassPathXmlApplicationContext(  

                "cxf.xml");  

        CIPB2BServiceAssuranceWorkForceClientManagementPortType client = (CIPB2BServiceAssuranceWorkForceClientManagementPortType) context  

                .getBean("client");  

  

        AcknowledgeRequestBody body = new AcknowledgeRequestBody();  

        body.setCustSysId("123456");  

  

        AcknowledgeRequest request = new AcknowledgeRequest();  

        request.setRequestBody(body);  

  

        AcknowledgeResponse response = client.acknowledge(request);  

        String desc = response.getResponseBody().getErrorDescription();  

        System.out.println(desc);  

  

    }  

  

}  

客户端的配置也是一样的。有一点要注意,好像只能通过getBean("client")拿到实例化的bean,通过@Autowired可能是搞不定的 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cxf web service