初识SOAP
SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换。或者更简单地说:SOAP 是用于访问网络服务的协议。
- SOAP 指简易对象访问协议
- SOAP 是一种通信协议
- SOAP 用于应用程序之间的通信
- SOAP 是一种用于发送消息的格式
- SOAP 被设计用来通过因特网进行通信
- SOAP 独立于平台
- SOAP 独立于语言
- SOAP 基于 XML
- SOAP 很简单并可扩展
- SOAP 允许您绕过防火墙
- SOAP 将被作为 W3C 标准来发展
构建demo
demoe结构
demo的项目结构大致如下
关键依赖
既然是spring与cxf的集成,这里则需要添加cxf的依赖到我们的pom文件中(spring以及其他的依赖此处省略),cxf的依赖如下:
1 2 3 4 5 6 7 8 9 10 11 12
| <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.1.12</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.1.12</version> </dependency> </dependencies>
|
server端
web.xml文件配置
由于是用cxf,所以需要在web.xml中使用CXFServlet,如下是相关配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring_soapserver_basic.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<servlet> <servlet-name>CXF</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CXF</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
|
webservice接口定义及实现
这里我们可以自定义我们的服务在wsdl文件中暴露在外的请求参数,服务名,以及返回类型值等信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.soapserver.service;
import com.soapserver.entity.Result; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.ws.BindingType; import javax.xml.ws.soap.SOAPBinding;
@WebService(targetNamespace = "selfNamespace") @BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) public interface HelloSoap { @WebMethod(operationName = "HelloSoap") @WebResult(name = "response") Result helloSoap(@WebParam(name = "NAME") String name, @WebParam(name = "GREETING") String greeting); }
package com.soapserver.service.impl;
import com.soapserver.entity.Result; import com.soapserver.service.HelloSoap; import org.springframework.stereotype.Service;
import javax.jws.WebService;
@Service("HelloSoapImpl") @WebService(targetNamespace = "selfNamespace", serviceName = "HelloSoapService") public class HelloSoapImpl implements HelloSoap {
@Override public Result helloSoap(String name, String greeting) { return new Result(0, greeting + "," + name); } }
|
spring配置
服务端的sping配置中需要配置我们要暴露的请求路径以及service。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.soapserver.service"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan>
<jaxws:server address="/helloSoap"> <jaxws:serviceBean> <ref bean="HelloSoapImpl"/> </jaxws:serviceBean> </jaxws:server> </beans>
|
WSDL
待简单的demo集成后,并且发布成功,我们就可以访问我们定义好的url: http://localhost:8080/server/hellosoap?wsdl 来查看我们的webservice的wsdl文件,通过分析该文件,可以很容的出服务端的服务相关信息,并因此来定义客户端的请求。本demo的wdsl信息如下:
client端
webservice接口定义
客户端请求接口是需要分析服务端wsdl中暴露的信息来定义的。本demo的定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.soapclient.service; import com.soapclient.entity.Result; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.ws.BindingType; import javax.xml.ws.soap.SOAPBinding;
@WebService(targetNamespace = "selfNamespace") @BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) public interface HelloSoap { @WebMethod(operationName = "HelloSoap") @WebResult(name = "response") Result helloSoap(@WebParam(name = "NAME") String name, @WebParam(name = "GREETING") String greeting); }
|
spring配置
客户端的spring配置中需要配置服务端的请求地址信息,配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="request" address="http://localhost:8080/server/helloSoap" serviceClass="com.soapclient.service.HelloSoap"> </jaxws:client> </beans>
|
main函数
本demo是用main方式打jar包来发布客户端,当然,我们也可以将我们的客户端请求集成到springmvc中,通过war包的形式来发布。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.soapclient.main;
import com.soapclient.entity.Result; import com.soapclient.service.HelloSoap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main { private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring_soapclient_basic.xml"); HelloSoap helloSoap = (HelloSoap) context.getBean("request", HelloSoap.class); Result result = helloSoap.helloSoap("girl", "hello"); LOGGER.info("result: {} ; {}", result.getResult(), result.getDescription()); } }
|