对接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中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

Springboot3+将ID转为JSON字符串的详细配置方案

《Springboot3+将ID转为JSON字符串的详细配置方案》:本文主要介绍纯后端实现Long/BigIntegerID转为JSON字符串的详细配置方案,s基于SpringBoot3+和Spr... 目录1. 添加依赖2. 全局 Jackson 配置3. 精准控制(可选)4. OpenAPI (Spri

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

java对接海康摄像头的完整步骤记录

《java对接海康摄像头的完整步骤记录》在Java中调用海康威视摄像头通常需要使用海康威视提供的SDK,下面这篇文章主要给大家介绍了关于java对接海康摄像头的完整步骤,文中通过代码介绍的非常详细,需... 目录一、开发环境准备二、实现Java调用设备接口(一)加载动态链接库(二)结构体、接口重定义1.类型

在Java中将XLS转换为XLSX的实现方案

《在Java中将XLS转换为XLSX的实现方案》在本文中,我们将探讨传统ExcelXLS格式与现代XLSX格式的结构差异,并为Java开发者提供转换方案,通过了解底层原理、性能优势及实用工具,您将掌握... 目录为什么升级XLS到XLSX值得投入?实际转换过程解析推荐技术方案对比Apache POI实现编程

如何搭建并配置HTTPD文件服务及访问权限控制

《如何搭建并配置HTTPD文件服务及访问权限控制》:本文主要介绍如何搭建并配置HTTPD文件服务及访问权限控制的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、安装HTTPD服务二、HTTPD服务目录结构三、配置修改四、服务启动五、基于用户访问权限控制六、

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe