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-INFat 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: nullat 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);/*@Beanpublic 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.xmlregistrationBean.addInitParameter("axis2.repository.path", root+"/WEB-INF");//设置 AxisServlet 的加载顺序。加载顺序为1,应用程序启动时将加载 AxisServletregistrationBean.setLoadOnStartup(1);return registrationBean;}*/@Beanpublic 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.xmlregistrationBean.addInitParameter("axis2.repository.path", path);registrationBean.setLoadOnStartup(1);return registrationBean;}
/* @Beanpublic 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();}}
相关文章:

WebService的services.xml问题
WebService有多种实现方式,这里使用的是axis2 问题: 在本地开发,访问本地的http://localhost:8080/services/ims?wsdl,正常访问 但是打成jar包,不管是linux还是window启动,都访问不到,报错…...

永久删除 Elasticsearch 中的主节点
Elasticsearch 是一个开源分布式搜索和分析引擎,用于各种任务,例如全文搜索、日志分析和实时数据分析。 Elasticsearch 集群由一个或多个节点组成,每个节点可以具有多种角色,包括主节点(master node)、数据…...

从搜索引擎到答案引擎:LLM驱动的变革
在过去的几周里,我一直在思考和起草这篇文章,认为谷歌搜索正处于被颠覆的边缘,它实际上可能会影响 SEO 作为业务牵引渠道的可行性。 考虑到谷歌二十多年来的完全统治地位,以及任何竞争对手都完全无力削弱它,坦率地说&…...

IDEA如何进行远程Debug调试
背景: 使用docker进行CVE漏洞复现的时候,由于只能黑盒进行复现,并不能知道为什么会产生这个漏洞,以及漏洞的POC为什么要这么写,之前我都是通过本地debug来进行源码分析,后来搜了一下,发现可以进…...

故障诊断 | 一文解决,GRU门控循环单元故障诊断(Matlab)
文章目录 效果一览文章概述专栏介绍模型描述源码设计参考资料效果一览 文章概述 故障诊断 | 一文解决,GRU门控循环单元故障诊断(Matlab) 专栏介绍 订阅【故障诊断】专栏,不定期更新机器学习和深度学习在故障诊断中的应用;订阅...

C语言数据结构之二叉树
少年恃险若平地 独倚长剑凌清秋 🎥烟雨长虹,孤鹜齐飞的个人主页 🔥个人专栏 🎥前期回顾-栈和队列 期待小伙伴们的支持与关注!!! 目录 树的定义与判定 树的定义 树的判定 树的相关概念 树的运用…...

《HTML 简易速速上手小册》第1章:HTML 入门(2024 最新版)
文章目录 1.1 HTML 简介与历史(😉🌐👽踏上神奇的网页编程之旅)1.1.1 从过去到现在的华丽蜕变1.1.2 市场需求 —— HTML的黄金时代1.1.3 企业中的实际应用 —— 不只是个网页1.1.4 职业前景 —— 未来属于你 1.2 基本 H…...

笔记本电脑Win11重装系统教程
在笔记本电脑Win11操作过程中,用户如果遇到很严重的系统问题,就可以重新正常的Win11系统,快速解决Win11系统问题。但是,部分新手用户不知道不知道如何操作才能给Win11笔记本电脑重装系统?以下小编分享笔记本电脑Win11重…...

突破编程_C++_面试(基础知识(3))
面试题5:函数调用的过程 C 中函数的调用包含参数入栈、函数跳转、保护现场、回复现场等过程,重点过程如下: (1)将函数的参数压入栈中,从右至左压入。 (2)调用函数时,将当…...

AI的安全应答之道
作者:统信UOS技术团队 2023,随着各种大语言模型的爆发,整个AI生态正处于从决策式AI进化到生成式AI的进程中。各类AI模型和AI应用层出不穷,也随之带来了与AI相关的各类潜在风险。AI开发和使用过程中的风险防范和治理,成为了不可忽…...

【昕宝爸爸小模块】日志系列之什么是分布式日志系统
➡️博客首页 https://blog.csdn.net/Java_Yangxiaoyuan 欢迎优秀的你👍点赞、🗂️收藏、加❤️关注哦。 本文章CSDN首发,欢迎转载,要注明出处哦! 先感谢优秀的你能认真的看完本文&…...

如何在淘宝和Shopee上进行选品:策略和原则
在当今数字化时代,电商平台已经成为卖家们扩展业务和增加销售额的重要渠道。而在淘宝和Shopee这两个知名电商平台上进行选品时,卖家可以遵循一些相似的原则和策略,以确保他们的产品能够吸引目标客户并取得成功。本文将为您介绍一些在淘宝和Sh…...

C++/数据结构:二叉搜索树的实现与应用
目录 一、二叉搜索树简介 二、二叉搜索树的结构与实现 2.1二叉树的查找与插入 2.2二叉树的删除 2.3二叉搜索树的实现 2.3.1非递归实现 2.3.2递归实现 三、二叉搜索树的k模型和kv模型 一、二叉搜索树简介 二叉搜索树又称二叉排序树,它或者是一棵空树࿰…...

C++引用、内联函数、auto关键字介绍以及C++中无法使用NULL的原因
文章目录 一、引用1.1 引用概念1.2 引用特性1.3 常引用1.4 使用场景1.4.1 做参数1.4.2做返回值 1.5 引用和指针的区别1.6 小结一下 二、内联函数2.1 内联的概念2.2 内联的特性2.3 【面试题】 三、auto关键字(C11)3.1 类型别名思考3.2 auto简介 四、auto的使用细则4.1 基于范围的…...

RabbitMQ之三种队列之间的区别及如何选型
目录 不同队列之间的区别 Classic经典队列 Quorum仲裁队列 Stream流式队列 如何使用不同类型的队列 Quorum队列 Stream队列 不同队列之间的区别 Classic经典队列 这是RabbitMQ最为经典的队列类型。在单机环境中,拥有比较高的消息可靠性。 经典队列可以选…...

【ArcGIS微课1000例】0099:土地利用变化分析
本实验讲述在ArcGIS软件中基于两期土地利用数据,做土地利用变化分析。 文章目录 一、实验描述二、实验过程三、注意事项一、实验描述 对城市土地利用情况进行分析时,需要考虑不同时期土地利用图层在空间上的差异性,如农用地转建筑用地的空间变化。而该变化过程表现为各时期…...

学习鸿蒙基础(2)
arkts是声名式UI DevEcoStudio的右侧预览器可以预览。有个TT的图标可以看布局的大小。和html的布局浏览很像。 上图布局对应的代码: Entry //入口 Component struct Index {State message: string Hello Harmonyos //State 数据改变了也刷新的标签build() {Row()…...

2024年美国大学生数学建模竞赛思路与源代码【2024美赛C题】
B站账号,提前关注,会有直播:有为社的个人空间-有为社个人主页-哔哩哔哩视频 (bilibili.com) 题目 待定 问题一 思路 待定 模型 待定 程序 待定 问题二 待定 思路 待定 模型 待定 程序 待定...

Windows11搭建GPU版本PyTorch环境详细过程
Anaconda安装 https://www.anaconda.com/ Anaconda: 中文大蟒蛇,是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。从官网下载Setup:点击安装,之后勾选上可以方便在普通命令行cmd和PowerShell中使用…...

Springboot项目基础配置:小白也能快速上手!
推荐文章 给软件行业带来了春天——揭秘Spring究竟是何方神圣(一) 给软件行业带来了春天——揭秘Spring究竟是何方神圣(二) 给软件行业带来了春天——揭秘Spring究竟是何方神圣(三) 给软件行业带来了春天—…...

20240127在ubuntu20.04.6下配置whisper
20240131在ubuntu20.04.6下配置whisper 2024/1/31 15:48 首先你要有一张NVIDIA的显卡,比如我用的PDD拼多多的二手GTX1080显卡。【并且极其可能是矿卡!】800¥ 2、请正确安装好NVIDIA最新的驱动程序和CUDA。可选安装! 3、配置whispe…...

C# 递归执行顺序
为了方便进一步理解递归,写了一个数字输出 class Program {static void Main(string[] args){int number 5;RecursiveDecrease(number);}static void RecursiveDecrease(int n){if (n > 0){Console.WriteLine("Before recursive call do : " n);Rec…...

go 实现暴力破解数独
一切罪恶的来源是昨晚睡前玩了一把数独,找虐的选了个最难的模式,做了一个多小时才做完,然后就睡不着了..........程序员不能受这委屈,今天咋样也得把这玩意儿破解了 破解思路(暴力破解加深度遍历) 把数独…...

go语言-字符串处理常用函数
本文介绍go语言处理字符串类型的常见函数。 ## 多行字符串 在 Go 中创建多行字符串非常容易。只需要在你声明或赋值时使用 () 。 str : This is a multiline string. ## 字符串的拼接 go // fmt.Sprintf方式拼接字符串 str1 : "abc" str2 : "def" …...

DevOps落地笔记-05|非功能需求:如何有效关注非功能需求
上一讲主要介绍了看板方法以及如何使用看板方法来解决软件研发过程中出现的团队过载、工作不均、任务延期等问题。通过学习前面几个课时介绍的知识,你的团队开始源源不断地交付用户价值。用户对交付的功能非常满意,但等到系统上线后经常出现服务不可用的…...

vs 撤销本地 commit 并保留更改
没想到特别好的办法,我想的是用 vs 打开 git 命令行工具 然后通过 git 命令来撤销提交,尝试之前建议先建个分支实验,以免丢失代码, git 操作见 git 合并多个 commit / 修改上一次 commit...

深度解读NVMe计算存储协议-1
随着云计算、企业级应用以及物联网领域的飞速发展,当前的数据处理需求正以前所未有的规模增长,以满足存储行业不断变化的需求。这种增长导致网络带宽压力增大,并对主机计算资源(如内存和CPU)造成极大负担,进…...

CHS_06.2.3.4_2+用信号量实现进程互斥、同步、前驱关系
CHS_06.2.3.4_2用信号量实现进程互斥、同步、前驱关系 知识总览信号量机制实现进程互斥信号量机制实现进程同步信号量机制实现前驱关系 知识回顾 各位同学 大家好 在这个小节中 我们要学习怎么用信号量机制来实现进程的同步互制关系 知识总览 那么 我们之前学习了互斥的几种软…...

Web实战丨基于Django的简单网页计数器
文章目录 写在前面Django简介主要程序运行结果系列文章写在后面 写在前面 本期内容 基于django的简单网页计数器 所需环境 pythonpycharm或vscodedjango 下载地址 https://download.csdn.net/download/m0_68111267/88795604 Django简介 Django 是一个用 Python 编写的高…...

mysql8安装基础操作(一)
一、下载mysql8.0 1.查看系统glibc版本 这里可以看到glibc版本为2.17,所以下载mysql8.0的版本时候尽量和glibc版本对应 [rootnode2 ~]# rpm -qa |grep -w glibc glibc-2.17-222.el7.x86_64 glibc-devel-2.17-222.el7.x86_64 glibc-common-2.17-222.el7.x86_64 gl…...