对接WSDL+SOAP服务:xFire替换方案

2024-04-30 04:44

本文主要是介绍对接WSDL+SOAP服务:xFire替换方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

有一个老旧的服务,我需要远程调用它
技术是WSDL + SOAP + webService
.
看到很多同学用的都是xFire。然而,它有漏洞,不让用~。
于是参考了cxf,xFire的新版包。感觉不友好(重点是折腾半天没搞定)

技术岂是如此不便之物?于是从传统方案开始思考:即HTTP,可行~

一、错误的认知

  • webService不是什么别的协议,依旧用的HTTP。
  • 解析WSDL可以和解析json一样,但同理发送请求需要WSDL、SOAP格式。
    (也就是说服务侧,需要提供xml请求响应格式。)

惍!隔壁团队的问题居然没有说清楚!搞得我以为WSDL是一种与HTTP不同的协议

二、postman测试

由于之前就是信心满满的写代码,然后搞不定,浪费了很多时间。
注:请求体、响应体格式需要问对接团队

请求头

在这里插入图片描述

请求体

在这里插入图片描述

响应体

在这里插入图片描述

结论:请求成功(成功)

三:设计Rest远程调用模组

要求:
  1. 同事希望能像调用方法一样调用远程服务
  2. 小领导要求:扩展友好、能用
  3. 我的要求:简单、易维护
项目包结构

简单的远程调用,懒得画图

在这里插入图片描述

四、关键代码

pom文件引用
<dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.13.0</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.16</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.14</version><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>6.1.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version></dependency><!-- xml bean 转换相关包 --><!-- https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api --><dependency><groupId>jakarta.xml.bind</groupId><artifactId>jakarta.xml.bind-api</artifactId><version>4.0.1</version></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>4.0.1</version></dependency><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>4.0.1</version></dependency><!-- aop 切面 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- 单元测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>3.1.2</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.1</version><scope>test</scope></dependency></dependencies>
调用外层

在这里插入图片描述

xml bean 数据结构

外围bean

