• 认识 CXF(WebService框架)


    Apache CXF = Celtix + Xfire

    支持多种协议:

    1)SOAP1.1,1.2

    2)HTTP

    3)CORBA(Common Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WS。C,C++,C#)

    4)可以与Spring进行快速无缝的整合

    5)灵活的部署:可以运行有Tomcat,Jboss,Jetty(内置),IBMWS,BeaWS上面。

    下载地址:http://cxf.apache.org/download.html

    最新的版本为3.8,但这里以2.4版本为例,解压后的目录结构如下:

    bin(目录):bin 目录中是 CXF 框架中所提供的代码生成、校验、管理控制台工具(可执行命令) 

    docs(目录):CXF 所有类(class)对应的 API 文档,为开发者使用 CXF 完成应用开发提供应有的帮助。 

    etc(目录):包含一个基本的 Service 暴露所需要的 web.xml 文件,及其它的配置文件。 

    lib(目录):包含 CXF 及其运行时所需要的和可选的第三方支持类包(.jar 文件),可以根据不同项目所需的 CXF 特性选择所需要的支持类包。如果不想一一去区分的话,可以直接在 Web 项目中包含所有的 CXF 及其运行时所需要的第三方支持类包(.jar 文件)即可。 其中 cxf-2.0.2-incubator.jar 是 CXF 框架的二进制包文件,包含了全部的模块(modules),cxf-manifest-incubator.jar 是列表清单文件 manifest jar 。 

    以下的 jar 包是所有 CXF 项目所必需的: 
    cxf.jar 
    commons-logging.jar 
    geronimo-activation.jar (Or the Sun equivalent) 
    geronimo-annotation.jar (Or the Sun equivalent) 
    geronimo-javamail.jar (Or the Sun equivalent) 
    neethi.jar 
    jaxb-api.jar 
    jaxb-impl.jar 
    stax-api.jar 
    XmlSchema.jar 
    wstx-asl.jar 
    xml-resolver.jar 
    
    对于 Java2WSDL 和 WSDL2Java,除了必需的之外,还需要再增加如下 jar 包: 
    jaxb-xjc.jar 
    veliocity.jar 
    velocity-dep.jar 
    
    为了支持 JAX-WS ,除了必需的之外,还需要再增加如下 jar 包: 
    jaxws-api.jar 
    saaj-api.jar 
    saaj-impl.jar 
    asm.jar (可选的,但是可以提升包装类型的性能) 
    
    为了支持 XML 配置,除了必需的之外,还需要再增加如下 jar 包:aopalliance.jar 
    spring-beans.jar 
    spring-context.jar 
    spring-core.jar 
    spring.web.jar 
    
    为了独立的 HTTP 服务支持,除了必需的之外,还需要再增加如下 jar 包:geronimo-servlet.jar 
    jetty.jar 
    jetty-sslengine.jar 
    jetty-util.jar 
    sl4j.jar & sl4j-jdk14.jar (可选的,但是可以提升日志 logging) 
    
    为了支持 Aegis ,除了必需的之外,还需要再增加如下 jar 包: 
    jaxen.jar 
    jdom.jar 
    stax-utils.jar 
    
    为了支持 WS-Security ,除了必需的之外,还需要再增加如下 jar 包:bcprov-jdk14.jar 
    wss4j.jar 
    xalan.jar 
    xmlsec.jar 
    
    为了支持 HTTP Binding ,除了必需的之外,还需要再增加如下 jar 包:jra.jar 
    jettison.jar (仅为 JSON 服务所需的) 
    jar包说明

    licenses(目录)列表了引用第三方 jar 包的相关许可协议。 

    modules(目录) modules 目录中包含了 CXF 框架根据不同特性分开进行编译的二进制包文件。发布基于 CXF 框架的 Web 项目时,可以选择使用该目录下的所有 .jar 文件,也可以选择 lib 目 录中的 cxf-2.0.2-incubator.jar 文件。 

    samples(目录)samples 目录中包含了所有随 CXF 二进制包发布的示例,包含这些示例的源代码和相关 Web 应用配置文件,可以方便地用 Ant 来编译运行测试这些示例,来了解 CXF 的开发和使用的方法。可以通过 samples 目录和它各个子目录下的 README.txt 的文件来详细了解示例的编译与运行的步骤。 

    下面介绍下怎样使用Ant和Tomcat来运行一个简单的例子(可以跳过这一部分)

    首先是搭建环境

    1)JAVA_HOME  需要jdk的支持

     

    2)CXF_HOME

     

    3)ANT_HOME

     

     4)CATALINA_HOME

     

    5)Path = ;%CXF_HOME%\bin;%CATALINA_HOME%\bin;%ANT_HOME%\bin

    6)CLASSPATH=.;%CXF_HOME%\lib\cxf-manifest.jar;.\build\classes

    运行CXF例子

    1)拷贝例子中的common_build.xml和java_first_pojo到没有中文的目录下

    2)执行ant server(这个不是固定的,得看ant脚本编写的target)

    3)执行ant client(这个不是固定的,得看ant脚本编写的target)

    上面两步执行完以后,可以看到客户端和服务端有一些输出,说明调用成功,但是还没有在服务器上运行,下面演示怎样发布到Tomcat服务器上

    4)执行ant war,生成war包

     

     

    手动将war包拷贝到Tomcat服务器的webapps中

     

    当然,我们也可以通过命令行的方式将war包拷到Tomcat的相应目录中(之前添加的Tomcat环境起了作用)

    执行ant deploy –Dtomcat=true将项目发布到tomcat的服务器上。

     

    发布到tomcat中:访问http://localhost:8080/helloworld/services/hello_world?wsdl

    服务路径由 cxf-servlet.xml 来配置

     

    6)卸载部署包

    停止tomcat后卸载应用:ant undeploy –Dtomcat=true

    7)清理构建目录

    ant clean

    下面使用CXF发布一个WebService

    1)创建java项目

    2)引入所有依赖包

    3)创建服务类

    可以用两个不同的类发布应用:

    ServerFactoryBean(不需要使用@webservice) 生成的文档不规范,不建议使用。

    JaxWsServerFactoryBean(建议使用此类,需要使用@webservice) 生成的文档可以用参数使之规范,可以发布SOAP1.1,SOAP1.2的协议,当CXF的服务类中没有方法时也可以发布成功,不报错。如果使用SOAP1.2需要用@bindType注解指定。当使用SOAP1.2时wsimport命令失效,需要使用CXF的wsdl2java。

    建议:发布服务的时候使用SOAP1.2,客户端调用的时候使用SOAP1.1。

    创建服务类

    import javax.jws.WebService;
    import javax.xml.ws.BindingType;
    
    @WebService
    @BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING)
    public class HelloService {    
        public String sayHello(String name){
            return name + " hello";
        }
    }

    创建发布类

    import org.apache.cxf.interceptor.LoggingInInterceptor;
    import org.apache.cxf.interceptor.LoggingOutInterceptor;
    import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
    
    public class MyCXFServer {  
        public static void main(String[] args) {
            //创建服务工厂对象
            JaxWsServerFactoryBean sfb = new JaxWsServerFactoryBean();
            //加入输入输出拦截器
            sfb.getInInterceptors().add(new LoggingInInterceptor());
            sfb.getOutInterceptors().add(new LoggingOutInterceptor());
            //指定服务地址
            sfb.setAddress("http://127.0.0.1:5555/hello");
            //设置服务类
            sfb.setServiceClass(HelloService.class);
            //设置服务类的实例对象
            sfb.setServiceBean(new HelloService());
            //发布服务
            sfb.create();
            System.out.println("server ready...");
        }
    }

    在CXF中,也提供了一个用于生成客户端调用代码的工具。它的功能就如同wsimport一样,可以生成一堆客户端调用的代码。既可以生成SOAP1.1也可以生成SOAP1.2。

    此工具位于CXF_HOME/bin目录下。参数与wsimport有所不同。

    它包含以下参数:

    a)-d参数,指定代码生成的目录。

    b)-p参数,指定生成的新的包结构。

    需要说明的是,由于wsdl2java是根据jdk1.7生成的本地代码,所以,需要对生成的代码做一点点修改:如果发现构造函数中有多余的入参,就把多余的入参删除。

    在命令行执行: wsdl2java –d . http://127.0.0.1:6666/helloworld?wsdl

    JaxWsServerFactoryBean不仅可以直接发布类,也可以发布接口

    1)创建服务接口和接口实现类。注意:@WebService注解标在接口上而不是实现类上

    @WebService
    public interface HI {
        public String sayHi(String name);
    }
    
    public class HIImpl implements HI {
        @Override
        public String sayHi(String name) {
            return name+ " hi";
        }
    }

    2)创建发布服务类

    public class MyCXFServerInter {    
        public static void main(String[] args) {
            //创建服务工厂对象
            JaxWsServerFactoryBean sfb = new JaxWsServerFactoryBean();
            //加入输入输出拦截器
            sfb.getInInterceptors().add(new LoggingInInterceptor());
            sfb.getOutInterceptors().add(new LoggingOutInterceptor());
            //指定服务地址
            sfb.setAddress("http://127.0.0.1:9999/hi");
            //设置接口
            sfb.setServiceClass(HI.class);
            //设置接口实现类
            sfb.setServiceBean(new HIImpl());
            //发布服务
            sfb.create();
            System.out.println("server ready...");
        }
    }

    3)调用时用接口调用

    public class HiInterClient {
        public static void main(String[] args) {
            HIService hiService = new HIService();
            //返回的服务的实现类使用接口接收
            HI hi = hiService.getHIPort();
            
            String result = hi.sayHi("王五");
            System.out.println(result);
        }
    }

    在web项目中创建类的cxf服务

    1)创建web项目

    2)导入所有包

    3)创建服务类,必须指定注解@webService

    @WebService//所用的webservice服务类都要要加@webservice,接口的形式加在接口上
    public class HelloService {
        public String sayHello(String name){
            return name + " hello";
        }
    }
    HelloService

    4)配置web.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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
            id="WebApp_ID" version="2.5">
        <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>/service/*</url-pattern>
        </servlet-mapping>
    </web-app>

    5)创建cxf的核心配置文件cxf-servlet.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"
        xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
              http://www.springframework.org/schema/beans/spring-beans.xsd
                http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
                http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
                http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
        <!-- 引入CXF Bean定义如下,早期的版本中使用 -->
        <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" />
        <!-- 
            ===============配置类的形式webservice服务=================
            address:tomcat的host http://ip:port/projectName/service/后面的一端路径
            http://ip:port/projectName/service/hello
            implementor:指定具体的服务的类
         -->
        <jaxws:endpoint id="hello" address="/hello" implementor="com.jwen.web.server.HelloService">
            <!-- 输入拦截器,打印输入的消息 -->
            <jaxws:inInterceptors>
                <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
            </jaxws:inInterceptors>
            <jaxws:outInterceptors>
                <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
            </jaxws:outInterceptors>
        </jaxws:endpoint>
    </beans>

    修改cxf-servlet.xml的位置和文件名

    1)第一种方式

    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    
    <web-app>
        <servlet>
            <servlet-name>cxf</servlet-name>
            <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>      
            <init-param>
              <param-name>config-location</param-name>
              <param-value>classpath:cxf.xml</param-value><!--文件路径-->
         </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>cxf</servlet-name>
            <url-pattern>/services/*</url-pattern>
        </servlet-mapping>  
    </web-app>
    第一种方式

    2)第二种方式

    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:cxf.xml</param-value><!--文件路径-->
      </context-param>
    
        <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>/services/*</url-pattern>
        </servlet-mapping>
    </web-app>
    第二种方式

     

    在web项目中创建接口的cxf服务

    1)创建服务接口在接口上加@webservice

    @WebService
    public interface ByeInter {
        public String sayBye(String name);
    }
    ByeInter

    2)创建服务接口的实现类

    public class ByeInterImpl implements ByeInter {
        @Override
        public String sayBye(String name) {
            return name + " bye";
        }
    }
    ByeInterImpl

    3)在web.xml中配置CXFServlet,和上面的例子是一样的

    4)配置cxf-servlet.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"
        xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
              http://www.springframework.org/schema/beans/spring-beans.xsd
                http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
                http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
                http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
        <!-- 引入CXF Bean定义如下,早期的版本中使用 -->
        <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" />
        
        <!-- 
            ===============配置带有接口的webservice服务=================
            address:tomcat的host http://ip:port/projectName/service/后面的一端路径
            http://ip:port/projectName/service/bye
            serviceClass:服务接口的类
            
         -->
        <jaxws:server address="/bye" serviceClass="com.jwen.web.server.inter.ByeInter">
            <!-- 服务接口的实现类 -->
            <jaxws:serviceBean>
                <bean class="com.jwen.web.server.inter.ByeInterImpl"></bean>
            </jaxws:serviceBean>
            <jaxws:inInterceptors>
                <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
            </jaxws:inInterceptors>
            <jaxws:outInterceptors>
                <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
            </jaxws:outInterceptors>
        </jaxws:server>        
    </beans>

    使用jquery调用CXF

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    <script type="text/javascript" src="js/jquery-1.6.0.js"></script>
    <script type="text/javascript">
        $(function(){        
            $("#mybutton").click(function(){
                //获得文本的值
                var mytext = $("#mytext").val();
                //组装消息体
                var data = '<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">'
                        +'<S:Body><ns2:sayBye xmlns:ns2="http://inter.server.web.rl.com/">'
                        +'<arg0>'+mytext+'</arg0>'
                        +'</ns2:sayBye>'
                        +'</S:Body>'
                        +'</S:Envelope>';
                $.ajax({
                    url:'http://localhost:8080/cxf-web-server/service/bye',
                    type:'post',
                    dataType:'xml',//返回值的数据类型
                    contentType:'text/xml;charset=UTF-8',//指定发送的数据类型
                    data:data,//发送的消息体
                    success:function(responseText){
                        //解析消息体
                        var returnObj = $(responseText).find("return");
                        alert(returnObj.text());
                    },
                    error:function(){
                        alert('system error');
                    }                
                });
            });
        });
    </script>
    </head>
    <body>
    <input type="text" id="mytext">
    <input type="button" id="mybutton" value="jquery_invoke_ws">
    </body>
    </html>
    jquery调用
  • 相关阅读:
    Java动态代理设计模式
    AOP的相关概念
    如何解决表单提交的中文乱码问题
    怎么防止重复提交
    http的响应码200,404,302,500表示的含义分别是?
    JSP三大指令是什么?
    说一下 session 的工作原理?
    session 和 cookie 有什么区别?
    说一下 JSP 的 4 种作用域?
    jsp有哪些内置对象?作用分别是什么?
  • 原文地址:https://www.cnblogs.com/jwen1994/p/10630417.html
Copyright © 2020-2023  润新知