“ 使用Spring Boot调用WebService接口是一个项目上的一个需求,甲方要求我们做一个对外的在线测评页面,但是我们公司的产品是在内网下,所以甲方提供一台服务器将一个端口映射到外网,由于仅仅是一个在线测评的功能所以尽可能高效的开发出来,于是Spring Boot便有用武之地了”
这里我就不谈客户的需求了,反正最终设计的方案是使用Spring Boot开发一个新的系统和OA进行交互,交互方式就是将用户在前端界面上提交测评的数据处理后,再调用OA提供的WebServices接口将数据进行回写。关于Spring Boot我就不多说了,但什么是WebService呢?如何调用WebService呢?
01
—
我个人理解WebService主要是用于提供服务的,而且允许跨编程语言和操作平台,所以我们可以用任何我们喜欢的语言和平台上写Web service ,我们可以通过WebService标准对这些服务进行查询和访问。这跟我们经常谈及到的面向服务(SOA)类似,事实上,WebService就是是实现SOA的方式之一。
一开始的时候我很好奇如何去构建一个webservice应用,在百度百科上面是这样的回答的:
Web Service平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和类型系统。要实现互操作性,Web Service平台必须提供一套标准的类型系统,用于沟通不同平台、编程语言和组件模型中的不同类型系统。这些协议主要有:
一:XML和XSD
XML我们都很熟悉了,是一门可扩展的标记语言,跟HTML用于格式化并显示数据不同的是,XML的作用大多都是用来结构化、存储以及传输信息,主要的优点在于它既与平台无关,又与厂商无关。
XSD我个人也是在使用WebService的时候听说的,Web Service平台是用XSD来作为数据类型系统的。当你用某种语言如VB. NET或C# 来构造一个Web Service时,为了符合Web Service标准,所有你使用的数据类型都必须被转换为XSD类型。如想让它使用在不同平台和不同软件的不同组织间传递,还需要用某种东西将它包装起来。这种东西就是一种协议,如 SOAP。
二:SOAP
SOAP是一种即简单对象访问协议(Simple Object Access Protocol),是用于交换XML编码信息的轻量级协议。这里我们区分一下HTTP,http是标准超文本传输协议,而SOAP借助于XML,提供了HTTP所需的扩展
三:WSDL
如果你接触WebService对于wsdl我想你是很熟悉的,wsdl是用于描述Web Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,换句话说它是基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问。
关于Web Service的概念就先写到这里,大家可以在网上查阅到很多关于WebService的东西,只不过相对于比较成熟WebService,现在流行的还是RestFul架构。
下面我们具体来看Spring Boot如何创建和调用WebService接口。
首先引入依赖
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.12</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.12</version>
</dependency>
不是Spring Boot项目我们可以引入响应的jar包。引入完依赖以后我们就开始写一个接口了,@WebService用于对接口,类进行注解,表示要发布的web服务,@WebMethod 注释表示作为一项 Web Service 操作的方法,此外 仅支持在使用 @WebService 注释来注释的类上使用 @WebMethod 注释
@WebService
public interface WSAPI {
@WebMethod
String getInfo();
}
对外的接口定义完之后,我们就简单的实现它,targetNamespace是指定你想要的名称空间,一般是使用接口实现类的包名,endpointInterface是服务接口全路径, 指定做SEI(Service EndPoint Interface)服务端点接口。这个方法我们只返回一个字符串。
(endpointInterface路径一定要写正确,不然启动会一直报错)
@WebService(targetNamespace = "http://com.baj.online.api/",
endpointInterface = "com.baj.online.api.WSAPI")
public class WSImp implements WSAPI {
public WSImp(){
}
@Override
public String getInfo() {
return "每天学Java";
}
}
做到这一步我们就定义好了一个webservice接口,此时我们要做的就是发布出去。
@Configuration
public class WSConfig {
//默认servlet路径/*,如果覆写则按照自己定义的来
@Bean
public ServletRegistrationBean cxfServlet() {
return new ServletRegistrationBean(new CXFServlet(),
"/webservice/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
//把实现类交给spring管理
@Bean
public WSAPI webService() {
return new WSImp();
}
//终端路径
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(),webService());
endpoint.publish("/test");
return endpoint;
}
}
我们启动看一下,在浏览器输出http://127.0.0.1:82/webservice/。路径是cxfServlet方法中定义好的
我们会看到getInfo这个方法,以及Endpointaddress,和wsdl。我们点击{http://com.baj.online.api/}WSImpService
这就是WSDL文件了,上面标签我们就不研究了,只需要知道这要就算发布成功了,下面就是调用了:
public void testSend1() {
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client =
dcf.createClient("http://127.0.0.1:82/webservice/test?wsdl");
// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
Object[] objects = new Object[0];
try {
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("getInfo");
System.out.println("返回数据:" + objects[0]);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}
需要注意的是createClient路径是http://127.0.0.1:82/webservice/test?wsdl以及client.invoke的第一参数是方法名,一开始我把它当作参数,一直没有结果返回。
这样我们使用Spring Boot简单创建了一个接口以及调用