前提
王二在公司被要求搞一个WebService出来,由于之前也只是浅显的了解了一下WebService是做什么的,没来的及实际操作,所以我懵了。
冷静了一会后,我开始上手了。
开始当然是先看一波文档或者网上别人写的文章,别人写的资料都一个样,王二理解能力有点差(毕竟还是小白),所以一直稀里糊涂没搞懂是啥玩意。
我的学习思维
- 首先先把一个知识点的整体架构搞懂,先把房子的总体构造弄清楚在去深入看造房用的具体材料。
- 闲话不多说,搞懂一个东西,肯定要知道这玩意是什么,能做什么事,有什么优点驱使我们去用。
- 就说这个WebService,我要知道它是用来干啥的,能做什么。如果只是没有方向的学习,那么效率和记忆效果就很差了。
学习第一步
问题:WebService是什么?
WebService是一种可以让我们跨编程语言,跨操作系统给别人或者调用别人的一种技术。
调用的就是服务,也就是我们写的业务逻辑和系统接口等等。
我觉得可以把它和咱们常见的RPC去比较,会发现其实这WebService就是写个服务出来,别人就可以通过你这个服务地址用到你写的业务逻辑,比如写个方法,可以传一个字符串的参数,那你这个服务一上传到网上,别人访问到你这个服务的时候,就可以输入一个字符串进来,调用了这个方法,就会走这个方法,然后相应返回结果。这其实就完成了预期的效果和作用。
学习第二步
看看WebService有哪几个重要的东西构成。
- 插件工厂:维护扩展点和扩展的容器,和Java容器的生命周期一致。(根据plugin.xml的配置,自动把相应的配置信息注册到工厂容器中,以备扩展点的提供方去调用)
- WSDL:网络服务描述语言,用于描述web Service 及 如何对它们进行访问的XML 语言。
- SOAP:一种基于XML的轻量级协议,用于在分布式环境中交换信息,使应用程序通过HTTP来交换信息。
- Apache CXF:一个开源的Services 框架,提供了Frontend编程API构建和开发services,CXF来自于XFire项目,实现了ESB(企业服务总线)。
- JAX-WS规范:提供了一组XML web services 的JAVA API允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。
5.1. 在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP。
5.2. 在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。
5.3. JAX-WS的运行时实现会将这些API的调用转换成为对应的SOAP消息。- MTOM:全称Message Transmission Optimization Mechanism,即消息传输优化机制。使用 MTOM 的目的在于优化对较大的二进制负载的传输,如上传文档和图片等。
解释一把:
- 插件工厂在项目中起到配置WebService的作用,就是配置用的,不用想那么多。
- WSDL是用来描述WebService的,你查看WebService的服务时就要在地址后面加上"?wsdl"这个就可以看到我们服务的一些数据,就是下面这些玩意。
- SOAP是个比较重要的东西了,也和上面说的一样,是一种协议,协议就是用来给我们交换信息用的,有了这个我们就可以在应用程序中交换信息。
- Apache CXF,一大堆人都是用这个CXF框架去创作他们的WebService。所以说,它也就是个框架,采用了JAX-WS规范,那我们就要想到待会可能要导个这种包啥的。
WebService是干啥的,有几个主要的组成部分都知道了就可以开始搞了!
学习第三步
实践:
一、 使用Idea开发一个简单的WebService。
- 先创建一个maven的web项目,取好名字,finish。
- 咱maven的开局第一步当然是导依赖啦!(为了以后可能用到spring,我同样导了很多相关的包)
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf</artifactId>
<version>2.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-bundle -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-bundle</artifactId>
<version>2.7.18</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-javamail_1.4_spec</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.xml.ws/jaxws-api -->
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.7.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
- 导好包就开始整代码,首先在main文件夹下再建一个文件夹用来写我们的Java代码,记得mark一下
项目结构
具体代码:
User:
package entity;
public class User {
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private int id;
private String name;
}
HelloWorld:
package service;
import entity.User;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
//使用WebService的接口类一定要加上这个注解
@WebService
public interface HelloWorld {
String sayHiToUser(User user);
}
HelloWorldImpl:
package service.serviceImpl;
import entity.User;
import service.HelloWorld;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.jws.WebService;
@WebService(endpointInterface= "service.HelloWorld",serviceName="service.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
Map<Integer, User> users = new LinkedHashMap<Integer, User>();
//传出去的方法
public String sayHiToUser(User user) {
users.put(users.size()+1, user);
return "Hello "+ user.getName();
}
}
WebServiceApp :
import service.serviceImpl.HelloWorldImpl;
import javax.xml.ws.Endpoint;
//模拟发布服务
public class WebServiceApp {
public static void main(String[] args) {
System.out.println("web service start");
HelloWorldImpl implementor= new HelloWorldImpl();
String address="http://localhost:8089/helloWorld";
Endpoint.publish(address, implementor);
System.out.println("web service started");
}
}
HelloWorldClient :
import entity.User;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import service.HelloWorld;
//模拟客户端
public class HelloWorldClient {
public static void main(String[] args) {
JaxWsProxyFactoryBean svr = new JaxWsProxyFactoryBean();
svr.setServiceClass(HelloWorld.class);
svr.setAddress("http://localhost:8089/helloWorld");
HelloWorld hw = (HelloWorld) svr.create();
User user = new User();
user.setName("Tony");
//user.setDescription("test");
System.out.println(hw.sayHiToUser(user));
}
}
- 先跑一把WebServiceApp ,发布服务
然后到浏览器输入那个地址:http://localhost:8089/helloWorld?wsdl 注意啦,地址后要加一个"?wsdl"
这样表示我们的服务已经发布了。这些xml形式的代码就是wsdl起到的作用。就是用来描述我们的WebService的服务。
接下来我们去用这个服务,跑一把客户端:
这样就调用了我们服务里面的那个sayHiToUser的方法了。
WebService差不多就是这样,我们这个服务现在是在本地发布的,以后发布到服务器,别人就可以很方便的用到你的服务了。
这里我想说一下测试WebService接口的几个工具,我用了postman和soapui,发现还是soapui好用,建议下载,打开以后直接点击soap
最后点击左上角那个绿色三角形就ok了!简单易懂。
二、使用eclipse开发一个简单的WebService
这是我项目中的,项目中使用WebService就可以使自己的系统和别的系统做一个集成,这样调用别人系统的接口,就可以快速,简单的做系统集成。
步骤:
- 编写一个Spring Bean的实现业务逻辑。
- 在plugin.xml的扩展文件中定义WebService的基础信息。
- 在系统管理模块中点击导入注册的服务信息。
总的来说,就是在Java代码中写好服务的接口和实现类,然后根据模块或者创建一个新模块把这个实现类加入spring的bean去。然后,根据服务信息配置plugin扩展。
<extension
point="com.landray.kmss.sys.webservice2">
<item
name="registry">
<param
name="serviceName"
value="测试例子WebService" />
<param
name="serviceClass"
value="com.landray.kmss.example.news.service.ITestWebService" />
<param
name="serviceBean"
value="testWebService" />
<param
name="serviceDoc" value="" />
</item>
</extension>
启动项目,导入这个WebService就可以出来对应服务了。看不懂这个也没关系,以后有机会进入项目再来看看就懂了。
总结
- WebService总的来说不难,跟我以前写过的一个基于socket实现的简单RPC类似,就是写个服务,让别人调用。
- WebService传输是用SOAP协议,其实就是HTTP+XML,HTTP是铁轨,XML就是火车,这种概念大家有个基本的想法就好了。
- 如果有写的不对的请麻烦大家给王二指出来,不胜感激!