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

前言:

名词解释: 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 进行处理。

【原创】IPTVC2实现方案(文末有demo)_第1张图片

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

【原创】IPTVC2实现方案(文末有demo)_第2张图片

windows 下执行:

打开cmd

cd到D:/tmp

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

这里的ctms结构:



 
  
   
   
    
     
     
    
   
  
 

   
      
      
      
      
   

   
      
   

   
      
         
         
      
   

   
      
      
         
         
            
         
         
            
         
      
   

   
      
         
      
   


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

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

生成好的文件结构

【原创】IPTVC2实现方案(文末有demo)_第3张图片

resources:

 java:

【原创】IPTVC2实现方案(文末有demo)_第4张图片

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

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

【原创】IPTVC2实现方案(文末有demo)_第5张图片

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


        
        
            org.apache.axis2
            axis2-transport-http
            ${axis2.version}
            
                
                    org.apache.axis2
                    axis2-kernel
                
            
        
        
            org.apache.axis2
            axis2-adb
            ${axis2.version}
        
        
            org.apache.axis2
            axis2-transport-local
            ${axis2.version}
        
        
            org.apache.axis2
            axis2-xmlbeans
            ${axis2.version}
        
        
            org.apache.axis2
            axis2-jaxws
            ${axis2.version}
        
        

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

发布接口:





    
        
            
        
        com.hmwl.c2service.iptv.CSPRequestServiceSkeleton
        false
        true
        
            iptv/CSPRequest/ExecCmdRequest
            iptv/CSPRequest/ExecCmdResponse
        
    
    
        
            
        
        com.hmwl.c2service.iptv.CSPResponseServiceSkeleton
        false
        true
        
            iptv/CSPResponse/resultNotifyRequest
            iptv/CSPResponse/resultNotifyResponse
        
    

测试:

【原创】IPTVC2实现方案(文末有demo)_第6张图片

可能遇到的问题:

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

com.hmwl.c2service.utils.MyServiceClient

【原创】IPTVC2实现方案(文末有demo)_第7张图片

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

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

如下文:


   
      
         
      
      
         0
         Success
      
   

(2) jar包冲突问题。

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

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

        
            org.apache.axis2
            axis2-transport-http
            1.7.9
            
                
                    org.apache.axis2
                    axis2-kernel
                
            
        

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

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

【原创】IPTVC2实现方案(文末有demo)_第8张图片

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

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

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

补充说明:

关于axis1版本的客户端调用axis2接口,multiRef取值问题。可以不使用

com.hmwl.c2service.iptv.CSPResponseServiceMessageReceiverInOut

中OM解析,原本的结构:

	ResultNotify wrappedParam = (ResultNotify) fromOM(msgContext.getEnvelope()
					.getBody()
					.getFirstElement(),
			ResultNotify.class);

可以改为:

 Map parseMap = ParseXmlUtils.parse(msgContext.getEnvelope().getBody().toString());
             

直接解析soap返回消息,自定义去解析映射值,本身axis2支持多种实体映射,插件式的,可以研究下,这里不做赘述。

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

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

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

github | gitee(推荐)

你可能感兴趣的:(spring,boot,后端,java)