@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "soap:Envelope")
public class AccountCertXmlResp {@XmlElement(name = "soap:Body")private Body body;@XmlAccessorType(XmlAccessType.FIELD)@Datapublic static class Body {@XmlElement(name = "ns1:accountCertApplyResponse")private AccountCertApplyResponse accountCertApplyResponse;}@XmlAccessorType(XmlAccessType.FIELD)@Datapublic static class AccountCertApplyResponse {@XmlElement(name = "ns1:out")private String out;}}
JaxbUtil xml打包解析工具类
@Slf4j
public class JaxbUtils {/*** xml 转bean** @param data        字符* @param targetClazz bean class* @param <T>         t* @return t*/public static <T> T xmlStrToBean(String data, Class<T> targetClazz) {return xmlStrToBean(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)), targetClazz);}/*** xml 转bean** @param is          输入流* @param targetClazz bean class* @param <T>         t* @return t*/public static <T> T xmlStrToBean(InputStream is, Class<T> targetClazz) {try {JAXBContext jc = JAXBContext.newInstance(targetClazz);Unmarshaller uma = jc.createUnmarshaller();// 忽略命名空间SAXParserFactory sax = SAXParserFactory.newInstance();sax.setNamespaceAware(false);XMLReader xmlReader = sax.newSAXParser().getXMLReader();Source source = new SAXSource(xmlReader, new InputSource(is));return (T) uma.unmarshal(source);} catch (JAXBException e) {log.error("xmlutil ", e);throw new RuntimeException("Deserialization from xml to object error: " + e.getMessage());} catch (ParserConfigurationException e) {throw new RuntimeException(e);} catch (SAXException e) {throw new RuntimeException(e);}}/*** bean 转字符** @param t   bean* @param <T> t* @return 字符*/public static <T> String beanToXml(T t) {StringWriter writer;try {//1、创建上下文JAXBContext context = JAXBContext.newInstance(t.getClass());//从上下文中获取Marshaller对象,用作将bean编组(转换)为xmlMarshaller marshaller = context.createMarshaller();//3、设置marshaller的属性//以下是为生成xml做的一些配置//格式化输出,即按标签自动换行,否则就是一行输出marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//是否省略xml头信息,默认不省略(false)marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);//4、实例化StringWriterwriter = new StringWriter();//5、将实体类读取到writer中marshaller.marshal(t, writer);//6、输出结果return writer.toString();} catch (JAXBException e) {log.error("xmlUtil toString error :", e);throw new RuntimeException(e);}}}
SoapUtil 工具类
@Slf4j
public class SoapUtil {/*** 打包为xml soap协议** @param reqBean   请求对象* @return 打包后的数据*/public static <T> String pkgXml(String operationName,T reqBean) {// 对象转xmlString xml = XmlConst.XML_8 + JaxbUtils.beanToXml(reqBean);// 替换原格式中的:操作名、内容String xmlPkg = XmlConst.SOAP_PKG.replace(XmlConst.OPERATION_NAME, operationName).replace(XmlConst.REQUEST_BODY, xml);log.info("xmlPkg : {}",xmlPkg);return xmlPkg;}}

常量写法
在这里插入图片描述

HTTP请求工具
@Slf4j
public class HttpUtil {static SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();static HttpHeaders headers = new HttpHeaders();static {factory.setReadTimeout(6000);factory.setConnectTimeout(6000);headers.setContentType(MediaType.APPLICATION_XML);}private static final RestTemplate REST = new RestTemplate(factory);/*** 发送Post请求** @param url 地址* @param body 内容* @return 请求结果*/public static String postSoap(String url, Object body) {// 获取操作名String operationName = url.substring(url.lastIndexOf("/") + 1);// 首字母小写operationName = operationName.substring(0,1).toLowerCase() + operationName.substring(1);// 组装请求包String pkgXml = SoapUtil.pkgXml(operationName, body);return post(url, pkgXml);}/*** 发送Post请求** @param url 地址* @param body 内容* @return 请求结果*/public static String post(String url, String body) {return httpPost(url, headers, body);}/*** 发送Post请求** @param url     请求地址* @param headers 请求头* @param body    请求体* @return 返回消息体*/public static String httpPost(String url, HttpHeaders headers, String body) {HttpEntity<String> request = new HttpEntity<>(body, headers);log.info("post url: {} headers: {} body:{}", url, headers, body);ResponseEntity<String> response;try {URI uri = new URI(url);response = REST.postForEntity(uri, request, String.class);if (HttpStatus.OK.value() != response.getStatusCode().value()){log.error("http post fail, response : {}",response);throw new CertRestRpcException();}} catch (Exception e) {log.error("http error : ",e);throw new CertRestRpcException();}return response.getBody();}}

五、异常捕获器

  • 将模组的异常捕获,并只抛出规定的异常
@Aspect
@Component
@Slf4j
public class CertRestExceptionHandler {@Pointcut("execution(* com.pak.service.CertRestService.*(..))")public void pointCut() {}@Around("pointCut()")public Object catchException(ProceedingJoinPoint joinPoint) throws Throwable {//核心业务处理try {// 获取切点请求参数Object[] args = joinPoint.getArgs();// 处理return joinPoint.proceed(args);}catch (Exception e){log.error("CertRestExceptionHandler : ",e);throw new CertRestRpcException();}}}

六、单元测试

@SpringBootApplication
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AccountCertTest.class)
public class AccountCertTest extends TestCase {@ResourceCertRestService certRestService;@ResourceCertPropsConfig propsConfig;public static void main(String[] args) {SpringApplication.run(AccountCertTest.class, args);}@Testpublic void rsaTest() {AccountCertParamDTO certParam = new AccountCertParamDTO();certParam.setIdType(propsConfig.getIdtype());certParam.setCertsort(propsConfig.getCertsort());certParam.setCertapptype(propsConfig.getCertapptype());certParam.setCertstoragetype(propsConfig.getCertstoragetype());// 填写参数certParam.setIdvalue("xxxx");String publicKey_RSA = "xxxx";certParam.setSubjectpubkey(publicKey_RSA);// 申请证书CertResponse response = certRestService.accountCertApply(certParam);// 下载证书CertDownloadParamDTO downloadParamDTO = new CertDownloadParamDTO();downloadParamDTO.setTransactioncode(response.getTransactioncode());CertResponse download = certRestService.certDownload(downloadParamDTO);// 加密证书String enccert = download.getEnccert();// 签名证书String signcert = download.getSigncert();System.out.println(download);}
}

这篇关于对接WSDL+SOAP服务:xFire替换方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/947934

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图