【WebService】带你走进webservice的世界
1. webservice是啥 准确的来说,webservice不是一种技术,而是一种规范。是一种跨平台,跨语言的规范,用于不同平台,不同语言开发的应用之间的交互。 2. 重温socket在分析如何调用webservice前,先来回忆一下传统的socket是如何通信的,这样更容易理解ws。 2.1 基于socket创建web服务为什么要使用socket呢?看一下下面的原理图: 2.2 经典的socket服务客户端: /** * @Description Socket客户端,用来发送给服务端请求 * @author Ni Shengwu * */
public class SocketClient {
public static void main(String[] args) throws Exception {
Scanner input = new Scanner(System.in);
// 1: 创建一个基于TCP协议的socket服务,在建立对象时,要指定连接服务器和端口号
Socket sc = new Socket("127.0.0.1",9999);
// 2: 通过建立的Socket对象获取Socket中的输出流,调用getOutStream方法
OutputStream out = sc.getOutputStream();
System.out.println("请输入要转化的字母:");
String initData = input.next();//获取控制台的输入
// 3: 写入到Socket输出流中
out.write(initData.getBytes());
System.out.println("等待服务器端返回数据");
// 4: 通过建立的Socket对象获取Socket中的输入流,输入流会接受来自服务器端数据
InputStream in = sc.getInputStream();
byte[] b = new byte[1024];
// 5: 获取输入字节流的数据,注意此方法是堵塞的,如果没有获取数据会一直等待
int len = in.read(b);
System.out.println("返回的结果为:" + new String(b,0,len));
// 关闭Socket
out.close();
in.close();
sc.close();
input.close();
}
}
服务端: /** * @Description Socket服务端,用来接收客户端请求,实现转大写功能 * @author Ni Shengwu * */
public class SocketServer {
public static void main(String[] args) throws Exception {
// 1:建立服务器端的tcp socket服务,必须监听一个端口
ServerSocket ss = new ServerSocket(9999);
while(true) {
System.out.println("等待客户端请求……");
// 2: 通过服务器端的socket对象的accept方法获取连接上的客户端对象,没有则堵塞,等待
Socket socket = ss.accept();
System.out.println("握手成功……");
// 3: 通过输入流获取数据
InputStream input = socket.getInputStream();
byte[] b = new byte[1024];
int len = input.read(b);
String data = new String(b,len);
System.out.println("客户端数据为:" + data);
// 4: 通过服务器端Socket输出流,写数据,会传送到客户端Socket输入流中
OutputStream out = socket.getOutputStream();
out.write(data.toUpperCase().getBytes());
// 5: 关闭socket
out.close();
input.close();
socket.close();
}
}
}
这个demo很简单,先开启服务端的程序,在那等待,然后开启客户端程序,如果在控制台输入hello过去,就会从服务端返回一个HELLO回来,这说明socket通信是成功的。 2.3 web程序访问socket service上面经典的demo是在本地写的两个java程序,我们现在的很多项目都是web项目,也就是通过浏览器来交互的,我们来看下通过浏览器的方式如何来访问socketService服务。服务端还是使用上面的那个java程序,客户端我改成浏览器请求,新写一个jsp如下: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<form action="http://127.0.0.1:9999" method="post">
<input type="text" name="sname">
<input type="submit" value="提交">
</form>
</body>
</html>
注意看action的请求地址,包括端口要和服务端的一样,这样当我们提交的时候就可以访问上面的服务端程序了。看一下服务端的运行结果: 3. 调用已发布的WebService 关于webservice本身,我就不做过多的描述了,在最上面也有简单介绍,既然传统的socket通信无法满足,那么下面开始来调用已发布的ws,真正走进ws的世界。 3.1 get请求方式 在java程序中如果要发送http请求,需要使用HttpClient工具。HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。 /** * @Description get方式请求 * @param number * @throws Exception */
public void get(String number) throws Exception {
//HttpClient:在java代码中模拟Http请求
// 创建浏览器对象
HttpClient client = new HttpClient();
// 填写数据,发送get或者post请求
GetMethod get = new GetMethod("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx"
+ "/getMobileCodeInfo?mobileCode=" + number + "&userID=");
// 指定传输的格式为get请求格式
get.setRequestHeader("Content-Type","text/xml; charset=utf-8");
// 发送请求
int code = client.executeMethod(get);
System.out.println("Http:状态码为:" + code);
String result = get.getResponseBodyAsString();
System.out.println("返回的结果为:" + result);
}
从程序中可以看出,请求的主机是ws.webxml.com.cn,这些url在ws提供方的网站上都有,我们只需要写对即可请求ws了,在main方法中调用一下该方法即可在控制台获取结果。 3.2 post请求方式请求的过程都一样,只是url和传输格式不同而已,修改一下相应的地方即可, /** * @Description post方式请求 * @param number * @throws Exception */
public void post(String number) throws Exception {
//HttpClient:在java代码中模拟Http请求
// 创建浏览器对象
HttpClient client = new HttpClient();
// 填写数据,发送get或者post请求
PostMethod post = new PostMethod("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx/getMobileCodeInfo");
// 指定传输的格式为默认post格式
post.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 传输参数
post.setParameter("mobileCode",number);
post.setParameter("userID","");
// 发送请求
int code = client.executeMethod(post);
System.out.println("Http:状态码为:" + code);
String result = post.getResponseBodyAsString();
System.out.println("返回的结果为:" + result);
}
3.3 SOAP方式请求这也是在用的多的方式,它有两个版本soap1.1和soap1.2,jdk1.7及以上才可以使用soap1.2。 /** * @Description soap post方式请求,但是传输的数据为xml格式,有利于数据的维护 * @param number * @throws Exception */
public void soap(String number) throws Exception {
//HttpClient:在java代码中模拟Http请求
// 创建浏览器对象
HttpClient client = new HttpClient();
// 填写数据,发送get或者post请求
PostMethod post = new PostMethod("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx");
// 指定传输的格式为xml格式
post.setRequestHeader("Content-Type","application/soap+xml;charset=utf-8");
// 传输xml,加载soap.txt
post.setRequestBody(new FileInputStream("E:/github/client/src/soap.txt"));
// 发送请求
int code = client.executeMethod(post);
System.out.println("Http:状态码为:" + code);
String result = post.getResponseBodyAsString();
// 如果采用的是soap,则返回的数据也是基于xml的soap格式
System.out.println("返回的结果为:" + result);
}
由于soap方式需要向服务端发送xml,所以我们可以实现写好一个txt文档,里面是xml的数据,这个模板ws提供方会提供,我们需要写好即可: <?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<getMobileCodeInfo xmlns="http://WebXml.com.cn/">
<mobileCode>18312345678</mobileCode>
<userID></userID>
</getMobileCodeInfo>
</soap12:Body>
</soap12:Envelope>
上面这些方式推荐使用soap的方式,不过本质上还是http方式调用,只是调用的时候可以传输xml数据而已。而且HttpClient是Java的调用http协议的解决方案,但是不能保证其它语言也拥有类似的工具。所以ws推荐的方案是使用wsimport命令。这也是下面分析的重点。 3.4 使用wsimport 每个ws都会有一个WSDL,WSDL即WebService Description Language – Web服务描述语言。它是通过XML形式说明服务在什么地方-地址。通过XML形式说明服务提供什么样的方法 – 如何调用。我们可以通过这个WSDL来获取和这个ws有关的信息,包括class和java代码。关于这个WSDL后面我再具体分析,这一节先来看一下如何使用。 public class _Main {
public static void main(String[] args) {
// 获取一个ws服务
MobileCodeWS ws = new MobileCodeWS();
// 获取具体的服务类型:get post soap1.1 soap1.2
MobileCodeWSSoap wsSoap = ws.getMobileCodeWSSoap();
String address = wsSoap.getMobileCodeInfo("18312345678",null);
System.out.println("手机归属地信息为:" + address);
}
}
这样就很方便了,现在已经完全没有了上面那种连接啊,设置地址啊等等,直接封装好了,我直接调用这些API即可调用远程的webservice。这也是官方推荐的一种方法,当然我们也可以将生成的class文件打包成jar放到工程中。运行一下这个main方法后,也直接返回归属地,没有那些标签的东西了,这才是开发中所需要的东西。 —–乐于分享,共同进步! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |