Giter VIP home page Giter VIP logo

webservice's Introduction

webservice笔记

XML(Extensible Markup Language) :扩展型可标记语言。面向短期的临时数据处理、面向万维网络,是Soap的基础。

SOAP(Simple Object Access Protocol) :简单对象存取协议。是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。

WSDL(Web Services Description Language) :WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。

UDDI (Universal Description, Discovery, and Integration)通用描述、发现与集成服务,是一个主要针对Web服务供应商和使用者的新项目。在用户能够调用Web服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服务端来编制软件,UDDI是一种根据描述文档来引导系统查找相应服务的机制。UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

什么是webservice?

类似RPC,或者说是RPC的一种实现,可以在网上调用其他人提供的服务。是一种跨平台,跨语言的规范,用于不同平台,不同语言开发的应用之间的交互(远程调用技术)。通过SOAP 在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。

如你现在要调别人的服务,可以通过UDDI找到对应的WSDL查看对应的服务,需要什么参数,有什么返回结果等,通过SOAP调用你的服务。

为什么要学习web service?

大多数对外接口会实现web service方法而不是http方法,如果你不会,那就没有办法对接。

web service相对http (post/get)有好处,区别吗?

  • 接口中实现的方法和要求参数一目了然
  • 不用担心大小写问题
  • 不用担心中文urlencode问题
  • 代码中不用多次声明认证(账号,密码)参数
  • 传递参数可以为数组,对象等...
  • httpservice通过post和get得到你想要的东西
  • webservice就是使用soap协议得到你想要的东西,相比httpservice能处理些更加复杂的数据类型
  • http协议传输的都是字符串了,webservice则是包装成了更复杂的对象。
  1. webservice走HTTP协议和8
  2. 而你说的api,用的协议和端口,是根据开发人员定义的。
  3. 这么说吧,api类似于cs架构,需要同时开发客户端API和服务器端程序。
  4. 而WebService则类似于bs架构,只需要开发服务器端,不需要开发客户端,客户端只要遵循soap协议,就可以调用。

webservice解决了什么问题?

  • 异构系统之间的通信
  • 一些公共资源的调用

使用jdk的方式(jws)发布webservice服务

1、定义一个查询天气的服务接口

public interface IWeatherService {
    
    String query(String cityName);
}

2、接口实现类

@WebService
public class IWeatherServiceImpl implements IWeatherService {
    @Override
    public String query(String cityName) {
        Random random = new Random();
        int n = random.nextInt(3);
        String weather = n==2? "晴天":n==1?"阴天":"暴雨";
        System.out.println("查询-> "+cityName+" 的天气为:"+weather);
        return weather;
    }
}

3、通过jws发布

public class Main {
    public static void main(String[] args) {
        Endpoint.publish("http://localhost:8080/weatherService",new IWeatherServiceImpl());
        System.out.println("发布成功");
    }
}

4、在浏览器上通过http://localhost:8080/weatherService?wsdl 就可以查看相关的wsdl文档

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<!--
 Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<!--
 Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webservice.lcdiao.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://webservice.lcdiao.cn/" name="IWeatherServiceImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://webservice.lcdiao.cn/" schemaLocation="http://localhost:8080/weatherService?xsd=1"/>
</xsd:schema>
</types>
<message name="query">
<part name="parameters" element="tns:query"/>
</message>
<message name="queryResponse">
<part name="parameters" element="tns:queryResponse"/>
</message>
<portType name="IWeatherServiceImpl">
<operation name="query">
<input wsam:Action="http://webservice.lcdiao.cn/IWeatherServiceImpl/queryRequest" message="tns:query"/>
<output wsam:Action="http://webservice.lcdiao.cn/IWeatherServiceImpl/queryResponse" message="tns:queryResponse"/>
</operation>
</portType>
<binding name="IWeatherServiceImplPortBinding" type="tns:IWeatherServiceImpl">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="query">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="IWeatherServiceImplService">
<port name="IWeatherServiceImplPort" binding="tns:IWeatherServiceImplPortBinding">
<soap:address location="http://localhost:8080/weatherService"/>
</port>
</service>
</definitions>

通过wsdl文档里的http://localhost:8080/weatherService?xsd=1去查看相关的方法信息

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<!--
 Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<xs:schema xmlns:tns="http://webservice.lcdiao.cn/" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://webservice.lcdiao.cn/">
<xs:element name="query" type="tns:query"/>
<xs:element name="queryResponse" type="tns:queryResponse"/>
<xs:complexType name="query">
<xs:sequence>
<xs:element name="arg0" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="queryResponse">
<xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>

总结

**目标:**通过JDK来发布webservice服务

步骤:

  1. 创建接口
  2. 创建实现类 + @WebService
  3. 发布服务 Endpoint.publish("http://localhost:8080/weatherService",new IWeatherServiceImpl());

创建客户端调用刚发布的服务(方案一)

进到创建的java项目目录下 (如:D:\GitHub\webservice\webservice_client_1\src),

使用命令 : wsimport -s . http://localhost:8080/weatherService?wsdl

cmd窗口如下:

D:\GitHub\webservice\webservice_client_1\src>wsimport -s . http://localhost:8080/weatherService?wsdl
正在解析 WSDL...



正在生成代码...


正在编译代码...


src目录下生成的对象如下:

wsimport生成的类

调用发布的webservice服务

public class Client {
    public static void main(String[] args) {
        //1、创建服务视图对象(视图是从service标签的name属性获取 --->    <service name="IWeatherServiceImplService">)
        IWeatherServiceImplService service = new IWeatherServiceImplService();
        //2、获取服务的实现类(实现类从portType标签的name属性获取    --->    <portType name="IWeatherServiceImpl">)
        IWeatherServiceImpl port = service.getPort(IWeatherServiceImpl.class);
        //3、调用方法(从portType的operation标签获取    --->    <operation name="query">   query就是方法名)
        String query = port.query("广州");
        //输出返回结果
        System.out.println(query);
    }
}

总结

目标:通过编程来访问webservice服务

步骤:

  1. 生成客户端代码 wsimport
  2. 查看服务的说明书 http://localhost:8080/weatherService?wsdl
  3. 按照服务的说明书来编程 关键节点: 服务视图实现类的名称 ​ 要调用的方法

创建客户端调用刚发布的服务(方案二)

进到创建的java项目目录下 (如:D:\GitHub\webservice\webservice_client_2\src),

使用命令 : wsimport -s . http://localhost:8080/weatherService?wsdl

调用发布的webservice服务

public class Client {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/weatherService?wsdl");
        //在<definitions 标签下找到 targetNamespace="http://webservice.lcdiao.cn/" name="IWeatherServiceImplService" 这两个属性
        QName qName = new QName("http://webservice.lcdiao.cn/","IWeatherServiceImplService");
        //相当于上一种的底层实现
        Service service = Service.create(url, qName);

        IWeatherServiceImpl port = service.getPort(IWeatherServiceImpl.class);
        String query = port.query("深圳");
        System.out.println(query);
    }
}

创建客户端调用网上发布的服务

国内手机号码归属地查询

  1. 通过服务的服务地址,来生成客户端代码 使用命令 : wsimport -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL

  2. 编写代码调用服务

    public class Client {
        public static void main(String[] args) {
            //1、创建一个服务视图
            MobileCodeWS mobileCodeWS = new MobileCodeWS();
            //2、根据服务视图创建对应的实现类
            MobileCodeWSSoap mobileCodeWSSoap = mobileCodeWS.getMobileCodeWSSoap();
            //3、调用方法 (查看文档)
            //获得国内手机号码归属地数据库信息    输入参数:无;返回数据:一维字符串数组(省份 城市 记录数量)。
            ArrayOfString databaseInfo = mobileCodeWSSoap.getDatabaseInfo();
            //获得国内手机号码归属地省份、地区和手机卡类型信息  输入参数:mobileCode = 字符串(手机号码,最少前7位数字),userID = 字符串(商业用户ID) 免费用户为空字符串;返回数据:字符串(手机号码:省份 城市 手机卡类型)。
            String mobileCodeInfo = mobileCodeWSSoap.getMobileCodeInfo("15876161217", "");
            //4、输出返回结果
            System.out.println(databaseInfo.getString());
            System.out.println(mobileCodeInfo);
        }
    }

天气预报查询

1、通过服务的服务地址,生成客户端代码 使用命令 : wsimport -s . http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL 命令窗口会报错!

正在解析 WSDL...


[WARNING] src-resolve.4.2: 解析组件 's:schema' 时出错。在该组件中检测到 's:schema' 位于名称空间 'http://www.w3.org/2001/XMLSchema' 中, 但无法从方案文档 'http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL#types?schema1' 引用此名称空间的组件。如果这是不正确的名称空间, 则很可能需要更改 's:schema' 的前
缀。如果这是正确的名称空间, 则应将适当的 'import' 标记添加到 'http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL#types?schema1'。
  http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL#types?schema1的第 15 行

[WARNING] src-resolve: 无法将名称 's:schema' 解析为 'element declaration' 组件。
  http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL#types?schema1的第 15 行

[ERROR] undefined element declaration 's:schema'
  http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL的第 15 行

[ERROR] undefined element declaration 's:schema'
  http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL的第 61 行

[ERROR] undefined element declaration 's:schema'
  http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL的第 101 行

Exception in thread "main" com.sun.tools.internal.ws.wscompile.AbortException

关于服务调用失败的问题

  1. 问题: java调用.NET生成的webservice,会出现这个问题生成客户端代码报错
  2. 解决方案: 因为这个服务是.NET开发的,所以我们在这一块要访问需要将wsdl的描述文件保存到本地, ​ 然后做一些更改 ​ 将wsdl文件中的 ​ <s:element ref="s:schema" /><s:any /> ​ 修改为 ​ <s:any minOccurs="2" maxOccurs="2" /> ​ 之后,以绝对路径是方式来生成对应的客户端代码即可 ​ wsimport -s . D:\GitHub\webservice\webservice_network_client_4\weather.wsdl

2、编写代码调用服务

public class Client {
    public static void main(String[] args) {
        //1、创建服务视图对象
        WeatherWS weatherWS = new WeatherWS();
        //2、创建服务的实体类
        WeatherWSSoap weatherWSSoap = weatherWS.getWeatherWSSoap();
        //3、调用方法
        /*  其他方法
getRegionCountry
获得国外国家名称和与之对应的ID    输入参数:无, 返回数据:一维字符串数组。
getRegionDataset
获得**省份、直辖市、地区;国家名称(国外)和与之对应的ID      输入参数:无,返回数据:DataSet。
getRegionProvince
获得**省份、直辖市、地区和与之对应的ID   输入参数:无,返回数据:一维字符串数组。
getSupportCityDataset
获得支持的城市/地区名称和与之对应的ID       输入参数:theRegionCode = 省市、国家ID或名称,返回数据:DataSet。
         */
        //获得支持的城市/地区名称和与之对应的ID      输入参数:theRegionCode = 省市、国家ID或名称,    返回数据:一维字符串数组。
        ArrayOfString sh = weatherWSSoap.getSupportCityString("上海");
        //获得天气预报数据      输入参数:城市/地区ID或名称,    返回数据:一维字符串数组。
        ArrayOfString cityWeather = weatherWSSoap.getWeather("广州", null);
        //4、输出返回结果
        System.out.println(sh.getString());
        System.out.println(cityWeather.getString());
    }
}

中英翻译

1、通过服务的服务地址,生成客户端代码 使用命令 : wsimport -s . http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl 依旧是报错,按照上面的方式生成客户端代码 wsimport -s . D:\GitHub\webservice\webservice_network_client_5\translate.wsdl

2、编写代码调用服务

public class Client {
    public static void main(String[] args) {
        //1、创建服务视图对象
        EnglishChinese englishChinese = new EnglishChinese();
        //2、创建服务的实体类
        EnglishChineseSoap port = englishChinese.getEnglishChineseSoap();
        //3、调用方法
        /*
GetMp3
获得朗读MP3字节流
输入参数:Mp3 = Mp3名称; 返回数据:字节数组 Byte[]。
SuggestWord
获得候选词
输入参数:wordKey = 单词; 返回数据:一维字符串数组 String[]。
Translator
中英文双向翻译 DataSet
输入参数:wordKey = 单词; 返回数据:DataSet。(包括全部数据三个DataTable)
TranslatorReferString
中英文双向翻译(相关词条)String()
输入参数:wordKey = 单词; 返回数据:一维字符串数组 String[]。
TranslatorSentenceString
中英文双向翻译(例句)String()
输入参数:wordKey = 单词; 返回数据:一维字符串数组 String[]。
TranslatorString
中英文双向翻译(基本)String()
输入参数:wordKey = 单词; 返回数据:一维字符串数组 String[]。
         */
        ArrayOfString hello = port.translatorString("你好");
        System.out.println(hello.getString());
        System.out.println("=============");
        ArrayOfString hello1 = port.translatorString("hello");
        System.out.println(hello1.getString());
    }
}

手写符合SOAP协议的请求数据

目标: 通过手工的方式来发送满足SOAP协议的数据信息 ​ 这样就可以不用生成客户端代码了

观察底层发送是数据格式是什么样的?

(这里以xml为例,也有使用json的)

TCP/IP 监控工具(eclipse使用TCP/IP Monitor,idea使用TunnelliJ) 安装完插件后在idea下Tunnellij下设置 localhost port为8000,redirected to 设置为localhost :8080 type选择HTTP/SOAP Tunnellij抓包

使用client_2的demo调用服务(要改变请求路径为监听的端口)

