WebService学习笔记(一)

本文介绍WebService的概念、原理及其应用场景,涵盖XML、WSDL、SOAP等关键技术,并详细讲解WebService的发布与调用流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

认识WebService

背景:

    1. 现在的应用程序变得越来越复杂,甚至只靠单一的应用程序已无法完成全部的工作,那就更别说只使用一种语言了。

    2.通常在写应用程序查询数据库时,并没有考虑过为什么可以将查询结果返回给上层的应用程序,甚至认为,这就是数据库应该做的,其实不然,这是数据库通过TCP/IP协议与另一个应用程序进行交流的结果,而上层是什么样的应用程序,是用什么语言,数据库本身并不知道,它只知道接收到了一份协议,这就是SQL92查询标准协议。




    3.既然数据库可以依据某些标准对外部其他应用程序提供服务、而且不关心对方使用的是什么语言,那我们为什么就不能实现跨平台、跨语言的服务呢?也就是说,我们用Java写的代码,可以被任意的语言所调用,这样我们就实现了跨平台,跨语言的服务!


    那么WebService,顾名思义就是基于Web的服务,它使用的是Web(HTTP)方式,接收和响应外部系统的某种请求,从而实现远程调用

    举个栗子帮我们理解一下:我们可以调用互联网上查询天气信息Web服务,然后将它嵌入到我们的程序(C/S或B/S程序)当中来,当用户从我们的网点看到天气信息时,他会认为我们为他提供了很多的信息服务,但其实我们什么也没有做,只是简单了调用了一下服务器上的一段代码而已

    反过来,WebSerice也可以将你的服务(一段代码)发布到互联网上让别人去调用,也可以调用别人机器上发布的WebService,就像使用自己的代码一样。

1.学习webservice调用的预备知识

名词1:XML. Extensible Markup Language -扩展性标记语言

           XML  用于传输格式化的数据,是Web服务的基础。

           namespace  命名空间。

           xmlns =“http://itcast.cn”使用默认命名空间。

           xmlns:itcast =“http://itcast.cn”使用指定名称的命名空间。

名词2:WSDL – WebService Description Language – Web服务描述语言。

           通过XML形式说明服务在什么地方--地址。

           通过XML形式说明服务提供什么样的方法 –- 如何调用。

           服务端给客户端提供的一个说明书

           约束了客户端和服务端之间通信的消息格式

名词3:SOAP-Simple Object Access Protocol(简单对象访问协议)

           SOAP作为一个基于XML语言的协议用于有网上传输数据。

           SOAP = HTTP的基础上+XML数据。

           SOAP是基于HTTP的。

           SOAP的组成如下:

                   Envelope– 必须的部分。以XML的根元素出现。

                   Headers– 可选的。

                   Body – 必须的。在body部分,包含要执行的服务器的方法和发送到服务器的数据

2.webservice服务网址

Webservice服务网站:http://www.webxml.com.cn

