webservice 学习笔记 1
Webservice-----------》跨语言服务调用 (视频学习总结)
1-1.有OA系统 需要添加一个功能,登录之后显示天气情况 此时可以使用Webservice
eg1: 气象局自己有数据库,不能直接访问,部分公司与其有关联合作,可以有数据,做成天气服务出售,通过webservice调用

模拟eg1:socket编程模拟服务端客户端访问
提供服务的服务器端:server.accept(); 阻塞等待客户端调用,模拟服务一直等待(只能接受一份请求)
可用 while (true){ ... }包裹读取客户端数据 从而接受多份请求
客户端模拟例子:

1-2 http://www.webxml.com.cn/zh_cn/index.aspx 此网站提供webservice服务 有免费的也有收费的

1-3 WSDL, SOAP 学习

业务层可以发布外部服务,其他应用可以访问此服务 (Webservice)

只要使用java写的代码,可以被任意语言调用,实现了跨平台跨语言服务 ------ webservice

WSDL 是给客户端了解的,方法名称 服务提供地址等待

1-4 http 协议和 soap(简单对象访问协议)差别
SOAP本身也是http协议,在http基础之上传输格式变成xml

SOAP 发出http请求格式实例

SOAP 发出http响应格式实例

发布一个简单的Webservice 服务

简单创建一个java project

添加一个HelloService方法,启动就可以提供服务
package com.lixuchun.server; import javax.jws.WebService;
import javax.xml.ws.Endpoint; /**
* jdk发布一个webservice服务
* @author lixuchun
*
*/
// 只有加了webservice注解类才能发布服务
@WebService
public class HelloService { // 有效合法方法不能是静态方法 也不能是final方法,final方法不能被重写
public String sayHello(String name) {
return "hello " + name;
} // main方法发布的话报错 不是有效合法方法
public static void main(String args[]) {
// 服务发布地址
String adderss = "http://127.0.0.1:8999/hello";
// 服务实例
Object implementor = new HelloService();
// publish 启动多线程
Endpoint.publish(adderss, implementor);
System.out.println("server start success !");
}
}
1-5 使用wsimport命令生成客户端代码调用webservice服务

服务启动,在浏览器输入adderss地址?wsdl

可以使用cmd 窗口使用wsimport -s . address?wsdl
-s 表示生成源码
. 表示当前目录

生成编码客户端 D:盘下

创建新client项目 webservice_day01_client 生成java文件复制到项目中

编辑App类调用webservice 服务
package com.lixuchun.server; /**
* 使用wsimport 命令生成客户端代码调用webservice服务
* 方法最简单 不需要关注细节问题
* @author lixuchun
*
*/
public class App {
public static void main(String args[]) {
// wsdl 看service标签 <service name="HelloServiceService">
HelloServiceService helloServiceService = new HelloServiceService();
// wsdl service 标签里头的 port <port name="HelloServicePort" binding="tns:HelloServicePortBinding">
HelloService hellowService = helloServiceService.getHelloServicePort(); String response = hellowService.sayHello("jack");
System.out.println(response); }
}
执行后 客户端出现 hello jack 调用成功
1-6 调用天气预报服务
wsimport -s . http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
调用时 报错

s:schema 报错
处理过程
1. 访问 http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl 将页面保存到本地 weather.xml

通过cmd窗口 了解到时 上图中s:schema报错 xml中的三处标签
然后重新执行wsimport命令 -->调用本地weather.xml
wsimport -s . weather.xml

重新执行没有问题了
在D生成java文件

复制文件到新项目中

编写App类调用服务
package cn.com.webxml; import java.util.List; /**
* 使用wsimport生成代码
* @author lixuchun
*
*/
public class App {
public static void main(String args[]) {
// wsdl service 标签
WeatherWS ws = new WeatherWS();
//
WeatherWSSoap soap = ws.getWeatherWSSoap();
ArrayOfString aos = soap.getWeather("沈阳", null);
List<String> list = aos.getString();
for (String weather : list) {
System.out.println(weather);
}
}
}
执行后客户端显示如下效果 调用成功

此处代码已经生成但是不能删除,删除后执行依然会报错(weather.xml)

找到出错的类

将此类中所有本地地址再改为网上地址 http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
在此访问webserice就没有问题了
此过程为 :先访问 WeatherWS 通过wsdlLocation 查看服务是否发布存在,如果存在再发布一个请求进行请求访问 所以
进行了2此请求,所以删除本地weather.xml文件后会报错
1-7 查看WSDL和 SOAP1.1 1.2对比
helloService中 新加入 sayHi方法 希望本地可以调用但是发布服务的时候外部看不见
可以使用 @WebMethod(exclude = true) 进行排除方法
package com.lixuchun.server;
package com.lixuchun.server; import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.ws.Endpoint; /**
* jdk发布一个webservice服务
* @author lixuchun
*
*/
// 只有加了webservice注解类才能发布服务
@WebService
public class HelloService { // 有效合法方法不能是静态方法 也不能是final方法,final方法不能被重写
public String sayHello(String name) {
return "hello " + name;
} // 内部可以调用 发布外部不能调用
@WebMethod(exclude = true)
public String sayHi(String name) {
return "Hi " + name;
} // main方法发布的话报错 不是有效合法方法
public static void main(String args[]) {
// 服务发布地址
String adderss = "http://127.0.0.1:8999/hello";
// 服务实例
Object implementor = new HelloService();
// publish 启动多线程
Endpoint.publish(adderss, implementor);
System.out.println("server start success !");
}
}
再来了解下WSDL文件

通过 address?wsdl 可以获取到 wsdl.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
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://server.lixuchun.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://server.lixuchun.com/" name="HelloServiceService">
<types>
<xsd:schema>
<xsd:import namespace="http://server.lixuchun.com/" schemaLocation="http://127.0.0.1:8999/hello?xsd=1"/>
</xsd:schema>
</types>
<message name="sayHello">
<part name="parameters" element="tns:sayHello"/>
</message>
<message name="sayHelloResponse">
<part name="parameters" element="tns:sayHelloResponse"/>
</message>
<portType name="HelloService">
<operation name="sayHello">
<input wsam:Action="http://server.lixuchun.com/HelloService/sayHelloRequest" message="tns:sayHello"/>
<output wsam:Action="http://server.lixuchun.com/HelloService/sayHelloResponse" message="tns:sayHelloResponse"/>
</operation>
</portType>
<binding name="HelloServicePortBinding" type="tns:HelloService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="sayHello">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="HelloServiceService">
<port name="HelloServicePort" binding="tns:HelloServicePortBinding">
<soap:address location="http://127.0.0.1:8999/hello"/>
</port>
</service>
</definitions>
通过文件可以获取: (查看文件倒叙查看)
服务名称
服务地址
服务的方法
方法的参数
参数个数类型
先看service -> HelloServiceService
port -> binding -> HelloServicePortBinding
binding - > type -> HelloService
protType -> HelloService -> operation
operation -> sayHello
input sayHello (sayHello 接收参数) -> message sayHello
output sayHelloResponse (返回参数) -> message sayHelloResponse
message sayHello -> element sayHello -> 指向 http://127.0.0.1:8999/hello?xsd=1
message sayHelloResponse element sayHelloResponse -> 指向 http://127.0.0.1:8999/hello?xsd=1
http://127.0.0.1:8999/hello?xsd=1内容为
<xs:schema
xmlns:tns="http://server.lixuchun.com/"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://server.lixuchun.com/">
<xs:element name="sayHello" type="tns:sayHello"/>
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
<xs:complexType name="sayHello">
<xs:sequence>
<xs:element name="arg0" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">
<xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
element sayHello ->complexType sayHello -> sequence 参数 name type string
element sayHelloResponse ->complexType sayHelloResponse ->return string
WSDL 对应客户端代码结构 如下图:

本地App类中没有具体实现类,HelloService helloService 对象 为 代理对象。
默认情况下 服务和客户端生成包结构是相同的 如下图:

可以自己指定包结构 wsimport -p 包结构 address
cmd 窗口下 wsimport -s . -p com.lixuchun.test http://127.0.0.1:8999/hello?wsdl
可以生成 自定义的包结构给客户端
传统xml数据格式,基于SAOP格式的都是post请求 因为需要 请求体
上面例子都是soap1.1例子 使用jdk开发,只支持soap1.1 , 需要cxf框架才能支持soap1.2

SOAP 1.1 和 1.2差异







1-9 ajax 请求WebService 服务


1-10 urlconnection调用webservice 代码量少
添加AppUrlConnection.java文件
package com.lixuchun.server; import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL; public class AppUrlConnection {
public static void main(String args[]) throws Exception {
// webservice 服务地址
URL url = new URL("http://127.0.0.1:8999/hello");
HttpURLConnection conn = (HttpURLConnection)url.openConnection(); // 请求头构建
// 有请求
conn.setDoInput(true);
// 有响应
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("content-type", "text/xml;charset=utf-8"); // 构造请求体
String requestBody = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+ "xmlns:q0=\"http://service.itheima.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ "<soapenv:Body> <q0:sayHello><arg0>test</arg0> "
+ "</q0:sayHello> </soapenv:Body></soapenv:Envelope>"; //获得一个输出流
OutputStream out = conn.getOutputStream();
out.write(requestBody.getBytes()); //获得服务端响应状态码
int code = conn.getResponseCode();
StringBuffer sb = new StringBuffer();
if(code == 200){
//获得一个输入流,读取服务端响应的数据
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0; while((len = is.read(b)) != -1){
String s = new String(b,0,len,"utf-8");
sb.append(s);
}
is.close();
} out.close();
System.out.println("服务端响应数据为:"+sb.toString());
}
}
执行后可以看到响应格式为正常的soap响应格式

wsimport方式调用webservice生成代码量过大,URLConnection方式需要自己解析
所以还有客户端编程方式 创建目录 创建appClient类


package client; import java.net.URL; import javax.xml.namespace.QName;
import javax.xml.ws.Service; /**
* 使用客户端编程方式调用webservice
* 也需要使用 wsimport 生成代码 但是只要导入接口就可以
* @author lixuchun
*
*/
public class AppClient {
public static void main(String args[]) throws Exception {
String wsdlUrl = "http://127.0.0.1:8999/hello?wsdl";
// arg1 服务地址 url
// QName 名称空间 uri wsdl文件 targetNamespace获取, wsdl服务名称
Service service = Service.create(new URL(wsdlUrl), new QName("http://server.lixuchun.com", "HelloServiceService"));
HelloService port = service.getPort(new QName("http://itheima.com", "HelloServicePort"), HelloService.class);
String ret = port.sayHello("test");
System.out.println(ret);
}
}
其中QName 2个参数为 uri 第二个为 service标签 服务
%默认情况下 生成URI就是包名的逆向 eg : com.lixuchun.server -> uri server.lixuchun.com
port 中 QName 第一个参数为uri 第二个参数为 service服务下的 port

1-14 通过注解修改WSDL文件内容
SOAP请求过程分析:
客户端先发送get请求 查看服务是否正常运行存在 如果存在再进行第二次post请求 请求数据

注解修改WSDL文件后之前使用的调用类就不好用了 名称都变为注解名称 需要重新wsimport 编译导入

通过注解修改wsdl文件的实例:
package com.lixuchun.service; import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.Endpoint; /**
* 注解修改webservice wsdl文件名称
* @author lixuchun
*/
//只有加了WebService注解的类,才有可能发布为web服务
@WebService(targetNamespace="http://server.lixuchun.com", serviceName="myService")
public class HelloService {
//提供一个合法的web方法
@WebMethod(operationName="myMethod")
@WebResult(name="myResult")
public String sayHello(
@WebParam(name="name")
String name,
@WebParam(name="age")
int age){
System.out.println("sayHello方法被调用了");
return "hello " + name;
} @WebMethod(exclude=true)//排除当前方法
public String sayHi(String name){
System.out.println("sayHi方法被调用了");
return "hi " + name;
} public static void main(String[] args) {
String address = "http://127.0.0.1:9999/hello";//服务的发布地址
HelloService implementor = new HelloService();//提供服务的实例
Endpoint.publish(address, implementor);
System.out.println("server ready...");
}
}
启动服务 再次查看wsdl文件,可以看到更改后的tag标签的变化


1-15 返回自定义对象
创建新的服务

添加自定义类和服务类
package com.lixuchun.service;
public class Person {
private String id;
private String name;
private String address;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
package com.lixuchun.service; import javax.jws.WebService;
import javax.xml.ws.Endpoint; @WebService
public class PersionService {
public Person findPersonById(String id) {
Person p = new Person();
p.setId(id);
p.setAddress("沈阳");
p.setName("jack");
return p;
} public static void main(String args[]) {
Endpoint.publish("http://127.0.0.1:9000/findPerson", new PersionService());
System.out.println("person server start ");
}
}
启动服务 查看wsdl文件

返回person类型

通过eclipse插件查看响应和请求

address bj / id 1 / name test
也可以使用 代码进行测试 用wsimport -s . address 生成源代码文件
然后再写调用客户端类

上图可以看到生成代码中有person类生成 为返回对象类
视频学习笔记 -> 视频地址 https://pan.baidu.com/s/1eOqnr4KIajLcaKSk_tYyJA#list/path=%2F 可以自行下载学习
webservice 学习笔记 1的更多相关文章
- WebService学习笔记系列(二)
soap(简单对象访问协议),它是在http基础之上传递xml格式数据的协议.soap协议分为两个版本,soap1.1和soap1.2. 在学习webservice时我们有一个必备工具叫做tcpmon ...
- Java WebService学习笔记 - Axis进阶(二)
上一篇 Java WebService学习笔记 - Axis(一) 前一篇博文中简单介绍了Axis的使用方法,这篇将介绍一些Axis的一些高级特性 Axis中Handler的使用 Handler ...
- Java WebService学习笔记 - Axis(一)
WebService 简介 实际开发中,很多系统都是基于历史遗留系统进行开发,有时,这些系统基于不同的语言,如C,C++,C#,java,PHP等等.为了实现历史系统的再利用,或向外部程序暴露调用接口 ...
- WebService 学习笔记(一、概念及定义)
定义 WebService是一种服务导向架构(SOA service-oriented architecture)的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作. Web ...
- webservice 学习笔记
1.webservice的概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的 ...
- WebService学习笔记一
01——Schema约束复习 1.1 schema约束 几个重要知识: 1.namespace 相当于schema文件的id 2.targetNamespace属性 用来指定schema文件的name ...
- WebService学习笔记系列(四)
今天主要来看看服务端的编写及发布. 服务端的编写主要包括三个步骤: 1.编写一个接口,即SEI(server endpoint interface) 2.编写接口的实现类,即SIB (server i ...
- WebService学习笔记系列(三)
网上有一些提供webservice服务的网站,我们要怎么调用呢? 今天来看个如何调用手机归属地查询服务.这个网站上提供了许多webservice服务,其中包括手机归属地查询服务,我们今天就用wsimp ...
- WebService学习笔记系列(一)
webservice主要是解决两个系统或者两个应用程序之间的远程调用,它提供了一种通过web方式访问的api,调用是跨语言.跨平台的. webservice的客户端与服务端进行交互的时候使用xml来传 ...
随机推荐
- Python入门习题9.数码管时间
#七段数码管.py import turtle,datetime def drawGap(): #绘制数码管间隔 turtle.penup() turtle.fd(5) def drawLine(dr ...
- deque(双向队列)基本用法
deque(双向队列)基本用法 阅读体验:https://zybuluo.com/Junlier/note/1297030 简单介绍 就是可以两头插元素,两头删元素的数据结构 那么具体的STL操作(只 ...
- bzoj2176 Strange string(字符串最小表示法)
Time Limit: 10 Sec Memory Limit: 259 MB 给定一个字符串S = {S1, S2, S3 … Sn}, 如果在串SS中, 子串T(|T| = n)为所有长度为n的 ...
- 利用java反射动态调用方法,生成grid数据
项目中需要java后台查询并组装前台grid的数据,数据行数不定,数据行定义不定,开始用了最原始的方法,写了几百行,就是前台需要什么字段后台拼接什么字段,java代码冗余量非常大,并且不够灵活,一旦前 ...
- 【JAVA】 04-Java中的多线程
链接: 笔记目录:毕向东Java基础视频教程-笔记 GitHub库:JavaBXD33 目录: <> <> 内容待整理: 多线程引入 概述 多线程: 进程:正在执行中的程序,其 ...
- 一些常见的js校验
今天有时间来总结一下那些常用的js校验: vernull = function(value){//非空校验 if(value.trim(value).length == 0){ return fals ...
- elasticsearch 深入 —— 近似匹配
近似匹配 使用 TF/IDF 的标准全文检索将文档或者文档中的字段作一大袋的词语处理. match 查询可以告知我们这大袋子中是否包含查询的词条,但却无法告知词语之间的关系. 思考下面这几个句子的不同 ...
- sendmail 出现 My unqualified host name的解决办法
有"My unqualified host name"错误 修改/etc/hosts, 在本机的ip那一行, 在xxxhostname后面加上" xxxhostname ...
- pandas-同时处理两行数据
pandas-同时处理两行数据 假设数据集data如下所示: 如果我们想要将user_id 和 item_id两列进行对应元素相加的操作,该怎么办呢? 显然我们先定义一个加法函数,然后使用apply函 ...
- Java面向对象的特征与含义
面向对象的主要特征包括抽象.继承.封装和多态. 抽象 把一个类对象的共同特征总结出来,构造新类的过程. 继承 从已有类中得到继承信息,创建新类的过程. 封装 把数据和对数据的操作绑定起来,对数据的访问 ...