模型组合工作流之Web Service服务项目构建、发布、测试

前言

  在一些业务场景中,可能会出现系统为用户提供一系列选择,然后用户自定义好执行流程后交给系统执行。由于用户的组合多种多样,且执行时前后具有依赖关系,因此无法使用常用的方法,如前端向后台发送任务、执行后返回,再继续下一个任务,而是前端构建好一个流程,再交给后台统一执行,避免前后端为完成一个大任务多次地向后台发送请求。针对地理模型计算流程而言,就是这样的场景。

下面以实现地理模型计算流程为例,阐述其技术思路。
1. 发布单个地理模型的WSDL文件;【本篇博客主讲内容】
2. 根据用户提供的流程拼接WSDL文件,形成一个流程WSDL文件;
3. 发布流程WSDL文件;
4. 通过HTTP SOAP方法调用并执行发布的流程WSDL文件(实际是通过该文件逐一调用单个WSDL文件)

0、术语介绍

  • Web Service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的交互操作的应用程序。
  • WSDL:Web服务描述语言(Web Services Description Language)是为描述Web服务发布的XML格式。WSDL描述Web服务的公共接口。这是一个基于XML的关于如何与Web服务通讯和使用的服务描述;也就是描述与目录中列出的Web服务进行交互时需要绑定的协议和信息格式。
  • Apache CXF:是一个开源的 Services 框架,CXF 可以帮助利用Frontend编程API来构建和开发 Services,像 JAX-WS。Apache CXF 的前身叫 Apache CeltiXfire,继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。

1、发布地理模型的Web Service

1.1、创建maven多模块项目框架

  由于地理模型有其适用的领域,如数字土壤制图有其里面常用的方法、数字地形分析有其常用的方法,因此需要将不同地理模型领域分为各个模块,易于管理。
  多模块项目通常由一个父模块和若干个子模块构成,每个模块都对应着一个pom.xml。它们之间通过继承和聚合(也称作多模块)相互关联。多模块适用于一些比较大的项目,通过合理的模块拆分,实现代码的复用,便于维护和管理。
  以IDEA为例,以应用spring-boot框架的前提构建maven多模块项目。
图片1:用spring initializr创建父项目模块

图片2:备用构建链接

图片3:填写项目基本信息

图片4:选择开发工具与spring web service依赖
图片5:填写项目名称与位置、模块名称
图片6:初始项目结构(含父模块)

图片7:用Maven创建主模块
图片8:填写主模块信息
图片9:将父模块中的src迁移到主模块中

图片10:用图片7的方式创建空的子模块

1.2、使用spring-boot+CXF实现Web Service的架构

  当前一个空的多模块项目就创建好了,接下来需要往里面配置web service的相关依赖。但在此之前仍需要稍微了解一下多模块配置的相关信息。

  多模块项目中,父模块打包类型必须是pom,同时以给出所有的子模块,其中每个module,都是另外一个maven项目。子pom可以继承父pom中的各项配置,因此父pom可以对子pom进行统一的配置和依赖管理。

  一般在项目最顶层的父pom中使用dependencyManagement元素,这让所有子模块都能够引用一个依赖而不用显式的列出版本号。maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用在这个dependencyManagement元素中指定的版本号。

  官方推荐使用application.yml文件代替application.properties。优点是yml文件可以使用结构化的编写。

  接着1.1节创建的多模块项目配置开发依赖。

图片11:主模块中需要的资源文件

图片12:主模块中程序入口的配置
图片13:主模块中spring-boot总配置

图片14:主模块中pom文件的依赖配置
图片15:子模块xml的bean初始化与cxf导入
图片16:父模块pom文件中子模块的统一依赖配置
图片17:父模块pom文件中的基础依赖配置
webservice父模块pom文件通用配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
    <module>ws-egc</module>
	<module>ws-hsm</module>
</modules>
<!--spring-boot框架-->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.4.0</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.egc</groupId>
<artifactId>webservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>webservice</name>
<description>Demo project for Spring Boot</description>

<properties>
	<maven.compiler.source>1.8</maven.compiler.source>
	<maven.compiler.target>1.8</maven.compiler.target>
	<boot.version>2.2.7.RELEASE</boot.version>
	<log4j2.version>2.11.1</log4j2.version>
	<cxf.version>3.3.6</cxf.version>
	<wsdl4j.version>1.6.3</wsdl4j.version>
	<commons-lang3.version>3.5</commons-lang3.version>
	<commons-exec.version>1.3</commons-exec.version>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<java.version>1.8</java.version>
</properties>

<dependencyManagement>
	<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.geronimo.specs/geronimo-jaxws_2.2_spec -->
		<dependency>
			<groupId>org.apache.geronimo.specs</groupId>
			<artifactId>geronimo-jaxws_2.2_spec</artifactId>
			<version>1.2</version>
		</dependency>
	</dependencies>
</dependencyManagement>

<dependencies>
	<!--  否则报错 java.lang.NoSuchMethodError:javax.validation.BootstrapConfiguration.getClockProvider     -->
	<dependency>
		<groupId>javax</groupId>
		<artifactId>javaee-api</artifactId>
		<version>8.0</version>
		<scope>provided</scope>
	</dependency>
	<!-- 帮助开发人员消除Java的冗长代码 -->
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<version>1.16.16</version>
		<scope>provided</scope>
	</dependency>
	<!--spring-boot-->
	<!--配置spring的框架-->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-actuator</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-validation</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
	<!--用于ConfigurationProperties-->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-configuration-processor</artifactId>
		<optional>true</optional>
		<scope>compile</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
		<!--排除默认的logback-->
		<exclusions>
			<exclusion>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-starter-logging</artifactId>
			</exclusion>
		</exclusions>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-log4j2</artifactId>
	</dependency>
	<!-- CXF SOAP webservice -->
	<!--配置cxf框架-->
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
		<version>${cxf.version}</version>
	</dependency>
	<!-- CXF REST webservice -->
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
		<version>${cxf.version}</version>
	</dependency>
	<!-- cxf-rt-rs-service-description -->
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-rs-service-description</artifactId>
		<version>${cxf.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-features-logging</artifactId>
		<version>${cxf.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-rs-extension-providers</artifactId>
		<version>${cxf.version}</version>
	</dependency>
</dependencies>

<build>
	<plugins>
		<!--添加spring-boot的插件-->
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>
</project>

图片18:将该框架托管到码云上

1.3、在子模块中创建具体服务

  在子模块中的实现遵循接口-实现的模式,避免把所有东西都放在同一个文件,增强灵活性。
图片19:子模块的结构

DomainASerive接口

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;
//注入SOAP绑定类型
@BindingType(SOAPBinding.SOAP11HTTP_BINDING)
//注入标识该接口为@WebService类型,同时指定目标的命名空间
@WebService(targetNamespace = "http://test.org/ws/DomainAService")
public interface DomainAService {
//为每个方法都注入标识为@WebMethod类型,同时指定action标识
	@WebMethod(action = "http://test.org/ws/DomainAService/geoModelOne")
	//注入返回的结果为result
	@WebResult(name = "result")
	//为每一个参数都指定@WebParam,为的是能够填写访问时的名字,否则默认名字为arg0, arg1,不以利于阅读
	String geoModelOne(@WebParam(name = "inputPath")String inputPath,
                           @WebParam(name = "outputPath")String outputPath);
}

DomainASeriveImp实现

import org.egc.ws.hsm.DomainAService;
import org.springframework.stereotype.Service;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;
//spring-boot注入,标识这是一个Service类型的Bean
@Service
//注入SOAP绑定类型
@BindingType(SOAPBinding.SOAP11HTTP_BINDING)
//与接口相同注入标识该接口为@WebService类型,定义命名空间的同时定义服务的名称
@WebService(serviceName = "DomainAService", targetNamespace = "http://test.org/ws/DomainAService")
public class DomainAServiceImpl implements DomainAService {
	@Override
	public String geoModelOne(String inputPath, String outputPath) {
    return null;
	}
}

图片20:ws-hsm模块的services.xml配置
图片21:启动服务
图片22:通过浏览器查看服务列表
图片23:服务节点的wsdl

1.4、通过SOAPUI测试发布的web service

  SOAPUI是一个开源测试工具,通过soap/http来检查、调用、实现Web Service的功能/负载/符合性测试。其能根据WSDL生成SOAP数据包,手工填入参数后可以直接进行性能测试,同时能够捕捉SOAP请求和响应、创建测试请求、测试用例并且提供仿真的服务。
图片24:使用SOAPUI模拟客户端测试wsdl是否正常


  至此,单个web service文件测试完毕,完成了地理模型wsdl的实现。
  接下来就是怎么把这些单个的wsdl文件拼接起来,实现思路2:构建流程WSDL文件。

1.5、参考资料

1、【IDEA无法访问spring-boot模板网站】
2、【创建springboot多模块项目】
3、【dependencyManagement的用法】
4、【application.yml与application.properties的区别】
5、【application.yml与application-dev.yml的区别】
6、【SpringBoot整合CXF框架开发】
7、【通过java代码执行exe文件】
8、【markdown文件插入图片】
9、【Apache CXF 简介】
10、【用idea创建项目并上传到码云】
11、【SoapUI的使用】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Oruizn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值