WebService的services.xml问题

WebService有多种实现方式,这里使用的是axis2

问题:

在本地开发,访问本地的http://localhost:8080/services/ims?wsdl,正常访问
在这里插入图片描述

但是打成jar包,不管是linux还是window启动,都访问不到,报错信息如下

2023-12-28 09:56:20.749 [http-nio-8092-exec-1] WARN  o.a.axiom.util.stax.dialect.StAXDialectDetector[214] - Unable to determine dialect of the StAX implementation at jar:file:/opt/testWebservice.jar!/BOOT-INF/lib/woodstox-core-6.4.0.jar!/
2023-12-28 09:56:21.110 [http-nio-8092-exec-1] ERROR o.apache.axis2.deployment.WarBasedAxisConfigurator[254] - org.apache.axis2.deployment.DeploymentException: The system cannot locate the specified repository location: file:/opt/testWebservice.jar!/BOOT-INF/classes!/WEB-INF: loading repository from classpath
org.apache.axis2.deployment.DeploymentException: The system cannot locate the specified repository location: file:/opt/testWebservice.jar!/BOOT-INF/classes!/WEB-INF
	at org.apache.axis2.deployment.DeploymentEngine.loadRepository(DeploymentEngine.java:146)
	at org.apache.axis2.deployment.WarBasedAxisConfigurator.getAxisConfiguration(WarBasedAxisConfigurator.java:205)
	at org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContext(ConfigurationContextFactory.java:64)
	at org.apache.axis2.transport.http.AxisServlet.initConfigContext(AxisServlet.java:622)
	at org.apache.axis2.transport.http.AxisServlet.init(AxisServlet.java:471)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1106)
	at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:763)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:115)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1790)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
2023-12-28 09:56:21.160 [http-nio-8092-exec-1] INFO  org.apache.axis2.transport.http.AxisServlet[115] - java.lang.NullPointerException
2023-12-28 09:56:21.161 [http-nio-8092-exec-1] ERROR o.a.c.c.C.[Tomcat].[localhost].[/].[axisServlet][175] - Allocate exception for servlet [axisServlet]
java.lang.NullPointerException: null
	at org.apache.axis2.deployment.DeploymentEngine.loadServices(DeploymentEngine.java:136)
	at org.apache.axis2.deployment.WarBasedAxisConfigurator.loadServices(WarBasedAxisConfigurator.java:275)
	at org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContext(ConfigurationContextFactory.java:95)
	at org.apache.axis2.transport.http.AxisServlet.initConfigContext(AxisServlet.java:622)
	at org.apache.axis2.transport.http.AxisServlet.init(AxisServlet.java:471)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1106)
	at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:763)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:115)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1790)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

原因

axis2默认加载的是项目中的WEB-INF/services/conf/META-INF/services.xml,打包以后默认加载的就是jar中的WEB-INF/services/conf/META-INF/services.xml,但是打包后,又不能读取到services.xml,所以报错了

解决

通过IO流,将services.xml保存到本地,然后指定要加载的路径为本地的这个services.xml

import com.tmkj.tcp.FileCopyUtils;
import org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder;
import org.apache.axis2.transport.http.AxisServlet;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;

@Configuration
public class AxisWebserviceConfig {

    private final static Logger log = LoggerFactory.getLogger(AxisWebserviceConfig.class);

    /*@Bean
    public ServletRegistrationBean<AxisServlet> axisServlet() throws Exception {
        ServletRegistrationBean<AxisServlet> registrationBean = new ServletRegistrationBean<>();
        registrationBean.setServlet(new AxisServlet());

        //将 AxisServlet 映射到 /services/* 的URL路径上,所有请求路径以 /services/* 开头的请求将由 AxisServlet 处理
        registrationBean.addUrlMappings("/services/*");
        // InputStream 对象用于从类路径中读取 services.xml 文件
        InputStream in= ClassUtils.getDefaultClassLoader().getResourceAsStream("WEB-INF/services/conf/META-INF/services.xml");
        //获取应用程序的当前工作目录,就是当前项目或者jar所在的目录
        String root = System.getProperty("user.dir");
        //设置本地存储的services.xml的路径
        String path=root+"/WEB-INF/services/conf/META-INF/services.xml";
        //将前面InputStream的流文件保存到本地指定的路径
        FileUtils.copyInputStreamToFile(in,new File(path));

        log.info("xml配置文件path={}","{"+root+"/WEB-INF"+"}");

        //向 AxisServlet 添加一个初始化参数。初始化参数的名称是 axis2.repository.path ,它的值是 services.xml 文件的路径,这个 root+"/WEB-INF" 已经是我们指定的本地的services.xml路径了,如果不指定,默认加载的就是项目中的WEB-INF/services/conf/META-INF/services.xml,打包以后默认加载的就是jar中的WEB-INF/services/conf/META-INF/services.xml
        registrationBean.addInitParameter("axis2.repository.path", root+"/WEB-INF");
        //设置 AxisServlet 的加载顺序。加载顺序为1,应用程序启动时将加载 AxisServlet
        registrationBean.setLoadOnStartup(1);
        return registrationBean;
    }*/

    @Bean
    public ServletRegistrationBean<AxisServlet> axisServlet(){
        ServletRegistrationBean<AxisServlet> registrationBean = new ServletRegistrationBean<>();
        registrationBean.setServlet(new AxisServlet());
        //将 AxisServlet 映射到 /services/* 的URL路径上,所有请求路径以 /services/* 开头的请求将由 AxisServlet 处理
        registrationBean.addUrlMappings("/services/*");

        /**
         * 在项目中:获取当前程序编译后截止/WEB-INF路径,这个WEB-INF在resources目录下,最后结果就是E:/test/target/classes/WEB-INF
         * 在jar包中:结果是:file:/opt/yunwang/evn.jar!/BOOT-INF/lib/woodstox-core-6.4.0.jar!/
         */
        
        String path = this.getClass().getResource("/WEB-INF").getPath().toString();
        //在jar中的话,把file:截取掉
        if(path.toLowerCase().startsWith("file:")){
            path = path.substring(5);
        }
        //如果是jar中,路径中会有!
        if(path.indexOf("!") != -1){
            try{
                //复制classpath下的文件到jar包的同级目录下
                FileCopyUtils.copy("WEB-INF/services/conf/META-INF/services.xml");
            }catch (Exception e){
                e.printStackTrace();
            }
            path = path.substring(0, path.lastIndexOf("/", path.indexOf("!"))) + "/WEB-INF";
        }
        log.info("xml配置文件path={}","{"+path+"}");

        //向 AxisServlet 添加一个初始化参数。初始化参数的名称是 axis2.repository.path ,它的值是 services.xml 文件的路径,这个 root+"/WEB-INF" 已经是我们指定的本地的services.xml路径了,如果不指定,默认加载的就是项目中的WEB-INF/services/conf/META-INF/services.xml,打包以后默认加载的就是jar中的WEB-INF/services/conf/META-INF/services.xml
        registrationBean.addInitParameter("axis2.repository.path", path);
        registrationBean.setLoadOnStartup(1);
        return registrationBean;
    }
/*    @Bean
    public ApplicationContextHolder getApplicationContextHolder(){
        return new  ApplicationContextHolder();
    }*/
}

以上两个axisServlet方法,都是一样的,将jar中的文件通过流放在本地,放开一个就行,第一个直接用,第二个是用了一个工具类,以下是工具类

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 将jar内的文件复制到jar包外的同级目录下
 */
public class FileCopyUtils {
    private static final Logger log = LoggerFactory.getLogger(FileCopyUtils.class);

    private static InputStream getResource(String location) throws IOException {
        InputStream in = null;
        try {
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            in = resolver.getResource(location).getInputStream();
            byte[] byteArray = IOUtils.toByteArray(in);
            return new ByteArrayInputStream(byteArray);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("getResource is error: {}", e);
            return null;
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

    /**
     * 获取项目所在文件夹的绝对路径
     *
     * @return
     */
    private static String getCurrentDirPath() {
        URL url = FileCopyUtils.class.getProtectionDomain().getCodeSource().getLocation();
        String path = url.getPath();
        if (path.startsWith("file:")) {
            path = path.replace("file:", "");
        }
        if (path.contains(".jar!/")) {
            path = path.substring(0, path.indexOf(".jar!/") + 4);
        }

        File file = new File(path);
        path = file.getParentFile().getAbsolutePath();
        return path;
    }

    private static Path getDistFile(String path) throws IOException {
        String currentRealPath = getCurrentDirPath();
        Path dist = Paths.get(currentRealPath + File.separator + path);
        Path parent = dist.getParent();
        if (parent != null) {
            Files.createDirectories(parent);
        }
        Files.deleteIfExists(dist);
        return dist;
    }

    /**
     * 复制classpath下的文件到jar包的同级目录下
     *
     * @param location 相对路径文件,例如kafka/kafka_client_jaas.conf
     * @return
     * @throws IOException
     */
    public static String copy(String location) throws IOException {
        InputStream in = getResource("classpath:" + location);
        Path dist = getDistFile(location);
        Files.copy(in, dist);
        in.close();
        return dist.toAbsolutePath().toString();
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

维护管理Harbor,docker容器的重启策略

维护管理Harbor 通过HarborWeb创建项目 在 Harbor 仓库中&#xff0c;任何镜像在被 push 到 regsitry 之前都必须有一个自己所属的项目。 单击“项目”&#xff0c;填写项目名称&#xff0c;项目级别若设置为"私有"&#xff0c;则不勾选。如果设置为公共仓库&#…

【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm1001.2014.3001.5482 ​​​​ 目录 归并排序 代码实现&#xf…

Matplotlib应用-股票技术分析实战

MACD Moving Average Convergence/Divergence&#xff0c;意为异同移动平均线。它刻画的是股价变化的速度 MACD算法 指标含义公式短期EMA短期收盘价指数移动均线(12天)前一日EMA(12)11/13 今日收盘价2/13长期EMA长期收盘价指数移动均线(26天)前一日EMA(26)25/27 今日收盘价2…

qt5-入门-组件布局

参考&#xff1a; Qt学习之路_w3cschool 本地环境&#xff1a; win10专业版&#xff0c;64位 组件布局 绝对定位&#xff1a;给出确切的坐标值和尺寸&#xff0c;缺点是当用户改变窗口大小时&#xff0c;需要写函数响应变化&#xff08;或者禁止用户改变大小&#xff09; 布…

openGauss学习笔记-210 openGauss 数据库运维-常见故障定位案例-谓词下推引起的查询报错

文章目录 openGauss学习笔记-210 openGauss 数据库运维-常见故障定位案例-谓词下推引起的查询报错210.1 谓词下推引起的查询报错210.1.1 问题现象210.1.2 原因分析210.1.3 处理办法 openGauss学习笔记-210 openGauss 数据库运维-常见故障定位案例-谓词下推引起的查询报错 210.…

Likeshop社区团购源码系统-社区团购更加便捷

一、什么是社区团购&#xff1f; 社区团购是一种基于社区的一种团购模式&#xff0c;依托于社区居民的消费需求&#xff0c;由社区团长组织发起&#xff0c;通过集中采购、批量销售的方式&#xff0c;为社区居民提供优质、优惠的商品。这种模式既满足了消费者对于优惠、便捷的…

Unity 观察者模式(实例详解)

文章目录 简介示例1 - 简单的文本更新通知示例2 - 多观察者监听游戏分数变化示例3 - 事件系统实现观察者模式示例4 - 泛型观察者和可序列化的事件系统示例5 - 使用C#委托简化版 简介 在Unity中实现观察者模式&#xff0c;我们可以创建一个Subject&#xff08;目标/主题&#x…

Redis -- 背景知识

目录 特性 为啥Redis快? 应用场景 Redis不能做什么&#xff1f; Redis是在内存中存储数据的一个中间件&#xff0c;用作为数据库&#xff0c;也可以用作为缓存&#xff0c;在分布式中有很高的威望。 特性 In-memory data structures&#xff1a;在内存中存储数据key-val…

微信开放平台第三方授权(第三篇)-获取auth_access_token

1.AuthAcsessToken的获取 继续上文&#xff0c;上文提到了想要发送消息&#xff0c;就要获取授权单独的authtoken&#xff0c;通过这个token才能调用微信发送消息接口。有六个步骤&#xff0c;少一步也获取不到这个authaccesstoken。 Token生成说明 | 微信开放文档 这里需要…

SV-8003V 网络寻呼话筒

SV-8003V是深圳锐科达电子有限公司的一款桌面式对讲主机SV-8003V同样作为广播对讲系统的核心组成部分&#xff0c;集成有全区广播、分区广播、单点呼叫、点对点对讲、以及监听等功能。SV-8003V使用铝合金拉丝面板&#xff0c;并配有高性能的鹅颈麦克风以及高保真的全频喇叭&…

Linux(CentOS7)与用户电脑传输文件(sz与rz)云与云(scp)

rz和sz是Linux/Unix同Windows进行Zmodem文件传输的命令工具 rz和sz中的z为Zmodem文件传输协议的首字母 s为send发送 r为receive接收&#xff0c;都是相对与Linux来看的接收和发送 Linux发送文件到电脑&#xff1a; sz命令 把文件发送到Windows sz 文件直接按回车就可以选择发送…

亚信安慧AntDB:AntDB-M元数据锁(五)

IS_DESTROYED: 标识锁对象将被释放。 HAS_OBTRUSIVE&#xff1a;标识锁对象下有obtrusive锁&#xff0c;新的锁申请必须进入慢速申请路径&#xff0c;释放锁时&#xff0c;也要先加锁以保护已授予锁链表。 HAS_SLOW_PATH: 标识锁对象下是否有unobtrusive锁。 5.3.2 干扰型(o…

船舶船体结构型面/曲面精度一致性三维检测海船提取结构几何参数

船舶船体结构型面三维扫描测量是一种高科技的测量方法&#xff0c;它利用三维激光扫描仪对船体表面进行高精度测量&#xff0c;以获取船体结构型面的三维数据。这种测量方法在船舶设计和制造中具有重要意义&#xff0c;可以为船舶工程师提供精确的数据支持&#xff0c;帮助他们…

《HTML 简易速速上手小册》第8章:HTML 表单高级技术(2024 最新版)

文章目录 8.1 数据收集与处理8.1.1 基础知识8.1.2 案例 1&#xff1a;创建一个注册表单8.1.3 案例 2&#xff1a;创建一个调查问卷表单8.1.4 案例 3&#xff1a;创建一个动态添加输入字段的表单 8.2 定制化表单元素8.2.1 基础知识8.2.2 案例 1&#xff1a;创建一个带有定制选择…

【Java】Lombok的使用

一、Lombok是什么&#xff1f; Lombok是一个Java库&#xff0c;能自动插入编辑器并构建工具&#xff0c;简化Java开发。通过添加注解的方式&#xff0c;不需要为类编写getter或eques方法&#xff0c;同时可以自动化日志变量&#x1f680; 在我们封装一个类时&#xff0c;最常用…

JMeter 性能测试基本过程及示例

jmeter 为性能测试提供了一下特色&#xff1a; jmeter 可以对测试静态资源&#xff08;例如 js、html 等&#xff09;以及动态资源&#xff08;例如 php、jsp、ajax 等等&#xff09;进行性能测试 jmeter 可以挖掘出系统最大能处理的并发用户数 jmeter 提供了一系列各种形式的…

【UE 材质】闪电材质

效果 步骤 1. 新建一个材质这里命名为“M_Lighting” 打开“M_Lighting”&#xff0c;设置混合模式为半透明&#xff0c;着色模型为无光照 在材质图表中添加如下节点 其中&#xff0c;纹理采样节点的纹理是一个线条 此时预览窗口中效果如文章开头所示。

基于链表实现贪吃蛇游戏

本文中&#xff0c;我们将使用链表和一些Win32 API的知识来实现贪吃蛇小游戏 一、功能 &#xff08;1&#xff09;游戏载入界面 &#xff08;2&#xff09;地图的绘制 &#xff08;3&#xff09;蛇身的移动和变长 &#xff08;4&#xff09;食物的生成 &#xff08;5&…

数学建模学习笔记||灰色关联分析

灰色系统 信息绝对透明的是白色系统&#xff0c;信息绝对秘密的是黑色系统&#xff0c;灰色系统介于两者之间 关联分析 即系统的分析因素 包含多种因素的系统中&#xff0c;哪些因素是主要的&#xff0c;哪些因素是次要的&#xff0c;哪些因素影响大&#xff0c;哪些因素影响小…

vue3+typescript+Vite基础简单项目

gitee地址 数据大屏 菜单管理
最新文章