public class Client {
    public static void main(String[] args) throws MalformedURLException {
        //URL url = new URL("http://localhost:8080/weatherService?wsdl");
        //去请求TunnelliJ,查看请求的数据
        URL url = new URL("http://localhost:8000/weatherService?wsdl");
        //在<definitions 标签下找到 targetNamespace="http://webservice.lcdiao.cn/" name="IWeatherServiceImplService" 这两个属性
        QName qName = new QName("http://webservice.lcdiao.cn/","IWeatherServiceImplService");
        //相当于上一种的底层实现
        Service service = Service.create(url, qName);

        IWeatherServiceImpl port = service.getPort(IWeatherServiceImpl.class);
        String query = port.query("深圳");
        System.out.println(query);
    }
}

查看请求数据

GET /weatherService?wsdl HTTP/1.1
User-Agent: Java/1.8.0_121
Host: localhost:8000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

POST /weatherService HTTP/1.1
Accept: text/xml, multipart/related
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://webservice.lcdiao.cn/IWeatherServiceImpl/queryRequest"
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
Host: localhost:8000
Connection: keep-alive
Content-Length: 199

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:query xmlns:ns2="http://webservice.lcdiao.cn/"><arg0>娣卞湷</arg0>			</ns2:query>
    </S:Body>
</S:Envelope>

可以看出最下面的xml就是请求数据(插件编码有问题!)

组装数据,成为这种数据格式并发送

public class Client {
    public static void main(String[] args) throws IOException {
        // URL
        URL url = new URL("http://localhost:8000/weatherService");
        //创建一个连接对象,用于向服务器发送http请求信息+获取服务器的响应信息
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        //设置请求信息
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type","text/xml; charset=utf-8");
        //打开通信
        connection.setDoOutput(true);
        connection.setDoInput(true);
        //拼接符合协议要求的数据格式
        String info = buildXML("广州");
        //发送请求信息
        connection.getOutputStream().write(info.getBytes());

        //获取响应的消息
        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            //响应状态正常,获取返回的信息
            InputStream inputStream = connection.getInputStream();
            Scanner sc = new Scanner(inputStream);
            while (sc.hasNext()) {
                //输出返回信息
                System.out.println(sc.nextLine());
                //结果:<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:queryResponse xmlns:ns2="http://webservice.lcdiao.cn/"><return>阴天</return></ns2:queryResponse></S:Body></S:Envelope>
            }
            sc.close();
        } else {
            System.out.println(responseCode);
        }
    }

    private static String buildXML(String cityName) {
        return "<?xml version=\"1.0\" ?>" +
                "<S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                "<S:Body>" +
                "<ns2:query xmlns:ns2=\"http://webservice.lcdiao.cn/\"><arg0>"+cityName+"</arg0>\t\t\t</ns2:query>" +
                "</S:Body>" +
                "</S:Envelope>";
    }
}

使用jdk的WebService注解

  • @WebService 放在接口,放在实现类
  • @WebMethod 控制方法,可以让方法不对外提供服务
  • @WebResult 控制发布服务的返回结果名称
  • @WebParam 控制发布服务的参数名
//基本都要去接口类上进行配置(有些不生效),这里省略接口类代码
@WebService(endpointInterface = "cn.lcdiao.webservice.IWeatherService")
public class IWeatherServiceImpl implements IWeatherService,IOtherService {
    //WebResult(name="weatherInfo")  表明返回的参数
    //@WebParam(name="cityName")  表明请求的参数名称,默认为arg0..
    @Override
    public @WebResult(name="weatherInfo") String query(@WebParam(name="cityName") String cityName) {
        Random random = new Random();
        int n = random.nextInt(3);
        String weather = n==2? "晴天":n==1?"阴天":"暴雨";
        System.out.println("查询-> "+cityName+" 的天气为:"+weather);
        return weather;
    }

    @Override
    public String other() {
        return "新的服务!庆祝webservice发布成功!";
    }

    @Override
    @WebMethod(exclude = true)
    public String noPublish() {
        return "使用注解@WebMethod(exclude = true)不发布出去";
    }

    @Override
    public void test() {
        //使用@WebService(endpointInterface = "cn.lcdiao.webservice.IWeatherService")
        //指定要发布的哪个接口的方法,不是该接口的方法不发布
        //但还需要去该接口类上加上@WebService注解,否则报错
    }
}

webservice框架——cxf

环境搭建

  • 官网下载好文件apache-cxf-3.3.6,配置环境变量
  • 测试,在cmd下输入wsdl2java

利用CXF发布服务

创建项目,导入文件apache-cxf-3.3.6下lib下的jar包

创建服务接口

@WebService
public interface IWeatherService {
    String query(String cityName);
}

创建服务实现类

public class WeatherServiceImpl implements IWeatherService {
    @Override
    public String query(String cityName) {
        Random random = new Random();
        int n = random.nextInt(3);
        String weather = n==2? "晴天":n==1?"阴天":"暴雨";
        System.out.println("查询-> "+cityName+" 的天气为:"+weather);
        return weather;
    }
}

发布服务

