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

相关文章

如何用java对接微信小程序下单后的发货接口

《如何用java对接微信小程序下单后的发货接口》:本文主要介绍在微信小程序后台实现发货通知的步骤,包括获取Access_token、使用RestTemplate调用发货接口、处理AccessTok... 目录配置参数 调用代码获取Access_token调用发货的接口类注意点总结配置参数 首先需要获取Ac

Java嵌套for循环优化方案分享

《Java嵌套for循环优化方案分享》介绍了Java中嵌套for循环的优化方法,包括减少循环次数、合并循环、使用更高效的数据结构、并行处理、预处理和缓存、算法优化、尽量减少对象创建以及本地变量优化,通... 目录Java 嵌套 for 循环优化方案1. 减少循环次数2. 合并循环3. 使用更高效的数据结构4

Nginx配置系统服务&设置环境变量方式

《Nginx配置系统服务&设置环境变量方式》本文介绍了如何将Nginx配置为系统服务并设置环境变量,以便更方便地对Nginx进行操作,通过配置系统服务,可以使用系统命令来启动、停止或重新加载Nginx... 目录1.Nginx操作问题2.配置系统服android务3.设置环境变量总结1.Nginx操作问题

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

springboot的调度服务与异步服务使用详解

《springboot的调度服务与异步服务使用详解》本文主要介绍了Java的ScheduledExecutorService接口和SpringBoot中如何使用调度线程池,包括核心参数、创建方式、自定... 目录1.调度服务1.1.JDK之ScheduledExecutorService1.2.spring

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

TP-Link PDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务

《TP-LinkPDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务》近期,路由器制造巨头普联(TP-Link)在用户群体中引发了一系列重要变动,上个月,公司发出了一则通知,明确要求所... 路由器厂商普联(TP-Link)上个月发布公告要求所有用户必须完成实名认证后才能继续使用普联提供的 D

Redis 多规则限流和防重复提交方案实现小结

《Redis多规则限流和防重复提交方案实现小结》本文主要介绍了Redis多规则限流和防重复提交方案实现小结,包括使用String结构和Zset结构来记录用户IP的访问次数,具有一定的参考价值,感兴趣... 目录一:使用 String 结构记录固定时间段内某用户 IP 访问某接口的次数二:使用 Zset 进行

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构