【原创】IPTVC2实现方案(文末有demo)

news2024/11/13 15:11:16

前言:

名词解释: IPTVC2, 全称: 央视国际节目定价发布接口规范,标准版本当前最新为2.7.12

附赠资源链接,侵删:规范

规范中提供的样例,实现基于axis1.4(2006的时代宠物)

基于axis1版本的实现参考: Spring boot 集成Axis1.4 ,使用wsdd文件发布webservice_董洪臣的博客-CSDN博客

 前辈的参考代码: GitHub - donghc/demo: Spring boot 集成Axis1.4 ,使用wsdd文件发布webservice的demo

博主在重构业务代码(基于axis1)的时候,基于SpringBoot2实现,就参考了董老师的代码。

免责条款:

(1) 本着反哺行业,避免走弯路,故编写本文章且提供demo样例。

(2) 所使用示例代码不包含业务代码,且尽可能与公司使用代码区别,严格遵守脱敏。

(3) 本文所使用代码,基本来自于wsdl文件通过wsdl2java生成。分享的是实现步骤,与业务代码无关。版本基于SpringBoot2.7 axis1.7.9

鸣谢: Springboot集成Axis2——通过wsdl生成webService_axis2根据wsdl生成services.xml_alistair_chow的博客-CSDN博客

背景介绍
c2需要通过WebService进行消息交互,并且文档中规定了wsdl格式。由于目前Springboot对cxf框架支持较好,并没对axis进行较好的集成,但是客户放所规定的wsdl又使用到了仅axis支持的rpc模式,因此不得不使用axis作为Webservice框架进行服务的服务端和客户端的搭建。

实操步骤(axis2实现):


Axis2提供了wsdl2java的工具包,首先需要现在Axis2至本地目录(不用是项目目录)。官网下载地址: http://archive.apache.org/dist/axis/axis2/java/core/

可以选择任意版本。最好和要引入的版本一致。当前最新版本为1.8.2,这里使用1.7.9 进行处理。

(1) 下载工具包到本地路径,如 D:/tmp,并且解压

windows 下执行:

打开cmd

cd到D:/tmp

./wsdl2java.bat -uri ctms.wsdl -d adb -s -ss -sd -ssi -o D:/tmp/ws/server/ctms

这里的ctms结构:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="iptv" xmlns:impl="iptv" xmlns:intf="iptv" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
 <wsdl:types>
  <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="iptv">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="CSPResult">
    <sequence>
     <element name="Result" type="xsd:int"/>
     <element name="ErrorDescription" nillable="true" type="soapenc:string"/>
    </sequence>
   </complexType>
  </schema>
 </wsdl:types>

   <wsdl:message name="ExecCmdRequest">
      <wsdl:part name="CSPID" type="soapenc:string"/>
      <wsdl:part name="LSPID" type="soapenc:string"/>
      <wsdl:part name="CorrelateID" type="soapenc:string"/>
      <wsdl:part name="CmdFileURL" type="soapenc:string"/>
   </wsdl:message>

   <wsdl:message name="ExecCmdResponse">
      <wsdl:part name="ExecCmdReturn" type="impl:CSPResult"/>
   </wsdl:message>

   <wsdl:portType name="CSPRequest">
      <wsdl:operation name="ExecCmd" parameterOrder="CSPID LSPID CorrelateID CmdFileURL">
         <wsdl:input name="ExecCmdRequest" message="impl:ExecCmdRequest"/>
         <wsdl:output name="ExecCmdResponse" message="impl:ExecCmdResponse"/>
      </wsdl:operation>
   </wsdl:portType>

   <wsdl:binding name="ctmsSoapBinding" type="impl:CSPRequest">
      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="ExecCmd">
         <wsdlsoap:operation soapAction=""/>
         <wsdl:input name="ExecCmdRequest">
            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="iptv"/>
         </wsdl:input>
         <wsdl:output name="ExecCmdResponse">
            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="iptv"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>

   <wsdl:service name="CSPRequestService">
      <wsdl:port name="ctms" binding="impl:ctmsSoapBinding">
         <wsdlsoap:address location="http://127.0.0.1"/>
      </wsdl:port>
   </wsdl:service>

</wsdl:definitions>

这里的ctms.wsdl 是你的soap说明文档,这里可以使用本地绝对路径,或者网络地址。自定替换。

备注: axis2有两种实体类映射形式,一种是adb,一种是xmlsBean这里使用前者,区别自行百度补充。

生成好的文件结构

resources:

 java:

 新建或者使用您既有的业务代码,将生成好的代码贴进去,并且修改相关的路径。