基于工厂的模式,三要素:地址、接口、实现类

public class Client {
    public static void main(String[] args) {
        JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
        //1、设置发布的地址
        factoryBean.setAddress("http://localhost:8888/weatherService");
        //2、设置访问的接口
        factoryBean.setServiceClass(IWeatherService.class);
        //3、设置服务的实现对象
        factoryBean.setServiceBean(new WeatherServiceImpl());
        //4、通过工厂创建服务
        factoryBean.create();
        System.out.println("发布服务成功!");
    }
}

查看服务的wsdl文档

浏览器访问 http://localhost:8888/weatherService?wsdl

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://webservice.lcdiao.cn/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="IWeatherServiceService" targetNamespace="http://webservice.lcdiao.cn/">
  <wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://webservice.lcdiao.cn/" elementFormDefault="unqualified" targetNamespace="http://webservice.lcdiao.cn/" version="1.0">

  <xs:element name="query" type="tns:query"/>

  <xs:element name="queryResponse" type="tns:queryResponse"/>

  <xs:complexType name="query">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="queryResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>
  </wsdl:types>
  <wsdl:message name="queryResponse">
    <wsdl:part element="tns:queryResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="query">
    <wsdl:part element="tns:query" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="IWeatherService">
    <wsdl:operation name="query">
      <wsdl:input message="tns:query" name="query">
    </wsdl:input>
      <wsdl:output message="tns:queryResponse" name="queryResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="IWeatherServiceServiceSoapBinding" type="tns:IWeatherService">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="query">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="query">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="queryResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="IWeatherServiceService">
    <wsdl:port binding="tns:IWeatherServiceServiceSoapBinding" name="IWeatherServicePort">
      <soap:address location="http://localhost:8888/weatherService"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

利用CXF调用服务

wsdl2java 命令是CXF提供的生成客户端的工具,和wsimport类型,可以根据wsdl生成客户端代码

wsdl2java常用参数: ​ -d,指定输出目录 ​ -p,指定包名,如果不指定该参数,默认包名是wsdl的命名空间的倒序

进入项目src目录下,命令行输出命令

wsdl2java -d . http://localhost:8888/weatherService?wsdl

wsdl2java生成的类

按照服务的说明书来编程

public class Client {
    public static void main(String[] args) throws Exception {
        JaxWsProxyFactoryBean proxyFactoryBean = new JaxWsProxyFactoryBean();
        //1、设置服务的地址(没有跟?wsdl)
        proxyFactoryBean.setAddress("http://localhost:8888/weatherService");
        //2、设置服务的接口 (<wsdl:portType name="IWeatherService">)
        proxyFactoryBean.setServiceClass(IWeatherService.class);
        //3、通过工厂获取对象
        IWeatherService service = (IWeatherService)proxyFactoryBean.create();
        //4、调用方法
        String q = service.query("广州");
        System.out.println(q);
    }
}

利用CXF调用网上的服务

国内手机号码归属地查询

  1. 通过服务的服务地址,来生成客户端代码 使用命令 : wsdl2java -d . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL

  2. 编写代码调用服务

    public class Client {
        public static void main(String[] args) {
            JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
            //1、设置服务的地址(没有跟?wsdl)
            factoryBean.setAddress("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx");
            //2、设置服务的接口
            factoryBean.setServiceClass(MobileCodeWSSoap.class);
            //3、通过工厂获取对象
            MobileCodeWSSoap service = factoryBean.create(MobileCodeWSSoap.class);
            //4、调用方法
            String info = service.getMobileCodeInfo("15876161217", "");
            System.out.println(info);
        }
    }

    结果:15876161217:广东 汕头 广东移动全球通卡

Spring整合cxf

cxf框架本身依赖spring,从官方下载cxf包种有spring的jar包。 将上边使用的JaxWsServerFactoryBean和JaxWsProxyFactoryBean,改为spring配置方式:

发布服务:使用spring和cxf整合的标签<jaxws:server> 客户端调用服务:使用spring和cxf整合的标签<jaxws:client>

服务端

第一步:maven项目,引入相应的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <parent>
        <artifactId>webservice</artifactId>
        <groupId>cn.lcdiao</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>

    <name>webservice_mvn_cxf_spring</name>
    <artifactId>webservice_mvn_cxf_spring</artifactId>
    <properties>
        <spring.version>5.2.5.RELEASE</spring.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- cxf -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-core</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.2.3</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.7</version>
                <configuration>
                    <connectors>
                        <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                            <port>8888</port>
                            <maxIdleTime>30000</maxIdleTime>
                        </connector>
                    </connectors>
                    <webAppSourceDirectory>${project.build.directory}/${pom.artifactId}-${pom.version}
                    </webAppSourceDirectory>
                    <contextPath>/</contextPath>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

