本文中主要是描述的WebService的相关内容,从初步的使用,Socket比较,以及在项目中的技术选型等方面做出详细的分析,并且给出实例与代码片段:
1、初步使用Socket实现两个项目之间的信息通讯
利用线程开发Socket的服务端,利用简单的代码实现Socket的客户端(属于Java的基础知识范畴)
在开发之前,首先需要理解的两个网络协议,也就是在大学本科和考研都必须学习的计算机网络中的两个重要协议:TCP和UDP协议:Tcp:是一种传输层协议,是一种面向连接的协议,经过三次握手客户端和服务端机建立了一个连接(通道)。优点:Tcp传输数据时稳定。
- Udp:(点对点的协议)是一种传输层协议,是一种数据报协议,速度是很快的,但是不稳定的。它是面向非连接的协议,它不与对方建立稳定的连接,而是直接就把数据包发送过去。
所以一般情况下,为了保证数据的传输安全以及稳定性能的要求会选择使用TCP协议:
首先编写一个Runnable线程类实现Runnable接口:
1、SocketServerRunnable.java
//保证Socket的服务端一直持续运行(暂时没有对性能做出优化)
public class SocketServerRunnable implements Runnable {
//全局声明Socket套接字
private Socket socket;
public SocketServerRunnable (Socket socket) {
}
@Override
public void run() {
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
//开启一个新的线程
//新线程处理内容就是,接收客户端请求数据,向客户端发送数据
dataInputStream = new DataInputStream(socket.getInputStream());
//客户端发送接收到的城市名称
String message = dataInputStream.readUTF();
System.out.println("the message from client ... " + message);
//...进行一系列的业务处理完成后得到了result结果回传给Client端
String result = "It`s the result from client to server";
//向客户端回应对应数据的天气信息
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(message + ":================" +result);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
dataInputStream.close();
dataOutputStream.close();
//服务端不会主动关闭
//客户端关闭socket
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
2、SocketServer.java
//开发Socket服务端类
private static ServerSocket serverSocket = null;
private static Socket socket = null;
public static void main(String[] args) throws IOException {
//创建socket服务端
//应用服务端口建议在1万以上
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("Start the Socket server Service ...");
while(true){
try {
//接收客户端链接
//阻塞方法
socket = serverSocket.accept();
//开户一个新线程
//新线程处理内容就是,接收客户端请求数据,向客户端发送数据
//可以使用线程池
//使用ThreadPoolExecutor
new Thread(new SocketServerRunnable(socket)).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3、SocketClient.java
//Socket客户端
public class SocketClient {
public static void main(String[] args) throws UnknownHostException, IOException {
//创建socket链接
Socket socket = new Socket("127.0.0.1",12345);
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
//向服务端发送数据
dataOutputStream = new DataOutputStream(socket.getOutputStream());
String message= "message from client";
dataOutputStream.writeUTF(message);
System.out.println("send Message to Server By Client " + message);
//接收服务端数据
dataInputStream = new DataInputStream(socket.getInputStream());
String result = dataInputStream.readUTF();
System.out.println("from server ..."+result);
} catch (Exception e) {
e.printStackTrace();
} finally {
dataOutputStream.close();
dataInputStream.close();
socket.close();
}
}
}
利用了Socket套接字开发的程序必须要去报两点:
- 2、Java中的WebService的三种规范(摘自百度百科)
JAVA 中共有三种WebService规范,分别是JAX-WS(JAX-RPC)、JAXM&SAAJ、JAX-RS。- JAX-WS 的全称为 Java API for XML-Based Webservices ,早期的基于SOAP 的JAVA 的Web 服务规范JAX-RPC(Java API For XML-Remote Procedure Call)目前已经被JAX-WS 规范取代。从java5开始支持JAX-WS2.0版本,Jdk1.6.0_13以后的版本支持2.1版本,jdk1.7支持2.2版本。Jaxws开发的webservice传输soap协议。
- JAXM(JAVA API For XML Message)主要定义了包含了发送和接收消息所需的API,SAAJ(SOAP With Attachment API For Java,JSR 67)是与JAXM 搭配使用的API,为构建SOAP 包和解析SOAP 包提供了重要的支持,支持附件传输等,JAXM&SAAJ 与JAX-WS 都是基于SOAP 的Web 服务,相比之下JAXM&SAAJ 暴露了SOAP更多的底层细节,编码比较麻烦,而JAX-WS 更加抽象,隐藏了更多的细节,更加面向对象,实现起来你基本上不需要关心SOAP 的任何细节
- JAX-RS 是JAVA 针对REST(Representation State Transfer)风格制定的一套Web 服务规范,由于推出的较晚,该规范(JSR 311,目前JAX-RS 的版本为1.0)并未随JDK1.6 一起发行。
- 3、自主开发WebService服务,并且使用自主开发的客户端实现功能(Java)
- 本文中使用的例子源于老师课堂讲授(以此声明,非个人所创);
/** * 1、根据城市信息查询天气信息 * @author YQ * */
public interface WeatherInterface {
//根据城市名称查询天气信息
public String queryWeather(String cityName);
}
//2、使用webService标记该类为webService的服务类
@WebService
//使用@BindingType控制发布soap1.2
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public class WeatherInterfaceImpl implements WeatherInterface{
@Override
public String queryWeather(String cityName) {
System.out.println("the cityName from client ..."+cityName);
//使用静态数据
String result = "天气-晴朗;温度适宜";
//向客户端返回数据
System.out.println("to client ..."+result);
return result;
}
}
//3、发布Server服务
public class WeatherServer {
public static void main(String[] args) {
//发布天气查询服务
//第一个参数:是webService的地址,也就是入口地址
//第二个参数:使用@webService标记的服务对象
Endpoint.publish("http://127.0.0.1:12345/weather", new WeatherInterfaceImpl());
}
}
重点关注1:Service
<service name="WeatherInterfaceImplService">
<port name="WeatherInterfaceImplPort" binding="tns:WeatherInterfaceImplPortBinding">
<soap12:address location="http://127.0.0.1:12345/weather"/>
</port>
</service>
重点关注2:Binding
<binding name="WeatherInterfaceImplPortBinding" type="tns:WeatherInterfaceImpl">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="queryWeather">
<input>
<soap12:body use="literal"/>
</input>
<output>
<soap12:body use="literal"/>
</output>
</operation>
</binding>
重点关注3:PortType
<portType name="WeatherInterfaceImpl">
<operation name="queryWeather">
<input wsam:Action="http://server.socket.jaxws/WeatherInterfaceImpl/queryWeatherRequest" message="tns:queryWeather"/>
<output wsam:Action="http://server.socket.jaxws/WeatherInterfaceImpl/queryWeatherResponse" message="tns:queryWeatherResponse"/>
</operation>
</portType>
开始客户端的开发 :首先使用的是wsimport的命令生成对应的java类:
wsimport -s . http://127.0.0.1:12345/weather?wsdl
wsimport -p //可以实现包名的自定义操作
客户端代码,方式一:
public class WeatherClientSimple {
public static void main(String[] args) throws MalformedURLException {
//使用JDK中的标准方法webService
//第一种使用Service创建服务视图
//wsdl路径
URL wsdDocumentLocation = new URL("http://127.0.0.1:12345/weather?wsdl");
//从wsdl中找到服务视图
//第一个参数:wsdl命名空间 http://server.socket.jaxws/
//第二个参数:服务视图名称
QName serviceName = new QName("http://server.socket.jaxws/","WeatherInterfaceImplService");
Service service = Service.create(wsdDocumentLocation, serviceName);
//从服务视图中获取portType对象
WeatherInterfaceImpl weatherInterfaceImpl = service.getPort(WeatherInterfaceImpl.class);
//调用portType的方法
String result = weatherInterfaceImpl.queryWeather("北京");
System.out.println(result);
}
}
客户端代码,方式二:
public class WeatherClient {
public static void main(String[] args) {
//创建服务视图对象
WeatherInterfaceImplService weatherInterfaceImplService =
new WeatherInterfaceImplService();
//通过服务视图portType(接口类型)
WeatherInterfaceImpl weatherInterfaceImpl =
weatherInterfaceImplService.getWeatherInterfaceImplPort();
//调用service方法
String result = weatherInterfaceImpl.queryWeather("郑州");
System.out.println(result);
}
}
- 4、WebSerivce中的理论支持
- Webservice即web 服务,是一种跨平台的远程调用技术,基于http的soap协议传输数据,也可以直接使用http传输数据。
- Web service 即web服务,它是一种跨编程语言和跨操作系统平台的远程调用技术即跨平台远程调用技术。
- 采用标准SOAP(Simple Object Access Protocol) 协议传输,soap属于w3c标准。Soap协议是基于http的应用层协议,soap协议传输是xml数据。
- 采用wsdl作为描述语言即webservice使用说明书,wsdl属w3c标准。
- xml是webservice的跨平台的基础,XML主要的优点在于它既与平台无关,又与厂商无关。
- XSD,W3C为webservice制定了一套传输数据类型,使用xml进行描述,即XSD(XML Schema Datatypes),任何编程语言写的webservice接口在发送数据时都要转换成webservice标准的XSD发送。
- 当前非SOAP协议的webService以轻量为首要目标,比如rest webservice也是webservice的一种方式。
WebService 三要素:
- 1、soap
soap协议是webservice是传输协议,即简单对象访问协议。Soap协议是xml格式,理解为基于http传输xml数据。(Soap=http+xml)
- 2、wsdl
wsdl是webservice的使用说明书。根据wsdl去如何调用webservice。从下往上读,找到service服务视图,通过binding找到portType(服务类)。
- 3、UDDI是一个目录服务,存储了全球的webservice地址。
5、WebService与其他中间件技术的简单比较,项目中技术选型的方向
- Socket:是一种传输层的协议。常使用的协议主要是TCP、UDP两种协议。Socket是操作系统提供的一套网络接口,不同的编程语言都有实现 。Socket是跨平台的。传输数据时需要程序员自己解析数据流。
- 优点 :传输速度很快。
- 应用场景:如果要考虑传输速度,优先使用Socket
Webservice使用soap协议:基于http的应用层协议,http属于的是应用层协议,主要基于的还是socket传输数据。http或soap都是跨平台的。soap在http协议的基础上,一个基于XML的协议。
- 不同:都是底层的通信协议,请求包的格式不同而已,soap包是XML格式,http纯文本格式。Jaxws开发Webservice,传输数据库是面向对象方式,不用程序员自己解析数据流。
- 技术选型参考:
- WebService的缺点:因为webservice要经过两次序列化,传输速度不快。
- WebService的优点:面向对象 开发,soap协议是一个标准协议,方便进行跨平台、跨公司进行接口开发。
- 应用场景参考:不考虑传输速度前提下,根据soap标准协议,方便进行接口定义,使用WebService是比较妥当的选择。同构程序间通信可以不用webservice,前提是多个同构程序是相同的公司开发的。比如:同一家公司使用相同的技术并且采用了相同的语言开发了两套系统比如淘宝,采用java提供一个远程调用技术,RMI。RMI 指的是远程方法调用 (Remote Method Invocation)。
- 传输速度比较:Socket>RMI>soap