3.WSDL文档解析(重要内容

WSDL: webservice描述语言

读的方式:从下向上读

service:服务访问点的集合元素,元素的name属性很重要,调用时需要使用

port:服务访问点元素的name属性调用时需要使用binding属性指定了服务访问点和服务类绑定元素

binding:把服务访问点和服务类绑定在一起,不需要关系元素的内部,要关心的就是他的type属性,这个属性指定了绑定的服务类xml元素(portType

portType:具体的服务类的元素,在portType内部有noperation

operation:就是服务类中的方法

message:输入输出的消息体,分别对应着服务端接收的参数和响应的返回值,我们前面说了消息是以soap为协议,这个协议是http方式的请求,请求体式xml,这个xml不能随便写,需要约束使用schema

types:对输入输出的消息体的约束schema

4.生成客户端代码(重要

1. wsimport是jdk自带的,可以根据wsdl文档生成客户端调用代码的工具。当然,无论服务器端的WebService是用什么语言写的,都将在客户端生成Java代码,服务器端用什么写的并不重要。

2. wsimport.exe 位于JAVA_HOME\bin目录下。

常用参数为:

        •   -d<目录>  - 将生成.class文件。默认参数。

        •    -s<目录>  - 将生成.java文件和.class文件。

        •    -p<生成的新包名> -将生成的类,放于指定的包下。

        •    (wsdlurl) - http://server:port/service?wsdl,必须的参数。

示例:C:/> wsimport –s . http://192.168.0.100/one?wsdl

3.注意:-s不能分开,-s后面有个小点,用于指定源代码生成的目录,点即当前目录。

            如果使用了-s参数则会在目录下生成两份代码,一份为.class代码,一份为.java代码。.class代码,可以经过打包以后使用。.java代码可以直接Copy到我们的项目中运行。

5. jdk发布webservice服务

注意:用Jdk1.6.0_21以后的版本发布一个WebService服务.

说明:在JDK1.6中JAX-WS规范定义了如何发布一个webService服务, JAX-WS是指Java Api for XML –WebService。

与Web服务相关的类,都位于javax.xml.ws.*包中。

主要类有:

a)@WebService - 它是一个注解,用在类上指定将此类发布成一个webservice服务。

b)Endpoint – 此类为端点服务类,它的方法publish用于将一个已经添加了@WebService注解对象绑定到一个地址的端口上。        Endpoint是jdk提供的一个专门用于发布服务的类,它的publish方法接收两个参数,一个是本地的服务地址,二是提供服务的类,它位于javax.xml.ws.*包中。

     static Endpoint.publish(String address,Object implementor) 在给定地址处针对指定的实现者对象创建并发布端点。stop方法用于停止服务。

其他注意事项:

1)      给类添加上@WebService注解后,类中所有的非静态方法都将会对外公布。不支持静态方法,final方法。

2)      如果希望某个方法(非static,非final)不对外公开,可以在方法上添加@WebMethod(exclude=true),阻止对外公开。

3)      如果一个类上,被添加了@WebService注解,则必须此类至少有一个可以公开的方法,否则将会启动失败。

4)      服务类中不能没有方法

5)      @WebMethod(exclude=true)屏蔽方法

6.调用webservice步骤(重要)

  (1)找一个空文件夹,通过命令行,切换到空文件夹目录。

  (2)执行:wsimport -s . -p  com.xxx.xx http://192.168.15.82:8099/hello?wsdl

wsdl文档元素名称修改(**

    自动生成的文档的名字有时不规范,可以手动进行修改。

          @WebService(

                portName="myHelloService",修改端口名字

                serviceName="HelloServices",修改服务访问点集合名字

                name="HelloService",修改服务类的名字

                targetNamespace="hello.rl.com",修改命名空间名字

          )

        @WebResult(name="sirHello")修改返回值的元素的父标签名字

        @WebParam(name="sir")修改传入参数的元素的父标签名字


  (3)把代码拷贝到客户端的工程中

  (4)服务端的调用

    //1.创建服务访问点集合对象
    PersonServiceService pss = new PersonServiceService();
    //2.获得服务点绑定的类,使用get加上port的名字(PersonServicePort), getPersonServicePort
    PersonService ps =pss.getPersonServicePort();
    //3.调用服务端的方法
    String result = ps.sayHello("周星星");
    System.out.println(result);

7. 其他调用webservice的方式(*)

1. 使用ajax调用

var xhr;
function invoke(){
	if(window.ActiveXObject){
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}else{
		xhr = new XMLHttpRequest();
	}
	//指定请求地址
	var url = "http://127.0.0.1:7777/hello?wsdl";
	//定义请求类型和地址和异步
	xhr.open("POST", url, true);
	//设置Content-Type
	xhr.setRequestHeader("Content-Type", "text/xml;charset=UTF-8");
	//指定回调方法
	xhr.onreadystatechange = back;
	var textVal = document.getElementById("mytext").value;
	//组装消息体的数据
	var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://server.hm.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
	+'<soapenv:Body>'
	+'<q0:sayHello>'
	+'<arg0>'+textVal+'</arg0>'
	+'</q0:sayHello>'
	+'</soapenv:Body>'
	+'</soapenv:Envelope>';
	xhr.send(data);
}
function back(){
	if(xhr.readyState == 4){
		if(xhr.status == 200){
			var doc = xhr.responseXML;
			alert(doc);
			alert(xhr.responseText);
			var tag = doc.getElementsByTagName("return")[0];
			alert(tag)	
	}
}
}

2. 通过URLConnection调用(*

//创建url地址
		URL url = new URL("http://192.168.1.104:8080/hello");
		//打开连接
		URLConnection conn = url.openConnection();
		//转换成HttpURL
		HttpURLConnection httpConn = (HttpURLConnection) conn;
		//打开输入输出的开关
		httpConn.setDoInput(true);
		httpConn.setDoOutput(true);
		//设置请求方式
		httpConn.setRequestMethod("POST");
		//设置请求的头信息
		httpConn.setRequestProperty("Content-type", "text/xml;charset=UTF-8");
		//拼接请求消息
		String data = "<soapenv:Envelope xmlns:soapenv=" +
				"\"http://schemas.xmlsoap.org/soap/envelope/\" " +
				"xmlns:q0=\"http://server.rl.com/\" " +
				"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
				"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
				+"<soapenv:Body>"
				+"<q0:sayHello>"
				+"<arg0>renliang</arg0> "
			  +"</q0:sayHello>"
			  +"</soapenv:Body>"
			  +"</soapenv:Envelope>";
		//获得输出流
		OutputStream out = httpConn.getOutputStream();
		//发送数据
		out.write(data.getBytes());
		//判断请求成功
		if(httpConn.getResponseCode() == 200){
			//获得输入流
			InputStream in = httpConn.getInputStream();
			//使用输入流的缓冲区
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			StringBuffer sb = new StringBuffer();
			String line = null;
			//读取输入流
			while((line = reader.readLine()) != null){
				sb.append(line);
			}
			//创建sax的读取器
			SAXReader saxReader = new SAXReader();
			//创建文档对象
			Document doc = saxReader.read(new StringReader(sb.toString()));
			//获得请求响应return元素
			List<Element> eles = doc.selectNodes("//return");
			for(Element ele : eles){
				System.out.println(ele.getText());
			}

3.复杂消息请求(***)

@WebService
public class TestComplexServer {
	
	List<Person> pList = new ArrayList<Person>();
	
	public void addPerson(Person person){
		pList.add(person);
	}
	
	public List<Person> getPersonList(){
		return pList;
	}
	
	public static void main(String[] args) {
		Endpoint.publish("http://192.168.1.104:8888/person", new TestComplexServer());
	}
}

8.消息体(重要**

1) SOAP1.1请求消息体

POST /WebServices/MobileCodeWS.asmx HTTP/1.1

Host: webservice.webxml.com.cn

Content-Type: text/xml; charset=utf-8

Content-Length: length

SOAPAction:"http://WebXml.com.cn/getMobileCodeInfo"

<?xml version="1.0"encoding="utf-8"?>

<soap:Envelopexmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="    ">

  <soap:Body>

   <getMobileCodeInfo xmlns="http://WebXml.com.cn/">

     <mobileCode>string</mobileCode>

     <userID>string</userID>

   </getMobileCodeInfo>

  </soap:Body>

</soap:Envelope>

2)  SOAP1.1响应消息体

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?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>
    <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/">
      <getMobileCodeInfoResult>string</getMobileCodeInfoResult>
    </getMobileCodeInfoResponse>
  </soap:Body>
</soap:Envelope>

9.使用myeclipse查看消息体(监听器:用于查看请求和相应的消息)



创建代理服务器的时候:

Local monitoring port :代理服务器的端口

Host name :被代理的主机地址

Port:被代理的服务的端口

Type:被代理服务器的网络传输的协议(不要选HTTP,使用TCP/IP)

Timeout:创建后代理延迟几秒后自动启动



















 
  














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值