对接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

相关文章

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

解决docker目录内存不足扩容处理方案

《解决docker目录内存不足扩容处理方案》文章介绍了Docker存储目录迁移方法:因系统盘空间不足,需将Docker数据迁移到更大磁盘(如/home/docker),通过修改daemon.json配... 目录1、查看服务器所有磁盘的使用情况2、查看docker镜像和容器存储目录的空间大小3、停止dock

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S

Java服务实现开启Debug远程调试

《Java服务实现开启Debug远程调试》文章介绍如何通过JVM参数开启Java服务远程调试,便于在线上排查问题,在IDEA中配置客户端连接,实现无需频繁部署的调试,提升效率... 目录一、背景二、相关图示说明三、具体操作步骤1、服务端配置2、客户端配置总结一、背景日常项目中,通常我们的代码都是部署到远程

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

SpringBoot集成WebService(wsdl)实践

《SpringBoot集成WebService(wsdl)实践》文章介绍了SpringBoot项目中通过缓存IWebService接口实现类的泛型入参类型,减少反射调用提升性能的实现方案,包含依赖配置... 目录pom.XML创建入口ApplicationContextUtils.JavaJacksonUt

C#实现高性能拍照与水印添加功能完整方案

《C#实现高性能拍照与水印添加功能完整方案》在工业检测、质量追溯等应用场景中,经常需要对产品进行拍照并添加相关信息水印,本文将详细介绍如何使用C#实现一个高性能的拍照和水印添加功能,包含完整的代码实现... 目录1. 概述2. 功能架构设计3. 核心代码实现python3.1 主拍照方法3.2 安全HBIT

Python进行word模板内容替换的实现示例

《Python进行word模板内容替换的实现示例》本文介绍了使用Python自动化处理Word模板文档的常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录技术背景与需求场景核心工具库介绍1.获取你的word模板内容2.正常文本内容的替换3.表格内容的