关键词
服务
现在的应用程序变得越来越复杂,甚至只靠单一的应用程序无法完成全部的工作。更别说只使用一种语言了。
大家在写应用程序查询数据库时,并没有考虑过为什么可以将查询结果返回给上层的应用程序,甚至认为,这就是数据库应该做的,其实不然,这是数据库通过TCP/IP协议与另一个应用程序进行交流的结果,而上层是什么样的应用程序,是用什么语言,数据库本身并不知道,它只知道接收到了一份协议,这就是SQL92查询标准协议。
既然数据库可以依据某些标准对外部其他应用程序提供服务、而且不关心对方使用什么语言,那我们为什么就不能实现跨平台、跨语言的服务呢?
只要我们用Java写的代码,可以被任意的语言所调用,我们就实现了跨平台,跨语言的服务!
XML. Extensible Markup Language -扩展性标记语言,用于传输格式化的数据,是Web服务的基础。
namespace-命名空间。
xmlns=“http://itcast.cn” 使用默认命名空间。
xmlns:itcast=“http://itcast.cn”使用指定名称的命名空间。
WSDL WebService Description Language – Web服务描述语言。
通过XML形式说明服务在什么地方-地址。
通过XML形式说明服务提供什么样的方法 – 如何调用。
SOAP Simple Object Access Protocol(简单对象访问协议)
SOAP作为一个基于XML语言的协议用于网上传输数据。
SOAP = 在HTTP的基础上+XML数据。
SOAP是基于HTTP的。有两个版本,Soap1.1,soap1.2
SOAP的组成如下:
Envelope – 必须的部分。以XML的根元素出现。
Headers – 可选的。
Body – 必须的。在body部分,包含要执行的服务器的方法。和发送到服务器的数据。
简单的网络应用
复杂的网络应用
WSDL
说明服务在哪里,如何调用,其实就是一个使用说明书。
说明书图解
说明书例子:
<?xml version="1.0" encoding="UTF8" ?>
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://ws.itcast.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.itcast.cn/"
name="HelloServiceService">
<types>
<xsd:schema>
<xsd:import namespace="http://ws.itcast.cn/"
schemaLocation="http://localhost:9999/hello?xsd=1" />
</xsd:schema>
</types>
<message name="sayHi">
<part name="parameters" element="tns:sayHi" />
</message>
<message name="sayHiResponse">
<part name="parameters" element="tns:sayHiResponse" />
</message>
<portType name="HelloService">
<operation name="sayHi">
<input message="tns:sayHi" />
<output message="tns:sayHiResponse" />
</operation>
</portType>
<binding name="HelloServicePortBinding" type="tns:HelloService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="sayHi">
<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://localhost:9999/hello" />
</port>
</service>
</definitions>
SOAP协议
soap协议--请求范本---发出HTTP请求,但不同的是向服务器发送的是XML数据!
soap协议--响应范本--响应的信息,同发送信息一样,先必须是HTTP协议,然后再遵循SOAP协议
协议,在某种程度上,可以理解为:通讯的数据格式!
WebService只采用HTTP POST方式传输数据,不使用GET方式。
普通http post的contentType为
application/x-www-form-urlencoded
WebService的contentType为-即在Http的基础上发SOAP协议
text/xml 这是基于soap1.1协议。
application/soap+xml 这是基于soap1.2协议。
SOAP请求过程分析:
webservice监听工具
为了获取SOAP数据发送和接收的格式。我们有必要使用一个工具来深入的了解WebService.
为了监控拦截请求头和响应头的具体数据,我们使用TCP/IP Monitor来拦截请求和响应的完整过程。
使用WebService Explorer只可以看到SOAP的XML数据,并看不到HTTP协议的头。
既然是用HTTP发XML数据,就一定会有HTTP头,为了获取HTTP头,我们使用TCP/IP Monitor.
此工具位于:window>show view>other>MyEclipse Common(常用工具)>TCP/IP Monitor
使用MyEclipse的TCP/IP Monitor这个工具来查看具体的请求过程。
TCP/IP Monitor不仅可以看到SOAP数据,还可以获取HTTP请求和接收的头信息。
1.1、此工具位于:window>show view>other>MyEclipse Common(常用工具)>TCP/IP Monitor
1.2、此工具,相当于一个代理商,启动后它将监听本地的某个端口,然后再将请求转发给指定的目标IP和端口。
获取到数据后,再将数据原封不动的返回给客户。在客户看来,永远首先访问的都应该是这个代理,否则
我们将看不到数据传输的过程。
1.3、配置选项:
在打开的TCP/IP Monitor界面上:view Menu(右上方向下的小箭头)>Properties>Add(右侧添加)
设置成以下属性:
步1:
local monitoring port(监听本地的端口号):9876,随意设置一个4位的端口号,一会将通过http://127.0.0.1:9876的形式访问
host name(要监听的服务器,如www.baidu.com):127.0.0.1 –因为本机发布了一个WebService所以监听本机IP.也可以是任意的主机。
Port(要监听的目标服务器的端口):6666 - 因为我们发布的WebService为http://127.0.0.1:6666/helloworld所以,6666是需要监听的端口号。
Type(监听的类型):
-- TCP/IP : 将使用原始地址继续访问下一个请求,如用户输入:http://127.0.0.1:9876/helloworld?wsdl此时将返回wsdl服务访问地址同前。
-- HTTP :将使用目标地址继续访问下一个请求。如用户输入: http://127.0.0.1:9876/helloworld?wsdl在请求方法时将使用http://127.0.0.1:6666/helloworld来访问sayHi方法。此种方式将不再会被代理。因为已经不是正在监听的端口号了。
在监听类型处,我们选择TCP/IP。
建议同学们,将两种方式都设置一下,然后通过在地址栏输入:http://127.0.0.1:9876/helloworld?wsdl,在返回的wsdl文件中
查看:<soap:address location=“http:……”/>处地址的变化情况。
time out:设置访问不成功的连接时间,保持为0,即不设置。 在设置好后,点OK按扭,然后再点右方的Start按扭,监听便已经启动。
步2:
在MyEclipse的WebService上配置WSDL URL为:http://127.0.0.1:9876/helloworld?wsdl,注意使用的是MyEclipse TCP/IP Monitor的端口。而不是直接去访问我们发布的http://127.0.0.1:6666/helloworld?wsdl
在WebService Explorer上请求sayHi方法,传递参数,并查看http头信息和发送及返回的xml信息。
无论是MyEclipse WebService Explorer,Httpwatch,还是TCP/IP Monitor都是一些辅助工具。虽然对编写代码没有什么用处,但对我如何监控问题,发现问题的能力有所帮助。更能从工具的使用中,发现代码的问题进行调整或改进。
什么是webservice
WebService,顾名思义就是基于Web的服务。它使用Web(HTTP)方式,接收和响应外部系统的某种请求。从而实现远程调用.
我们可以调用互联网上查询天气信息Web服务,然后将它嵌入到我们的程序(C/S或B/S程序)当中来,当用户从我们的网点看到天气信息时,他会认为我们为他提供了很多的信息服务,但其实我们什么也没有做,只是简单调用了一下服务器上的一段代码而已。
学习WebService可以将你的服务(一段代码)发布到互联网上让别人去调用,也可以调用别人机器上发布的WebService,就像使用自己的代码一样.。
webservice能解决什么问题
webservice怎么用
看懂wsdl文件,能帮助我们顺利弄清如何调用一个WebService,以及它有哪些类的哪些方法可以调用。
1、SOAPBinding(style=Style.DOCUMENT或Stype.RPC)指定了消息的格式,即相互交流以语言。此值默认为DOCUMENT。并在wsdl文件的soap:binding ….type上出现。请大家注意观察。
(目前我的使用的WebService规范是基于jax-ws的,而rpc是基于jax-rpc的,已经过时。)
以下是wsdl文档的部分代码:
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
Style指定了消息格式
Transport的最后部分指定了使用什么样的协议。此处定义为http协议。
所以,binding部分,定义了如何调用,使用什么样的协议和消息格式,有什么样的方法可以调用。
portType又指定了一个可以调用的Java类,types定义命名空间的信息,其中namespace是倒置的包名。schemaLocation是xsd地址信息,可以拷贝此地址,并查看xsd的定义。
开始的二行注释是Jax-ws的版本,及是由哪个jdk生成的。
图解
修改wsdl内容
注解的作用
2:以下是加了注解的示例:
package com.itcast;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.xml.ws.Endpoint;
/**
* 一个加了很多注解的代码
*/
@WebService(name="myName",//对应portType name="myName"
portName="myPort", //对应服务中的port name="myPort"
serviceName="myService",//对应service name="myService"
targetNamespace="http://leaf.com/mynamespace")//可以随意书写类似于java中的package
public class HelloWorld{
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@WebMethod(action="myAction",//定义一个soapAction="myAction"用于找到这个方法以执行
operationName="myOperationName")//定义可以调用的方法,会生成相应类的具体方法,operation name=".."
public @WebResult(name="mySayHelloResult")String//定义返回值的名称
sayHello(){
return "HelloWorld";
}
@WebMethod(action="mySayHiAction",operationName="mySayHiOperationName")
public @WebResult(name="mySayHiResult")String sayHi(@WebParam(name="myParaName",
//将参数放到头信息中,用于保护参数,默认在body中
header=true,
mode=Mode.IN)
String name){
String str = "你好:"+name+",当前时间是:"+sdf.format(new Date());
return str;
}
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:6666/helloworld",new HelloWorld());
}
}
3:将上面的程序对外发布以后,我们通过MyEclipse的WebService Explorer来访问
你会发现和以前不一样的提示信息,但其实,仍然还是调用的那同一个方法。
4:观察SOAP请求和返回文档的修改。在MyEclipse WebService Explorer的返回信息窗口中点Soure即可以看到。观察变化加以分析。
5:再次使用wsimport –s . http://127.0.0.1:6666/helloworld?wsdl生成java代码然后调用,看看还是哪些类名吗?
以下是调用代码(可以用面目全非来形容,但完成的还是同样的工作。)
package com.leaf.mynamespace;
public class Main {
public static void main(String[] args) {
//通过分析wsdl可知从myService中调用getMyPort返回myName
MyName myName = new MyService().getMyPort();
//通过myName的mySayHiOperationName来调用sayHi方法
String str = myName.mySayHiOperationName("王健");
System.err.println(str);
}
}
代码:
mport java.util.Date;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
/**
* 发布第一个web服务
*/
@WebService
(serviceName="WjService"//修改Service的名称,即:new WjService();
,name="One"//定义Port名称,即端口-new WjService().getOnePort();返回接口即One
,targetNamespace="http://wj.cn"//定义命名空间,默认为倒置的包名
,portName="one"//定义获取的方法,此值可以覆盖name的定义,即port name="getOne"
)
public class OneService{
@WebMethod(operationName="sayHello"//修改方法名
)
public
@WebResult(name="ReturnMsg")
String sayHi(
@WebParam(name="yourName")
String name){
return name+",你好,现在时间是:"+new Date();
}
public static void main(String[] args) throws Exception {
//发布服务
Endpoint ed= Endpoint.publish("http://127.0.0.1:9999/one",
new OneService());
System.err.println("服务发布成功");
}
}
分析WSDL
CXF
图解
服务与客户端类调用原则
未完待续。。。。
webservice原理