如该结构(截图为ctmsResp也进行生成,粘贴后的样子,可以根据需要进一步调整层次):

 引入pom依赖(仅axis2部分,其他自行引入):


        <!-- axis2 -->
        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-transport-http</artifactId>
            <version>${axis2.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.axis2</groupId>
                    <artifactId>axis2-kernel</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-adb</artifactId>
            <version>${axis2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-transport-local</artifactId>
            <version>${axis2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-xmlbeans</artifactId>
            <version>${axis2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-jaxws</artifactId>
            <version>${axis2.version}</version>
        </dependency>
        <!-- axis2 -->

servlet注册(注意,注册路径要和services.xml所在路径一致):

package com.hmwl.c2service;

import com.hmwl.c2service.utils.FileCopyUtils;
import org.apache.axis2.transport.http.AxisServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

/**
 * axis2配置类,用于设置AxisServlet和访问读取services.xml文件
 *
 */
@Configuration
public class Axis2WebServiceConfiguration {

    //服务访问前缀
    public static final String URL_PATH = "/services/*";
    //services.xml文件的位置
    public static final String SERVICES_FILE_PATH = "WEB-INF/services/axis2/META-INF/services.xml";
    //AXIS2参数key
    public static final String AXIS2_REP_PATH = "axis2.repository.path";

    @Bean
    public ServletRegistrationBean axis2Servlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
        servletRegistrationBean.setServlet(new AxisServlet());
        servletRegistrationBean.addUrlMappings(URL_PATH);
        // 通过默认路径无法找到services.xml,这里需要指定一下路径,且必须是绝对路径
        String path = this.getClass().getResource("/WEB-INF").getPath().toString();
        if (path.toLowerCase().startsWith("file:")) {
            path = path.substring(5);
        }
        if (path.indexOf("!") != -1) {
            try {
                FileCopyUtils.copy(SERVICES_FILE_PATH);
            } catch (IOException e) {
                e.printStackTrace();
            }
            path = path.substring(0, path.lastIndexOf("/", path.indexOf("!"))) + "/WEB-INF";
        }
        //System.out.println("xml配置文件,path={ "+path+" }");
        servletRegistrationBean.addInitParameter(AXIS2_REP_PATH, path);
        servletRegistrationBean.setLoadOnStartup(1);
        return servletRegistrationBean;
    }

}

业务实现: 

com.hmwl.c2service.iptv.CSPRequestServiceSkeleton

com.hmwl.c2service.iptv.CSPResponseServiceSkeleton

发布接口:

<?xml version="1.0" encoding="UTF-8"?>
<!-- This file was auto-generated from WSDL -->
<!-- by the Apache Axis2 version: 1.7.9  Built on : Nov 16, 2018 (12:05:37 GMT) -->
<serviceGroup>
    <service name="ctms">
        <messageReceivers>
            <messageReceiver mep="http://www.w3.org/ns/wsdl/in-out" class="com.hmwl.c2service.iptv.CSPRequestServiceMessageReceiverInOut"/>
        </messageReceivers>
        <parameter name="ServiceClass">com.hmwl.c2service.iptv.CSPRequestServiceSkeleton</parameter>
        <parameter name="useOriginalwsdl">false</parameter>
        <parameter name="modifyUserWSDLPortAddress">true</parameter>
        <operation name="ExecCmd" mep="http://www.w3.org/ns/wsdl/in-out" namespace="iptv">
            <actionMapping>iptv/CSPRequest/ExecCmdRequest</actionMapping>
            <outputActionMapping>iptv/CSPRequest/ExecCmdResponse</outputActionMapping>
        </operation>
    </service>
    <service name="ctmsResp">
        <messageReceivers>
            <messageReceiver mep="http://www.w3.org/ns/wsdl/in-out" class="com.hmwl.c2service.iptv.CSPResponseServiceMessageReceiverInOut"/>
        </messageReceivers>
        <parameter name="ServiceClass">com.hmwl.c2service.iptv.CSPResponseServiceSkeleton</parameter>
        <parameter name="useOriginalwsdl">false</parameter>
        <parameter name="modifyUserWSDLPortAddress">true</parameter>
        <operation name="ResultNotify" mep="http://www.w3.org/ns/wsdl/in-out" namespace="iptv">
            <actionMapping>iptv/CSPResponse/resultNotifyRequest</actionMapping>
            <outputActionMapping>iptv/CSPResponse/resultNotifyResponse</outputActionMapping>
        </operation>
    </service>
</serviceGroup>

测试:

可能遇到的问题:

(1) 使用axis2调用axis1,会遇到multiRef问题。可以通过重写ServiceClient实现,参考:

com.hmwl.c2service.utils.MyServiceClient

原本的实现在getBody后会getFirstElement(),则无法获取到ref标签。

这里整体返回回去后,可以通过自定义解析dom去处理。

如下文:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <ns1:resultNotifyResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="iptv">
         <resultNotifyReturn href="#id0"/>
      </ns1:resultNotifyResponse>
      <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:CSPResult" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="iptv">
         <Result xsi:type="xsd:int">0</Result>
         <ErrorDescription xsi:type="soapenc:string">Success</ErrorDescription>
      </multiRef>
   </soapenv:Body>
</soapenv:Envelope>

(2) jar包冲突问题。

比如遇到servletApi2.3的冲突。这是由于axis2-spring的jar引发的。后来发现没用上,就整个去掉了。

比如遇到import org.apache.axis2.transport.http.AxisServlet; 引入不了,可以排除下

        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-transport-http</artifactId>
            <version>1.7.9</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.axis2</groupId>
                    <artifactId>axis2-kernel</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

(3)The endpoint reference (EPR) for the Operation not found 

发布的名称和调用的名称不一致

(4) org.apache.axis2.databinding.ADBException: Unexpected subelement correlateID

工单这个字段大小写调用和服务端不一致。

com.hmwl.c2service.iptv.ExecCmdResponse 或者回调的Response中看一下,这个报错是在生成的代码里出现的。可以把equals修改成忽略大小写。

还有一些其他报错。反正前前后后,踩了不少坑。

如果其他需要axis1 使用axis2替换的朋友们刷到了这个帖子,希望能帮到你。

demo资源分享(免费好了,就不传csdn资源了,大家搬运请注明出处,且不要任何形式收费哦):

github | gitee(推荐)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/821562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言每日一题:12《数据结构》相交链表。

题目&#xff1a; 题目链接 思路一&#xff1a; 1.如果最后一个节点相同说明一定有交点。 2.使用两个循环获取一下长度&#xff0c;同时可以获取到尾节点。 3。注意初始化lenA和lenB为1&#xff0c;判断下一个节点是空是可以保留尾节点的。长度会少一个&#xff0c;尾节点没有…

【C++修炼之路】多态

&#x1f451;作者主页&#xff1a;安 度 因 &#x1f3e0;学习社区&#xff1a;StackFrame &#x1f4d6;专栏链接&#xff1a;C修炼之路 文章目录 一、概念二、定义和实现1、虚函数2、虚函数的重写3、多态的构成条件4、重写的例外5、C11 override 和 final6、不能被继承的类7…

RxJava异步编程初探

RxJava 其实就是提供一套异步编程的 API&#xff0c;这套 API 是基于观察者模式的&#xff0c;而且是链式调用的&#xff0c;所以使用 RxJava 编写的代码的逻辑会非常简洁。 RxJava 有以下三个基本的元素&#xff1a; 被观察者&#xff08;Observable&#xff09;观察者&…

prometheus+grafana进行服务器资源监控

在性能测试中&#xff0c;服务器资源是值得关注一项内容&#xff0c;目前&#xff0c;市面上已经有很多的服务器资 源监控方法和各种不同的监控工具&#xff0c;方便在各个项目中使用。 但是&#xff0c;在性能测试中&#xff0c;究竟哪些指标值得被关注呢&#xff1f; 监控有…

SqlSugar、Freesql、Dos.ORM、EF、四种ORM框架的对比

SqlSugar、Freesql、Dos.ORM、EF、四种ORM框架的对比 一、默认情况下,导航属性是延迟查询; 答:ORM(Object-relational mapping)即对象关系映射,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。也就是说,ORM是通过使用描述对象和数据库之间映射的元数据…

线程状态

从卖包子的案例学习进程间的通信 public class Test {public static void main(String[] args) {Object objnew Object();Thread th1new Thread(){Overridepublic void run() {synchronized (obj){System.out.println("来三个包子&#xff01;");try {obj.wait(); /…

IDEA删除本地git仓库、创建本地git仓库、关联其他仓库并上传

IDEA删除本地git仓库、创建本地git仓库、关联其他仓库并上传 删除本地Git仓库 创建本地Git仓库 关联其他仓库并上传 要在IntelliJ IDEA中删除本地Git仓库并创建新的本地Git仓库&#xff0c;以及关联其他仓库并上传&#xff0c;请按照以下步骤进行操作&#xff1a; 删除本地G…

【笔记】数据结构与算法 python-03-列表查找

列表查找 在一个数据结构中&#xff0c;通过一定的方法找出与给定关键字相同的数据元素的过程。 列表查找&#xff08;线性表查找&#xff09;&#xff1a;从列表&#xff08;一种线性数据结构&#xff0c;元素按照一定的顺序存储&#xff0c;每个元素都有一个唯一的位置索引…

网络出口技术中的单一出口网络结构,你会用吗?

我们在设计一个园区网络的时候&#xff0c;园区网络的出口需要和运营商的网络进行对接&#xff0c;从而提供internet服务。 在和运营商网络对接的时候&#xff0c;一般采用如下3终方式&#xff1a; 单一出口网络结构 1、网络拓扑 终端用户接入到交换机&#xff0c;交换机直…

干货 ,ChatGPT 4.0插件Review Reader,秒杀一切选品神器

Hi! 大家好&#xff0c;我是专注于AI项目实战的赤辰&#xff0c;今天继续跟大家介绍另外一款GPT4.0插件Review Reader&#xff08;评论阅读器&#xff09;。 做电商领域的小伙伴们&#xff0c;都知道选品分析至关重要&#xff0c;可以说选品决定成败&#xff0c;它直接关系到产…

MySQL用通配符过滤数据

简单的不使用通配符过滤数据的方式使用的值都是已知的&#xff0c;但是当搜索产品名中包含ashui的所有产品时&#xff0c;用简单的比较操作符肯定不行&#xff0c;必须使用通配符。利用通配符可以创建比较特定数据的搜索模式。 通配符&#xff1a;用来匹配值的一部分的特殊字符…

【数据分享】1999—2021年地级市市政公用事业和邮政、电信业发展情况相关指标(Excel/Shp格式)

在之前的文章中&#xff0c;我们分享过基于2000-2022年《中国城市统计年鉴》整理的1999-2021年地级市的人口相关数据、各类用地面积数据、污染物排放和环境治理相关数据、房地产投资情况和商品房销售面积、社会消费品零售总额和年末金融机构存贷款余额、地方一般公共预算收支状…

减轻 PWM 的滤波要求

经典脉宽调制器 (PWM) 发出 H 个连续逻辑高电平&#xff08;1&#xff09;&#xff0c;后跟 L 个连续逻辑低电平&#xff08;0&#xff09;的重复序列。每个高电平和低电平持续一个时钟周期 T 1/F (Hz)。结果的占空比可定义为 H/N&#xff0c;其中 N HL 时钟周期。N 通常是 2…

keil固件库的安装 库函数的配置

文章目录&#xff1a; 第一步&#xff1a;下载固件库文件 第二步&#xff1a;创建一个新的文件夹&#xff0c;用来保存固件库文件。在该文件夹下新建文件夹&#xff1a;CMSIS、Lib、Startup、User 第三步&#xff1a;把库文件中文件放入我们建立对应的文件中 1.CMSIS模块 …

【MIPI协议 C-PHY详解】

MIPI协议 C-PHY详解 前言一、C-PHY介绍1.1 C-PHY 与 D-PHY wire的区别1.2 3 wire的状态&#xff08;states&#xff09;变化1.3 C-PHY Data Mapping Between 7 Symbols and a 16-Bit Data1.3 C-PHY Lane States and Line Levels ~ LP Mode 二、C-PHY LP Package Format2.1 C-PH…

SQLI_LABS攻击

目录 Less1 首先来爆字段 联合注入 判断注入点 爆数据库名 爆破表名 information_schema information_schmea.tables group_concat() 爆破列名 information_schema.columns 爆值 SQLMAP Less-2 -4 Less -5 布尔 数据库 表名 字段名 爆破值 SQLMAP Less-6 …

​LeetCode解法汇总142. 环形链表 II

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a; 力扣 描述&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如…

ssl单向证书和双向证书校验测试及搭建流程

零、前提准备 说明&#xff1a; 50.50.1.118作为服务端&#xff0c;系统是 linux&#xff0c;openssl版本是&#xff1a;OpenSSL 1.1.1f 31 Mar 2020。 50.50.1.116是客户端&#xff0c;系统是Windows&#xff0c;openssl版本是&#xff1a;OpenSSL 3.0.5 5 Jul 2022 (Library…

Day07-作业(MySQL查询设计)

作业1: 根据如下需求完成SQL语句的编写 【仔细阅读题目需求】 数据准备&#xff1a; 创建一个数据库 db02_homework 执行如下SQL语句&#xff0c;准备测试数据 -- 员工管理(带约束) create table tb_emp (id int unsigned primary key auto_increment comment ID,username …

这款轻量级规则引擎,真香!

大家好&#xff0c;我是老三&#xff0c;之前同事用了一款轻量级的规则引擎脚本AviatorScript&#xff0c;老三也跟着用了起来&#xff0c;真的挺香&#xff0c;能少写很多代码。这期就给大家介绍一下这款规则引擎。 简介 AviatorScript 是一门高性能、轻量级寄宿于 JVM &…