• day46_Webservice学习笔记_02


    一、回顾昨天所学

    什么是webservice?
        什么是远程调用技术?答:系统和系统之间的调用,从远程系统当中获取业务数据。
        Webservice是web服务,他是用http传输SOAP协议数据的一种远程调用技术。

    Webservice的入门程序
        服务端
            第一步:创建SEI接口
            第二步:创建SEI实现类,要在类上加入注解:@WebService,作用是标识这个类是服务类,要发布里面的public方法。
            第三步:发布服务,Endpoint的publish方法,有2两个参数:1.服务地址  2.实现类实例
            第四步:测试服务是否发布成功,通过阅读使用说明书,确定服务接口、方法、参数和返回值存在,说明服务发布成功。
                WSDL地址:服务地址+”?wsdl”,比如:http://127.0.0.1:54321/weather?wsdl
                WSDL阅读方式,从下往上,service --> binding --> portType --> 其中有接口、方法、参数和返回值
        客户端
            第一步:使用wsimport命令生成客户端代码
            第二步:根据使用说明书,使用客户端调用服务端
                创建服务视图,视图是从service的name属性获取
                获取服务实现类,从portType的name属性获取
                调用查询方法,从portType下的operation标签的name属性获取

    Webservice的优缺点:
        优点:发送方式采用http的post,http默认端口是80,所以跨防火墙。
              数据封装使用XML格式,XML是跨平台,所以webservice可以跨平台。
              Webservice支持面向对象开发。
        缺点:使用XML封装数据,需要额外传输其他标签,性能较差。

    Webservice的应用场景
    宏观
        软件集成和复用
    微观
        适用场景:
            发布服务(对内/对外),不考虑性能,不考虑客户端类型,建议使用webservice
            服务端已经确定webservice,客户端只能使用webservice
        不适用场景:
            考虑性能时,不建议使用webservice
            同构程序下,不建议使用webservice,比如:客户端服务端都是java开发,建议使用Java RMI,Java的RMI同样可以实现远程调用,而且性能比webservice好很多。

    Webservice的三要素
        WSDL:
            定义:web服务描述语言,它是webservice服务端的使用说明书,它说明服务、接口、方法、参数和返回值,它是伴随服务发布成功,而自动生成的,无需编写。
            文档结构:
                service
                binding
                portType
                message
                types
            阅读方式:从下往上
        SOAP:
            定义:SOAP即简单对象访问协议,它是使用http传输XML格式的数据,跨平台,跨防火墙,它不是webservice专有协议。
            Soap = http + xml
            协议的格式:
                必须项:envelope和body
                非必须项有:header和fault
        SOAP1.1和1.2区别
            相同点:
                都使用http的POST发送请求
                协议格式都相同:都有envelope和body标签
            不同点:
                Content-type不同:
                    SOAP1.1:text/xml; charset=utf-8;
                    SOAP1.2:application/soap+xml; charset=utf-8
                命名空间不同:
                    SOAP1.1:http://schemas.xmlsoap.org/soap/envelope/
                    SOAP1.2:http://www.w3.org/2003/05/soap-envelope

    Webservice的四种客户端调用方式
        生成客户端的调用方式
        Service编程的调用方式
        HttpURLConnecton调用方式
        Ajax调用方式

    深入开发:用注解修改WSDL内容
        @Webservice
        @WebMethod
        @WebParam
        @WebResult
    修改完WSDL之后,需要重新生成客户端代码。

    二、课程安排

    • CXF的介绍、安装和配置
    • 使用CXF发布SOAP1.1协议的服务
      • 使用CXF发布SOAP1.2协议的服务(了解一下)
    • CXF + Spring整合发布SOAP的服务
    • 使用CXF发布REST的服务(大企业中使用)
    • 什么是REST
    • CXF + Spring整合发布REST的服务
    • 综合案例:把公网的服务集成到自己开发的系统中,通过调用服务实现查询功能,再把我们做的查询功能发布成一个服务,让外界的人去调用。(背着写)

    三、CXF的介绍、安装和配置

    3.1、CXF的介绍

    Apache CXF = Celtix + Xfire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。

    Apache CXF 是一个开源的web Services 框架,CXF 帮助您快速构建和开发 web Services ,它支持多种协议,比如:SOAP1.1,1,2、XML/HTTP、RESTful HTTP 或者 CORBA。

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

    CXF是基于SOA总线结构,依靠spring完成模块的集成,实现SOA方式。

    灵活的部署:可以运行有Tomcat、Jboss、Jetty(内置)、Weblogic上面。
    • CXF是一个开源的webservice框架,提供很多完善功能,可以实现快速构建和开发。
    • CXF支持的协议:SOAP1.1/1.2、REST(今天要讲的)
    • CXF支持数据格式:XML、JSON(仅在REST方式下支持)

    3.2、CXF的安装及配置

    • 下载地址,建议下载最新版本:
      http://cxf.apache.org/download.html
    • 包结构介绍:
    • 安装和配置:
    • 第一步:安装JDK,建议1.8,安装成功界面
    • 第二步:解压 apache-cxf-3.2.6.zip 到指定目录,创建系统环境变量:CXF_HOME
    • 第三步:把CXF_HOME加入到Path路径下
    • 第四步:测试,在新的cmd命令行窗口下输入命令:wsdl2java –h,出现如下图所示界面,表示安装成功。
    • 如果不想使用IDE(比如:Eclipse),即手动创建项目的方式,需要在环境变量下配置如下信息:

    四、使用CXF发布SOAP1.1协议的服务

    4.1、需求

    • 服务端:发布服务,接收客户端的城市名,返回天气数据给客户端。
    • 客户端:发送城市名给服务端,接收服务端的响应信息,打印。

    4.2、实现-服务端

    开发步骤:
    第一步:导入jar包
    第二步:创建SEI接口,要在接口上加入注解:@WebService

    package com.itheima.webservice.cxf.server;

    import javax.jws.WebService;

    /*
     * SEI接口
     */

    @WebService
    public interface WeatherInterface {

        public String queryWeather(String cityName);
    }

    第三步:创建SEI实现类

    package com.itheima.webservice.cxf.server;

    /*
     * SEI实现类
     */

    public class WeatherInterfaceImpl implements WeatherInterface {

        @Override
        public String queryWeather(String cityName) {
            System.out.println("from client..." + cityName);
            if ("北京".equals(cityName)) {
                return "冷且霾";
            } else {
                return "暖且晴";
            }
        }
    }

    第四步:发布服务, 使用JaxWsServerFactoryBean发布服务,需要设置3个参数:1.服务接口; 2.服务实现类; 3.服务地址; Endpoint仅支持发布实现类,JaxWsServerFactoryBean支持发布接口。

    package com.itheima.webservice.cxf.server;

    import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

    /*
     * 发布服务端
     */

    public class WeatherServer {

        public static void main(String[] args) {
            /* JaxWsServerFactoryBean发布服务,需要设置3个参数:1.服务接口; 2.服务实现类;  3.服务地址;
               Endpoint仅支持发布实现类,JaxWsServerFactoryBean支持发布接口
            */

            // JaxWsServerFactoryBean发布服务
            JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
            // 设置服务接口
            jaxWsServerFactoryBean.setServiceClass(WeatherInterface.class);
            // 设置服务地址
            jaxWsServerFactoryBean.setAddress("http://127.0.0.1:12345/weather");    
            // 设置服务实现类
            jaxWsServerFactoryBean.setServiceBean(new WeatherInterfaceImpl());
            // 发布服务
            jaxWsServerFactoryBean.create();
        }
    }

    第五步:测试服务是否发布成功,阅读使用说明书,确定关键点。我们先启动服务端服务,如下图所示:


    如果在CXF发布的服务下,直接访问服务地址:http://127.0.0.1:12345/weather,会如下异常:

    此时直接访问使用说明书的地址即可:http://127.0.0.1:12345/weather?wsdl,如下图所示:

    4.3、使用CXF发布SOAP1.2协议的服务

    • 在接口上加入如下注解:
      @BindingType(SOAPBinding.SOAP12HTTP_BINDING)
    • 再重新发布服务端。注意:每次我们重新发布服务端的时候,端口都会被占用,需要我们手动结束任务,清理出端口来。

    4.4、CXF拦截器

    • CXF拦截器的原理:
      • 拦截器可以拦截请求和响应
      • 拦截器可以有多个
      • 拦截器可以根据需要自定义
    • CXF拦截器的使用:
      • 拦截器必须加到服务端,在服务端发布服务之前加入
      • 获取拦截器列表,将自己的拦截器加入列表中
    • CXF拦截器的应用场景:
      • 一般用于测试,比如:安全性方面:过滤非法请求、非法代码等
      • 但是一般情况下是不会用的,因为拦截器加上了之后会增加正式服务器的负载,影响性能,而且这些拦截器和业务逻辑是无关的
      • 一般情况下,拦截器会加到代理服务器上面,以后用或不用,是由经理来决定的

    示例代码如下:

    package com.itheima.webservice.cxf.server;

    import org.apache.cxf.interceptor.LoggingInInterceptor;
    import org.apache.cxf.interceptor.LoggingOutInterceptor;
    import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

    /*
     * 发布服务端
     */

    public class WeatherServer {

        public static void main(String[] args) {
            /* JaxWsServerFactoryBean发布服务,需要设置3个参数:1.服务接口; 2.服务实现类;  3.服务地址;
               Endpoint仅支持发布实现类,JaxWsServerFactoryBean支持发布接口
            */

            // JaxWsServerFactoryBean发布服务
            JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
            // 设置服务接口
            jaxWsServerFactoryBean.setServiceClass(WeatherInterface.class);
            // 设置服务地址
            jaxWsServerFactoryBean.setAddress("http://127.0.0.1:12345/weather");
            // 设置服务实现类
            jaxWsServerFactoryBean.setServiceBean(new WeatherInterfaceImpl());

            // 加入CXF拦截器
            jaxWsServerFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
            jaxWsServerFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());

            // 发布服务
            jaxWsServerFactoryBean.create();
        }
    }

    重新发布服务端和客户端,服务端控制台打印出的结果如下:

    ----------------------------
    ID: 1
    Address: http://127.0.0.1:12345/weather
    Encoding: UTF-8
    Http-Method: POST
    Content-Type: text/xml; charset=UTF-8
    Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[240], content-type=[text/xml; charset=UTF-8], Host=[127.0.0.1:12345], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache-CXF/3.2.6]}
    Payload:
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Body><ns2:queryWeather xmlns:ns2="http://server.cxf.webservice.itheima.com/">
            <arg0>山西省运城市永济市</arg0></ns2:queryWeather>
        </soap:Body>
    </soap:Envelope>
    --------------------------------------
    from client...山西省运城市永济市
    九月 22, 2018 12:18:05 上午 org.apache.cxf.services.WeatherInterfaceService.WeatherInterfacePort.WeatherInterface
    信息: Outbound Message
    ---------------------------
    ID: 1
    Response-Code: 200
    Encoding: UTF-8
    Content-Type: text/xml
    Headers: {}
    Payload: 
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Body><ns2:queryWeatherResponse xmlns:ns2="http://server.cxf.webservice.itheima.com/">
            <return>暖且晴</return></ns2:queryWeatherResponse>
        </soap:Body>
    </soap:Envelope>
    --------------------------------------

    4.5、实现-客户端

    • 第一步:生成客户端代码
    • wsdl2java命令是CXF提供的生成客户端的工具,它和wsimport类似,可以根据WSDL生成客户端代码。
      wsdl2java -p com.itheima.cxf.weather -d . http://127.0.0.1:12345/weather?wsdl
      演示效果如下图所示:
    • wsdl2java常用参数:
      • -d,指定客户端代码输出目录
      • -p,指定客户端代码输出包名,如果不指定该参数,默认包名是WSDL的命名空间的倒序
    • wsdl2java支持SOAP1.1和SOAP1.2协议的客户端生成。
    • 第二步:使用说明书,使用生成的客户端代码调用服务端
      • 先引入jar包
      • `使用JaxWsProxyFactoryBean调用服务端,设置2个参数:1.设置服务接口; 2.设置服务地址`

    示例代码如下:

    package com.itheima.cxf.weather.client;

    import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

    import com.itheima.cxf.weather.WeatherInterface;

    public class WeatherClient {

        public static void main(String[] args) {
            // JaxWsProxyFactoryBean调用服务端
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            // 设置服务接口
            jaxWsProxyFactoryBean.setServiceClass(WeatherInterface.class);
            // 设置服务地址
            jaxWsProxyFactoryBean.setAddress("http://127.0.0.1:12345/weather");
            // 获取服务接口实例
            WeatherInterface weatherInterface = jaxWsProxyFactoryBean.create(WeatherInterface.class);
            // 调用查询方法
            String weather = weatherInterface.queryWeather("山西省运城市永济市");

            System.out.println(weather);
        }
    }

    服务端效果截图如下:


    客户端效果截图如下:

    五、CXF + Spring整合发布SOAP协议的服务

    5.1、服务端-示例使用Web Project

    开发步骤:
    第一步:在MyEclipse中创建Web Project,之后在lib目录下引入jar包,然后添加至构建路径(在Eclipse中创建动态的Web Project)
    第二步:创建SEI接口
    第三步:创建SEI实现类
      我们可以直接拷贝之前没有整合Spring时的代码:创建SEI接口的代码和创建SEI实现类的代码。
      因为我们不在WeatherServer.java中发布服务端了,而是在Tomcat中发布服务端,所以我们需要删掉WeatherServer.java文件。
    第四步:整合Spring,配置spring配置文件,applicationContext.xml,在Spring中使用 <jaxws:server 标签来发布服务,该标签是对 JaxWsServerFactoryBean类 的封装,需要设置:1.设置服务地址;2.设置服务接口;3.设置服务实现类
    示例代码如下:
    applicationContext.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"
    >

        <!-- 在Spring中使用 <jaxws:server 标签来发布服务,该标签是对 JaxWsServerFactoryBean类 的封装 
             需要设置:1.设置服务地址;2.设置服务接口;3.设置服务实现类
             注意:这里面的“设置”都应该叫“配置”才更为恰当哦。
        -->

        <jaxws:server address="/weather" serviceClass="com.itheima.webservice.cxf.server.WeatherInterface">
            <!-- 配置服务实现类 -->
            <jaxws:serviceBean>
                <ref bean="WeatherInterfaceImpl"/>
            </jaxws:serviceBean>
        </jaxws:server>
        <!-- 配置服务实现类的bean -->
        <bean name="WeatherInterfaceImpl" class="com.itheima.webservice.cxf.server.WeatherInterfaceImpl"></bean>
    </beans>

    第五步:配置web.xml,配置spring配置文件地址和配置加载的listener,配置CXF的servlet
    示例代码如下:
    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">

        <display-name>day46_03_Webservice_cxf_spring_server</display-name>

        <!-- 配置web.xml,配置spring配置文件地址和配置加载的listener,配置CXF的servlet -->
        <!-- 配置spring配置文件地址 -->
        <context-param>
            <!-- 注意:contextConfigLocation 这个是不能修改的  -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
        <!-- 配置加载的listener -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!-- 配置CXF的servlet:是因为服务端需要接收http请求 -->
        <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>/ws/*</url-pattern><!-- 路径映射 -->
            <!-- <url-pattern>*.action</url-pattern>扩展映射 -->
        </servlet-mapping>

        <welcome-file-list>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

    第六步:部署到tomcat下,启动tomcat
    注意:启动tomcat时控制台会出现一个错误: Error configuring application listener of class [org.springframework.web.context.ContextLoaderListener],如下图所示:


    解决办法:
    右击项目点击“Properties”,然后会出现一个弹框,弹框中找到“Deployment Assembly” 点击,如下图所示:

    然后点击“Add” 出现如下图:

    选择 Jave Build Path Entries,把程序用于的Library加入进来,如下图所示:

    加入成功后的截图如下:

    重新运行Server,即重新启动tomcat,控制台看不到这个问题了!噢耶

    第七步:测试服务,阅读使用说明书
    WSDL地址规则:http://ip:端口号/项目名称/servlet拦截路径/服务名称?wsdl
    例如:http://127.0.0.1:8080/day46_03_Webservice_cxf_spring_server/webservice/weather?wsdl
    效果截图如下:


    说明界面地址:http://ip:端口号/项目名称/servlet拦截路径
    例如:http://127.0.0.1:8080/day46_03_Webservice_cxf_spring_server/webservice
    说明界面如下图所示:

    5.2、配置CXF拦截器

    需要在 applicationContext.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"
    >

        <!-- 在Spring中使用 <jaxws:server 标签来发布服务,该标签是对 JaxWsServerFactoryBean类 的封装 
               需要设置:1.设置服务地址;2.设置服务接口;3.设置服务实现类
               注意:这里面的“设置”都应该叫“配置”才更为恰当哦。
        -->

        <jaxws:server address="/weather" serviceClass="com.itheima.webservice.cxf.server.WeatherInterface">
            <!-- 配置服务实现类 -->
            <jaxws:serviceBean>
                <ref bean="WeatherInterfaceImpl"/>
            </jaxws:serviceBean>
            <!-- 配置CXF拦截器 -->
            <jaxws:inInterceptors>
                <ref bean="inInterceptor"/>
            </jaxws:inInterceptors>
            <jaxws:outInterceptors>
                <ref bean="outInterceptor"/>
            </jaxws:outInterceptors>
        </jaxws:server>
        <!-- 配置服务实现类的bean -->
        <bean name="WeatherInterfaceImpl" class="com.itheima.webservice.cxf.server.WeatherInterfaceImpl"></bean>
        <!-- 配置CXF拦截器的bean -->
        <bean name="inInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
        <bean name="outInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
    </beans>

    重启Tomcat,没有报错,CXF拦截器配置成功。

    5.3、使用Endpoint标签发布服务

    使用<jaxws:endpoint>标签
    示例代码如下:

    package com.itheima.webservice.cxf.server;

    import javax.jws.WebService;

    /*
     * 简单类 
     * 
     * 因为使用Endpoint标签发布服务,是不需要接口的
     */


    @WebService // @WebService表示该类是一个服务类,需要发布其中的public的方法,即我想把它发布成一个服务
    public class HelloWorld {

        public String sayHello(String name) {
            return "hello," + name;
        }
    }

    application.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"
    >

        <!-- 在Spring中使用 <jaxws:endpoint 标签来发布服务,该标签是对 Endpoint类 的封装 
               需要设置:1.设置服务地址;2.设置服务实现类
               注意:这里面的“设置”都应该叫“配置”才更为恰当哦。
        -->
                         
        <jaxws:endpoint address="/hello" implementor="com.itheima.webservice.cxf.server.HelloWorld"></jaxws:endpoint>

        <!-- 在Spring中使用 <jaxws:server 标签来发布服务,该标签是对 JaxWsServerFactoryBean类 的封装 
               需要设置:1.设置服务地址;2.设置服务接口;3.设置服务实现类
               注意:这里面的“设置”都应该叫“配置”才更为恰当哦。
        -->

        <jaxws:server address="/weather" serviceClass="com.itheima.webservice.cxf.server.WeatherInterface">
            <!-- 配置服务实现类 -->
            <jaxws:serviceBean>
                <ref bean="WeatherInterfaceImpl"/>
            </jaxws:serviceBean>
            <!-- 配置CXF拦截器 -->
            <jaxws:inInterceptors>
                <ref bean="inInterceptor"/>
            </jaxws:inInterceptors>
            <jaxws:outInterceptors>
                <ref bean="outInterceptor"/>
            </jaxws:outInterceptors>
        </jaxws:server>
        <!-- 配置服务实现类的bean -->
        <bean name="WeatherInterfaceImpl" class="com.itheima.webservice.cxf.server.WeatherInterfaceImpl"></bean>
        <!-- 配置CXF拦截器的bean -->
        <bean name="inInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
        <bean name="outInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
    </beans>

    然后重新启动tomcat,没有报错,表示成功!
    再次访问:http://127.0.0.1:8080/day46_03_Webservice_cxf_spring_server/webservice/weather?wsdl
    新的效果截图如下:


    再次访问:http://127.0.0.1:8080/day46_03_Webservice_cxf_spring_server/webservice
    新的说明界面如下图所示:

    5.4、客户端-示例使用Java Project

    开发步骤:
    第一步:引入jar包
    第二步:生成客户端代码
    第三步:配置spring配置文件,applicationContent.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"
    >
                         
        <!-- 在Spring中使用 <jaxws:client 标签来实现客户端,该标签是对 JaxWsProxyFactoryBean类 的封装 
             需要设置:1.设置服务地址;2.设置服务接口
             注意:这里面的“设置”都应该叫“配置”才更为恰当哦。
        -->

        <jaxrs:client id="weatherClient" address="http://127.0.0.1:8080/day46_03_Webservice_cxf_spring_server/webservice/weather" serviceClass="com.itheima.cxf.weather.WeatherInterface"></jaxrs:client>
    </beans>

    第四步:从spring的上下文中获取服务实现类
    第五步:调用查询方法,打印
    客户端代码示例如下:
    WeatherClient.java

    package com.itheima.cxf.weather.client;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.itheima.cxf.weather.WeatherInterface;

    public class WeatherClient {

        public static void main(String[] args) {
            // 初始化Spring的上下文
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
            WeatherInterface  weatherInterface  = (WeatherInterface) context.getBean("weatherClient");
            String weather = weatherInterface.queryWeather("山西省运城市永济市");
            System.out.println(weather);
        }
    }

    运行服务端代码,没有报错,成功!
    客户端控制台截图如下所示:


    服务端控制台截图如下所示:

    六、回顾上午所学

    CXF的介绍、安装和配置
        CXF是一个开源的webservice的框架,提供很多成熟的功能,可以实现快速开发
        CXF支持的协议:SOAP1.1/1.2,REST
        CXF支持的数据格式:XML,JSON
    安装和配置
        安装JDK,建议1.8
        解压cxf压缩包到指定目录,配置CXF_HOME
        CXF_HOME加入Path中
        测试成功,在cmd中输入wsdl2java –h

    使用CXF发布SOAP协议的服务
    服务端
        第一步:引入jar包
        第二步:创建SEI接口,要在`接口`上加入注解:@WebService
        第三步:创建SEI实现类
        第四步:发布服务,使用JaxWsServerFactoryBean发布服务,设置3个参数,1.服务接口; 2.服务实现类; 3.服务地址
        第五步:测试服务

    客户端
        第一步:引入jar包
        第二步:生成客户端代码
        第三步:使用JaxWSProxyFactoryBean调用服务端,设置2个参数,1.服务接口;2.服务地址
        第四步:获取实现类的实例,调用查询方法

    CXF + Spring整合发布SOAP协议的服务
    服务端
        第一步:在MyEclipse中创建Web Project,之后在lib目录下引入jar包,然后添加至构建路径(在Eclipse中创建 动态的Web Project)
        第二步:创建SEI接口
        第三步:创建SEI实现类
        第四步:配置Spring配置文件,applicationContext.xml,`使用<jaxws:server>标签`
        第五步:配置web.xml,配置spring配置文件地址和配置加载的listener,以及CXF的servlet
        第六步:部署tomcat下,启动tomcat
        第七步:测试服务是否发布成功
            WSDL地址规则:http://ip:端口号/项目名称/servlet拦截路径/服务名称?wsdl

    客户端
        第一步:引入jar包
        第二步:生成客户端代码
        第三步:配置spring的配置文件,applicationContext.xml,`使用<jaxws:client>标签`
        第四步:初始化spring上下文,获取接口实现类,调用查询方法

    七、使用CXF发布REST的服务(大企业中使用)

    7.1、什么是REST

    REST 是一种软件架构模式,只是一种风格,,REST服务采用 HTTP 做传输协议,REST 对于 HTTP 的利用实现精确的资源定位。

    Rest要求对资源定位更加准确,如下:
        非rest方式:http://ip:port/queryUser.action?userType=student&id=001
        Rest方式:http://ip:port/user/student/query/001
        Rest方式表示互联网上的资源更加准确,但是也有缺点,可能目录的层级较多不容易理解。

        REST 是一种软件架构理念,现在被移植到Web服务上,那么在开发Web服务上,偏于面向资源的服务适用于REST。
        REST简单易用,效率高(不用生成客户端)。
        SOAP 成熟度较高,安全性较好。

        注意:REST 不等于WebService,JAX-RS 只是将REST 设计风格应用到Web 服务开发上。    
    • 定义:REST就是一种编程风格,它可以精确定位网上资源(服务接口、方法、参数)。
    • REST支持数据格式:XML、JSON
    • REST支持发送方式:GET、POST

    7.2、需求

    • 第一个:查询单个学生
    • 第二个:查询多个学生

    7.3、实现-服务端

    开发步骤:
    第一步:导入jar包
    第二步:创建学生pojo类,要在类上加入注解:@ XmlRootElement
    示例代码如下:

    package com.itheima.cxf.rest.pojo;

    import java.util.Date;

    import javax.xml.bind.annotation.XmlRootElement;

    /*
     * 学生实体类
     */

    @XmlRootElement(name="student"// 该注解 @XmlRootElement 可以实现对象和XML数据之间的转换
    public class Student {

        private long id;

        private String name;

        private Date birthday;

        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Date getBirthday() {
            return birthday;
        }

        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    }

    第三步:创建SEI接口
    示例代码如下:

    package com.itheima.cxf.rest.server;

    import java.util.List;

    import javax.jws.WebService;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;

    import com.itheima.cxf.rest.pojo.Student;

    /*
     * 学生接口
     */

    @WebService         // @WebService 作用是:标识这个类是服务类,要发布里面的public方法。
    @Path("/student")    // @Path("/student") 作用是:将请求路径中的“/student”映射到接口上
    public interface StudentInterface {
        // 查询单个学生
        @GET // 指定请求方式,如果服务端发布的时候指定的是GET(POST),那么客户端访问时必须使用GET(POST)
        @Produces(MediaType.APPLICATION_XML) // 指定服务的数据类型
        @Path("/query/{id}") // @Path("/query/{id}") 作用是:将“/query”映射到方法上,将“{id}”映射到参数上,如果是多个参数,以“/”隔开,放到“{}”中
        // 查询单个学生
        public Student query(@PathParam("id")long id);

        @GET // 指定请求方式,如果服务端发布的时候指定的是GET(POST),那么客户端访问时必须使用GET(POST)
        @Produces(MediaType.APPLICATION_XML) // 指定服务的数据类型
        // @Produces("application/json; charset=utf-8") // 指定服务的数据类型
        @Path("/queryList/{name}") // @Path("/queryList/{name}") 作用是:将“/query”映射到方法上,将“{name}”映射到参数上,如果是多个参数,以“/”隔开,放到“{}”中
        // 查询多个学生
        public List<Student> queryList(@PathParam("name")String name);
    }

    第四步:创建SEI实现类
    示例代码如下:

    package com.itheima.cxf.rest.server;

    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;

    import com.itheima.cxf.rest.pojo.Student;

    /*
     * 学生的实现类
     */

    public class StudentInterfaceImpl implements StudentInterface {

        @Override
        public Student query(long id) {
            Student st = new Student();
            st.setId(110);
            st.setName("张三");
            st.setBirthday(new Date());
            return st;
        }

        @Override
        public List<Student> queryList(String name) {
            Student st = new Student();
            st.setId(110);
            st.setName("张三");
            st.setBirthday(new Date());

            Student st2 = new Student();
            st2.setId(120);
            st2.setName("李四");
            st2.setBirthday(new Date());

            List<Student> list = new ArrayList<Student>();
            list.add(st);
            list.add(st2);
            return list;
        }
    }

    第五步:发布服务, 使用JAXRSServerFactoryBean发布REST服务,发布前,需要设置3个参数,1.设置服务实现类;2.设置资源类;3.设置服务地址,然后我们启动服务端服务
    示例代码如下:

    package com.itheima.cxf.rest.server;

    import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;

    public class StudentServer {
        public static void main(String[] args) {
            // 使用 JAXRSServerFactoryBean 发布REST的服务
            JAXRSServerFactoryBean jaxRSServerFactoryBean = new JAXRSServerFactoryBean();
            // 设置服务实现类
            jaxRSServerFactoryBean.setServiceBean(new StudentInterfaceImpl());
            // 设置服务资源类,如果有多个资源类,可以以“,”隔开。
            jaxRSServerFactoryBean.setResourceClasses(StudentInterfaceImpl.class);
            // 设置服务地址
            jaxRSServerFactoryBean.setAddress("http://127.0.0.1:12345/user");
            // 发布服务
            jaxRSServerFactoryBean.create();
        }
    }

    第六步:测试服务

    1、访问服务地址:http://127.0.0.1:12345/user/student/query/110
    查询单个学生,返回XML数据,如下图所示:

    2、访问服务地址:http://127.0.0.1:12345/user/student/query/110
    查询单个学生,返回JSON数据,如下图所示:
    需要先修改学生接口中配置的注解为@Produces(MediaType.APPLICATION_JSON),之后再重新发布服务

    3、访问服务地址:http://127.0.0.1:12345/user/student/queryList/110
    查询多个学生,返回XML数据,如下图所示:

    4、访问服务地址:http://127.0.0.1:12345/user/student/queryList/110
    查询多个学生,返回JSON数据,如下图所示:
    需要先修改学生接口中配置的注解为@Produces(MediaType.APPLICATION_JSON),之后再重新发布服务

    注意事项:

    • 如果服务端发布时指定请求方式是GET(POST),客户端必须使用GET(POST)访问服务端,否则会报如下异常:
    • 如果在同一方法上同时指定XML和JSON媒体类型,在GET请求下,默认返回XML数据,在POST请求下,默认返回JSON数据。
      • 可以通过:
      • `http://127.0.0.1:12345/user/student/queryList/110?_type=json` 或者
      • `http://127.0.0.1:12345/user/student/queryList/110?_type=xml`进行切换

    7.4、实现-客户端

    REST服务不用生成客户端代码,因为服务端返回来的就是XML数据或者JSON数据,我们只需要通过URL就能拿到数据进行解析就可以了,所以不需要生成客户端代码了。那么如何解析URL呢?方式一:使用dom4j框架。

    可以自学一下httpclient框架,该框架是专门发送Http请求,然后从URL中获取数据的框架。自学网址:http://hc.apache.org/httpclient-3.x/

    今天我们不使用httpclient框架,还是使用HttpURLConnection调用方式实现服务端调用
    示例代码如下:

    package com.itheima.cxf.rest.client;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;

    /*
     * HttpURLConnection调用方式实现服务端调用
     */

    public class HttpClient {

        public static void main(String[] args) throws IOException {
            // 第一步:创建服务地址,注意:不是WSDL地址
            URL url = new URL("http://127.0.0.1:12345/user/student/query/110");
            // 第二步:打开一个通向服务地址的连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 第三步:设置参数
            // 设置POST,POST必须大写,如果不大写,报如下异常:
            // 3.1、设置发送方式:POST必须大写
            connection.setRequestMethod("POST");
            // 3.2、设置数据格式:content-type
            // connection.setRequestProperty("content-type", "text/xml;charset=utf-8");
            // 3.3、设置输入输出:因为默认新创建的connection没有读写权限
            connection.setDoInput(true);
            // connection.setDoOutput(true);
            // 如果不设置输入输出,会报如下异常:
            // 第四步:组织SOAP数据,发送请求
            // String soapXML = getXML("13651311090");
            // OutputStream os = connection.getOutputStream();
            // os.write(soapXML.getBytes());
            // 第五步:接收服务端响应,打印
            int responseCode = connection.getResponseCode();
            if (200 == responseCode) { // 表示服务端响应成功
                InputStream is = connection.getInputStream();
                InputStreamReader isr = new InputStreamReader(is); // 由于字节流容易出现乱码,所以把字节流转换为字符流
                BufferedReader br = new BufferedReader(isr); // 为了高效,装饰一把,装饰设计模式

                StringBuilder sb = new StringBuilder();
                String temp = null;
                while (null != (temp = br.readLine())) {
                    sb.append(temp);
                }
                System.out.println(sb.toString());
                // 使用dom4j解析返回的xml数据,课下作业
                // ......

                // 从里往外关流
                is.close();
                isr.close();
                br.close();
            }
            // os.close();
        }

    /*    public static String getXML(String phoneNum) {
            String soapXML = "<?xml version="1.0" encoding="utf-8"?>" 
            + "<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">" 
                + "<soap:Body>" 
                + "<getMobileCodeInfo xmlns="http://WebXml.com.cn/">" 
                    + "<mobileCode>" + phoneNum + "</mobileCode>" 
                  + "<userID></userID>" 
                + "</getMobileCodeInfo>" 
              + "</soap:Body>" 
            + "</soap:Envelope>";
            return soapXML;
        }*/

    }

    八、CXF + Spring整合发布REST的服务

    8.1、服务端-示例使用Web Project

    开发步骤:
    第一步:创建Web Project项目(引入jar包)
    第二步:创建POJO类
    第三步:创建SEI接口
    第四步:创建SEI实现类
    第五步:配置Spring配置文件,applicationContext.xml,使用 <jaxrs:server> 标签,需要设置2个参数:1.服务地址;2.服务实现类
    示例代码如下:

    <?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"
    >
                                     
        <!-- 在Spring中使用 <jaxrs:server 标签来发布REST服务,该标签是对 JAXRSServerFactoryBean类 的封装 
               需要设置:1.设置服务地址;2.设置服务实现类
               注意:这里面的“设置”都应该叫“配置”才更为恰当哦。
        -->

        <jaxrs:server address="/user">
            <jaxrs:serviceBeans>
                <ref bean="studentInterface"/>
            </jaxrs:serviceBeans>
        </jaxrs:server>
        <!-- 配置服务实现类 -->
        <bean name="studentInterface" class="com.itheima.cxf.rest.server.StudentInterfaceImpl"></bean>
    </beans>

    第六步:配置web.xml
    示例代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">

        <display-name>day46_07_Webservice_cxf_rest_spring_server</display-name>

        <!-- 配置web.xml,配置spring配置文件地址和配置加载的listener,配置CXF的servlet -->
        <!-- 配置spring配置文件地址 -->
        <context-param>
            <!-- 注意:contextConfigLocation 这个是不能修改的  -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
        <!-- 配置加载的listener -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!-- 配置CXF的servlet:是因为服务端需要接收http请求 -->
        <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>/webservice/*</url-pattern><!-- 路径映射 -->
            <!-- <url-pattern>*.action</url-pattern>扩展映射 -->
        </servlet-mapping>

        <welcome-file-list>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

    第七步:将项目部署到tomcat下,启动tomcat,控制台没有报错即可。
    第八步:测试服务
    REST服务的使用说明书地址:http://127.0.0.1:8080/day46_07_Webservice_cxf_rest_spring_server/webservice/user?_wadl ,如下图所示:

    8.2、客户端-示例使用Java Project,使用ajax调用方式

    示例代码如下:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script type="text/javascript">
            function queryStudent() {
                // 创建XMLHttpRequest对象
                var xhr = new XMLHttpRequest();
                // 打开连接
                xhr.open("get""http://127.0.0.1:8080/day46_07_Webservice_cxf_rest_spring_server/webservice/user/student/queryList/110?_type=json"true);
                // 设置数据类型
                // xhr.setRequestHeader("content-type", "text/xml;charset=utf-8");
                // 设置回调函数
                xhr.onreadystatechange=function() {
                    // 判断是否发送成功和判断服务端是否响应成功
                    if (4 == xhr.readyState && 200 == xhr.status) {
                        alert(eval("(" + xhr.responseText + ")").student[0].name);
                    }
                }
    //             // 组织SOAP协议数据
    //             var soapXML = "<?xml version="1.0" encoding="utf-8"?>"
    //             + "<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">"
    //                 + "<soap:Body>"
    //                 + "<getMobileCodeInfo xmlns="http://WebXml.com.cn/">"
    //                     + "<mobileCode>" + document.getElementById("phoneNum").value + "</mobileCode>"
    //                   + "<userID></userID>"
    //                 + "</getMobileCodeInfo>"
    //               + "</soap:Body>"
    //             + "</soap:Envelope>";
    //             alert(soapXML);
                // 发送数据
                xhr.send(null);
            }
        
    </script>
    </head>
    <body>
        <input type="button" value="学生查询" onclick="javascript:queryStudent();"/>
    </body>
    </html>

    演示效果如下图所示:

    九、综合案例

    9.1、需求

    • 集成(调用)公网手机号归属地查询服务
    • 对外发布自己的手机号归属地查询服务
    • 提供查询界面

    9.2、分析

    9.3、实现

    开发步骤:
    第一步:创建Web Project项目(引入jar包)
    第二步:生成公网客户端代码
    第三步:创建SEI接口
    示例代码如下:

    package com.itheima.mobile.server;

    import javax.jws.WebService;

    /*
     * SEI接口
     */

    @WebService    // 该注解的作用是:标识这个类是服务类,要发布里面的public方法。
    public interface MobileInterface {
        public String queryMobile(String phoneNum);
    }

    第四步:创建SEI实现类,因为最后我们调用公网客户端代码的时候,调用的是服务接口中的实现类,所以我们要把公网客户端的服务接口给注入进来。公网客户端的服务接口为:MobileCodeWSSoap
    示例代码如下:

    package com.itheima.mobile.server;

    import com.itheima.mobile.MobileCodeWSSoap;

    /*
     * SEI实现类
     *         因为最后我们调用公网客户端代码的时候,调用的是服务接口中的实现类,所以我们要把公网客户端的服务接口给注入进来。
     *         公网客户端的服务接口为:MobileCodeWSSoap
     */

    public class MobileInterfaceImpl implements MobileInterface {

        private MobileCodeWSSoap mobileClient;

        public MobileCodeWSSoap getMobileClient() {
            return mobileClient;
        }

        public void setMobileClient(MobileCodeWSSoap mobileClient) {
            this.mobileClient = mobileClient;
        }

        @Override
        public String queryMobile(String phoneNum) {
            return mobileClient.getMobileCodeInfo(phoneNum, "");
        }
    }

    第五步:创建queryMobile.jsp
    示例代码如下:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>

    <!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>手机号归属地查询网站</title>
    </head>
    <body>
        <form action="queryMobile.action" method="post">
            手机号归属地查询:<input type="text" name="phoneNum"/><input type="submit" value="查询"><br/>
            查询结果:${result}
        </form>
    </body>
    </html>

    第六步:创建MobileServlet.java
    示例代码如下:

    package com.itheima.mobile.server.servlet;

    import java.io.IOException;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.springframework.context.ApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;

    import com.itheima.mobile.server.MobileInterface;

    public class MobileServlet extends HttpServlet {

        private MobileInterface mobileServer;

        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String phoneNum = request.getParameter("phoneNum");
            if (null != phoneNum && "".equals(phoneNum)) {
                // 通过Spring上下文初始化mobileServer
                ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
                mobileServer = (MobileInterface) context.getBean("mobileServer");

                String result = mobileServer.queryMobile(phoneNum);
                request.setAttribute(result, "result");
            }
            // 跳转页面
            request.getRequestDispatcher("/WEB-INF/jsp/queryMobile.jsp").forward(request, response);;
        }

        @Override
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    第七步:配置spring配置文件,applicationContext.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"
    >
                         
        <!-- 在Spring中使用 <jaxws:server 标签来来发布服务,该标签是对JaxWsServerFactoryBean类 的封装 
               需要设置:1.设置服务地址;2.设置服务接口;3.设置服务实现类
               注意:这里面的“设置”都应该叫“配置”才更为恰当哦。
        -->

        <jaxws:server address="/mobile" serviceClass="com.itheima.mobile.server.MobileInterface">
            <!-- 配置服务实现类 -->
            <jaxws:serviceBean>
                <ref bean="mobileServer"/>
            </jaxws:serviceBean>
        </jaxws:server>
        <!-- 配置服务实现类的bean,并注入 -->
        <bean name="mobileServer" class="com.itheima.mobile.server.MobileInterfaceImpl">
            <property name="mobileClient" ref="mobileClient"></property>
        </bean>

        <!-- 配置公网客户端 -->
        <jaxws:client id="mobileClient" address="http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx" serviceClass="com.itheima.mobile.MobileCodeWSSoap"></jaxws:client>
    </beans>

    第八步:配置web.xml
    示例代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">

        <display-name>day46_09_Webservice_eg_mobile</display-name>
        <!-- 配置web.xml,配置spring配置文件地址和配置加载的listener,配置CXF的servlet -->
        <!-- 配置spring配置文件地址 -->
        <context-param>
            <!-- 注意:contextConfigLocation 这个是不能修改的 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
        <!-- 配置加载的listener -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

        <!-- 配置CXF的servlet:是因为服务端需要接收http请求 -->
        <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>/webservice/*</url-pattern><!-- 路径映射 -->
            <!-- <url-pattern>*.action</url-pattern>扩展映射 -->
        </servlet-mapping>

        <!-- 配置mobileServlet -->
        <servlet>
            <servlet-name>mobileServlet</servlet-name>
            <servlet-class>com.itheima.mobile.server.servlet.MobileServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>mobileServlet</servlet-name>
            <url-pattern>*.action</url-pattern>
        </servlet-mapping>

        <welcome-file-list>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

    第九步:将项目部署到tomcat下,启动tomcat
    第十步:测试
    测试服务是否发布成功,访问地址:http://127.0.0.1:8080/day46_09_Webservice_eg_mobile/webservice,如下图所示:


    点击WSDL地址:http://127.0.0.1:8080/day46_09_Webservice_eg_mobile/webservice/mobile?wsdl,查看上下文,没有问题。如下图所示:

    测试查询界面,查询网址:http://127.0.0.1:8080/day46_09_Webservice_eg_mobile/queryMobile.action,如下图所示:

    查询结果截图如下:

    查询结果截图如下:
  • 相关阅读:
    剑指 Offer 56 II. 数组中数字出现的次数 II
    剑指 Offer 57 II. 和为s的连续正数序列
    剑指 Offer 63. 股票的最大利润
    剑指 Offer 55 II. 平衡二叉树
    剑指 Offer 59 II. 队列的最大值
    剑指 Offer 57. 和为s的两个数字
    剑指 Offer 64. 求1+2+…+n
    239. 滑动窗口最大值
    剑指 Offer 58 I. 翻转单词顺序
    剑指 Offer 60. n个骰子的点数
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/9692658.html
Copyright © 2020-2023  润新知