第二步:创建SEI接口(WebService EndPoint Interface,是webservice的终端接口,就是WebService服务器端用来处理请求的接口)

@WebService
public interface IDreamService {
    String query(String name);
}

第三步:创建SEI接口实现类 接口和实现类都要加上**@WebService**注解

@WebService
public class DreamServiceImpl implements IDreamService {
    @Override
    public String query(String name) {
        System.out.println(name + "的梦想是:有钱");
        return "有钱";
    }
}

第四步:配置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"
       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="dreamServiceImpl" class="cn.lcdiao.DreamServiceImpl"/>

  <!--
      利用jaxws:server发布服务端
      address:服务地址
      serviceClass:服务接口的全类名
   -->
  <jaxws:server address="/DreamService" serviceClass="cn.lcdiao.IDreamService">
    <jaxws:serviceBean>
      <!-- 引入服务的实现类 -->
      <ref bean="dreamServiceImpl"/>
    </jaxws:serviceBean>
  </jaxws:server>
</beans>

第五步:配置web配置文件 webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <!-- 1、启动Spring容器 -->
  <!-- 配置Spring环境 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 2、创建CXF提供的Servlet,来处理关于服务的请求 -->
  <servlet>
    <servlet-name>CXF</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXF</servlet-name>
    <url-pattern>/ws/*</url-pattern>
  </servlet-mapping>
</web-app>

第六步:启动Tomcat

浏览器输入 http://localhost:8080/ws/DreamService?wsdl 测试结果

PS:本地下载的jar可能部分冲突,一直运行报错,依赖也是配了多次后才成功,不清楚是不是一定要这样配

客户端

1、创建项目,在要用的目录下输入目录生成客户端代码 wsdl2java -d . http://localhost:8080/ws/DreamService?wsdl

2、编写代码、配置文件调用服务

  • 编写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"
           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">
    
        <!--
            利用jaxws:client 调用访问
            address: 服务地址
            serviceClass:服务接口的全类名
        -->
        <jaxws:client id="dreamService" serviceClass="cn.lcdiao.IDreamService"
            address="http://localhost:8080/ws/DreamService?wsdl">
    
        </jaxws:client>
    </beans>
  • 编写测试类测试

    public class DreamServiceTest {
    
        @Test
        public void dreamTest() {
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    
            IDreamService dreamService = context.getBean(IDreamService.class);
            String me = dreamService.query("我");
            System.out.println(me);
        }
    }

Spring+SpringMVC整合cxf调用网上的翻译服务

初始环境搭建 (maven)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>webservice</artifactId>
        <groupId>cn.lcdiao</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>webservice_mvn_ssc_translate</artifactId>


    <properties>
        <spring.version>5.2.5.RELEASE</spring.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>


        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-core</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>

        <!-- JSON -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.2</version>
        </dependency>

        <!-- jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
</project>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://cxf.apache.org/jaxws
       http://cxf.apache.org/schemas/jaxws.xsd">


    <!-- 扫描service -->
    <context:component-scan base-package="cn.lcdiao.translate.service"/>


    <!-- 作为客户端调用网络上的翻译服务-->
    <jaxws:client id="translateClient" serviceClass="cn.com.webxml.EnglishChineseSoap"
        address="http://fy.webxml.com.cn/webservices/EnglishChinese.asmx?wsdl">
    </jaxws:client>
</beans>

spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <!-- 扫描web相关的bean -->
    <context:component-scan base-package="cn.lcdiao.translate.controller"/>

    <!-- 开启SpringMVC注解模式 -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes" value="text/plain;charset=UTF-8"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 静态资源默认servlet配置 -->
    <mvc:default-servlet-handler/>

    <!-- 配置jsp 显示ViewResolver -->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 配置静态资源映射 -->
    <mvc:resources mapping="/js/*" location="/js/"></mvc:resources>
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 1、启动Spring容器 -->
    <!-- 配置Spring环境 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 2、SpringMVC的前端控制器 -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置springMVC需要加载的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-*.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <!-- 匹配所有请求,此处也可以配置成 *.do 形式 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!-- 3、配置编码过滤器 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

生成客户端代码

wsdl2java -d . D:\GitHub\webservice\webservice_network_client_5\translate.wsdl

测试翻译服务

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class translateTest {

    @Resource
    private EnglishChineseSoap translate;

    @Test
    public void test() {
        List<String> happy = translate.translatorString("happy").getString();
        happy.forEach(System.out::println);
    }
}

成功则输出:

happy
'hæpi

adj. 快乐的,幸福的
7765.mp3

编写controller类

@Controller
public class TranslateController {

    @Resource
    private TranslateService translateService;

    @RequestMapping("translate")
    @ResponseBody
    public String translate(String source) {
        return translateService.translate(source);
    }
}

编写service接口

public interface TranslateService {
    String translate(String source);
}

编写service接口实现类

@Service
public class TranslateServiceImpl implements TranslateService {

    @Resource
    private EnglishChineseSoap translate;

    @Override
    public String translate(String source) {
        List<String> list = translate.translatorString(source).getString();
        return list.get(list.size()-2);
    }
}

编写前端页面jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>我的翻译</title>
<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
 <script>
     $(function () {
         $("#translate").click(function () {
             //获取要翻译的信息
            var source = $("#source").val();
             //异步发送请求,执行翻译
             $.ajax({
                 url:"translate",
                 data:"source="+source,
                 success:function (data) {
                     //将返回的翻译结果赋值给target
                     $("#target").val(data);
                 }
             })
         })
     })
 </script>
</head>
<body>
    <div style="width: 300px;height:100px;color: blue;float: left">
        <textarea rows="10" cols="30" id="source"></textarea>
    </div>
    <div style="float: left;padding: 50px;">
        <input type="button" value="翻译" id="translate">
    </div>
    <div style="width: 300px;height:100px;color: blue;float: left">
        <textarea rows="10" cols="30" id="target"></textarea>
    </div>
</body>
</html>

SSM整合CXF

服务端

目标: 开发基本的查询功能和添加功能 ​ 将这些功能以服务的方式发布出去

搭建环境

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>webservice</artifactId>
        <groupId>cn.lcdiao</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>webservice_mvn_ssm_server</artifactId>
    <properties>
        <spring.version>5.2.5.RELEASE</spring.version>
        <mybatis.version>3.5.4</mybatis.version>
        <mybatis-spring.version>2.0.4</mybatis-spring.version>
    </properties>
    <dependencies>

        <!-- 数据库 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.41</version>
            <scope>runtime</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.22</version>
        </dependency>


        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>

        <!-- mybatis/spring整合包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${mybatis-spring.version}</version>
        </dependency>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>


        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-core</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>

        <!-- JSON -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.2</version>
        </dependency>

        <!-- jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

</project>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://cxf.apache.org/jaxws
       http://cxf.apache.org/schemas/jaxws.xsd">


    <!-- 扫描service -->
    <context:component-scan base-package="cn.lcdiao.ssm.service"/>

    <!-- 配置数据库相关参数properties的属性:${url} -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 阿里 druid 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password -->
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="1" />
        <property name="minIdle" value="1" />
        <property name="maxActive" value="20" />
        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="60000" />
        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />

        <property name="validationQuery" value="SELECT 'x'" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />

        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
        <property name="poolPreparedStatements" value="true" />
        <property name="maxPoolPreparedStatementPerConnectionSize" value="20" />

        <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
        <property name="filters" value="stat" />
    </bean>
    <!-- 配置SqlSessionFactory对象 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 扫描entity包 使用别名 -->
        <property name="typeAliasesPackage" value="cn.lcdiao.ssm.entity"/>
        <!-- 扫描sql配置文件:mapper需要的xml文件 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <!-- 配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 给出需要扫描mapper接口包 -->
        <property name="basePackage" value="cn.lcdiao.ssm.mapper"/>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 配置事务增强策略 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED"/>
            <tx:method name="list*" propagation="REQUIRED" read-only="true"/>
            <tx:method name="get*" propagation="REQUIRED" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    <!-- 配置哪些切点需要应用该事务增强策略 -->
    <aop:config>
        <aop:pointcut id="service" expression="execution(* cn.lcdiao.ssm.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="service"/>
    </aop:config>


    <!-- 配置基于注解的声明式事务 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!--
      利用jaxws:server发布服务端
      address:服务地址
      serviceClass:服务接口的全类名
   -->
    <jaxws:server address="/userService" serviceClass="cn.lcdiao.ssm.service.UserService">
        <jaxws:serviceBean>
            <!-- 引入服务的实现类 -->
            <ref bean="userServiceImpl"/>
        </jaxws:serviceBean>
    </jaxws:server>
</beans>
spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <!-- 扫描web相关的bean -->
    <context:component-scan base-package="cn.lcdiao.ssm.controller"/>

    <!-- 开启SpringMVC注解模式 -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes" value="text/plain;charset=UTF-8"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 静态资源默认servlet配置 -->
    <mvc:default-servlet-handler/>

    <!-- 配置jsp 显示ViewResolver -->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--&lt;!&ndash; 配置静态资源映射 &ndash;&gt;-->
    <!--<mvc:resources mapping="/js/*" location="/js/"></mvc:resources>-->
</beans>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
#数据库地址
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8
#用户名
jdbc.username=root
#密码
jdbc.password=diao
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 1、启动Spring容器 -->
    <!-- 配置Spring环境 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 2、SpringMVC的前端控制器 -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置springMVC需要加载的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-*.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <!-- 匹配所有请求,此处也可以配置成 *.do 形式 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!-- 3、配置编码过滤器 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 4、druid相关 -->
    <filter>
        <filter-name>DruidWebStatFilter</filter-name>
        <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
        <init-param>
            <param-name>exclusions</param-name>
            <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>DruidWebStatFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>DruidStatView</servlet-name>
        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DruidStatView</servlet-name>
        <url-pattern>/druid/*</url-pattern>
    </servlet-mapping>

    <!-- 5、创建CXF提供的Servlet,来处理关于服务的请求 -->
    <servlet>
        <servlet-name>CXF</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>CXF</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>
</web-app>

创建实体类

public class User {
    private Long id;

    private String name;

    private Integer age;

    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 Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

编写mapper接口

public interface UserMapper {
    int insert(User record);

    int insertSelective(User record);

    List<User> list();

    User getUser(Long id);
}

编写mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.lcdiao.ssm.mapper.UserMapper">
  <resultMap id="BaseResultMap" type="cn.lcdiao.ssm.entity.User">
    <!--@mbg.generated-->
    <result column="id" jdbcType="BIGINT" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="age" jdbcType="INTEGER" property="age" />
  </resultMap>

  <select id="list" resultMap="BaseResultMap">
    select * from user
  </select>
  <select id="getUser" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select * from user where id = #{id}
  </select>

  <insert id="insert" parameterType="cn.lcdiao.ssm.entity.User">
    <!--@mbg.generated-->
    insert into user (id, `name`, age)
    values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER})
  </insert>
  <insert id="insertSelective" parameterType="cn.lcdiao.ssm.entity.User">
    <!--@mbg.generated-->
    insert into user
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="name != null">
        `name`,
      </if>
      <if test="age != null">
        age,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        #{age,jdbcType=INTEGER},
      </if>
    </trim>
  </insert>
</mapper>

编写service接口

@WebService
public interface UserService{


    int insert(User record);

    int insertSelective(User record);

    List<User> list();

    User getUser(Long id);

}

编写service实现类

@Service
@WebService
public class UserServiceImpl implements UserService{

    @Resource
    private UserMapper userMapper;

    @Override
    public int insert(User record) {
        return userMapper.insert(record);
    }

    @Override
    public int insertSelective(User record) {
        return userMapper.insertSelective(record);
    }

    @Override
    public List<User> list() {
        return userMapper.list();
    }

    @Override
    public User getUser(Long id) {
        return userMapper.getUser(id);
    }

}

编写controller

@Controller
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping("getUser")
    @ResponseBody
    public User getUser(Long id) {
        User user = userService.getUser(id);
        System.out.println(user);
        return user;
    }

    @RequestMapping("list")
    @ResponseBody
    public List<User> list(Long id) {
        return userService.list();
    }

    @RequestMapping(value = "insert",method = RequestMethod.POST)
    @ResponseBody
    public int insert(@RequestBody User user) {
        return userService.insertSelective(user);
    }
}

测试

浏览器输入 http://localhost:8080/ws/userService?wsdl 有wsdl文档则说明cxf整合成功

浏览器输入 http://localhost:8080/list 能出现数据库的全部user数据,说明ssm整合成功

客户端

1、创建项目,在要用的目录下输入目录生成客户端代码 wsdl2java -d . http://localhost:8080/ws/userService?wsdl

2、导入依赖,配置配置文件

3、参照Spring整合cxf,主要就修改下面

<!--
    利用jaxws:client 调用访问
    address: 服务地址
    serviceClass:服务接口的全类名
-->
<jaxws:client id="wsUserService" serviceClass="cn.lcdiao.ssm.service.UserService"
              address="http://localhost:8080/ws/userService?wsdl">
</jaxws:client>

4、写测试类,能运行就说明成功

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class WebserviceTest {
    @Resource
    private UserService wsUserService;

    @Test
    public void test(){
        User user = wsUserService.getUser(1L);
        System.out.println(user);
    }
}

CXF总结

发布服务

  1. JaxWsServerFactoryBean

  2. 设置三要素 ​ 访问路径address ​ 服务的接口 ​ 服务的实力对象

    spring整合则需要注意标签配置 <jaxws:server> ,一样注意三要素

访问服务

  1. 根据wsdl生成客户端代码

  2. JaxWsProxyFactoryBean

  3. 设置二要素 ​ 访问服务的路径 ​ 服务提供的接口

    spring整合则需要注意标签配置 <jaxws:client>,一样注意二要素

webservice's People

Contributors

lcdiao avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.