简体   繁体   English

打包Spring托管的Axis2 Web服务客户端

[英]Packaging a Spring managed Axis2 web service client

I've created a web service client using Axis2. 我已经使用Axis2创建了一个Web服务客户端。 I would like to package the client into a jar, so I can use it in several other projects. 我想将客户端打包到一个jar中,以便可以在其他几个项目中使用它。 The client uses the Axis2 WS-Security module 'rampart'. 客户端使用Axis2 WS-Security模块“ rampart”。 This module, rampart.mar (not a typo!) has to be present on the Axis 'repository path', in a directory called 'modules'. 必须在Axis的“存储库路径”上的一个名为“模块”的目录中存在该模块rampart.mar(不是拼写错误!)。 The client also requires a security policy file, policy.xml. 客户端还需要一个安全策略文件policy.xml。 The locations of these last two are injected via Spring, but as they are not subject to change, I would like to package them into the jar. 最后两个的位置是通过Spring注入的,但是由于它们没有变化,因此我想将它们包装到罐子中。

If you inject a File object like: 如果您注入一个File对象,例如:

<bean id="webserviceStubFactory" class="com.company.WebserviceStubFactory">
    <constructor-arg value="classpath:policy.xml"/>
</bean>

it will work just fine when running/testing the project directly. 直接运行/测试项目时,它将正常工作。 However, when you package it into a jar, you get 但是,将其包装到罐子中时,会得到

java.io.FileNotFoundException: class path resource [policy.xml] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/path/to/webservice-0.8.jar!/policy.xml

This is a well known Spring 'problem': the constructor-arg is resolved into a Spring ClasspathResource instance and it doesn't support getFile(), because File instances cannot refer to something inside a jar. 这是众所周知的Spring“问题”:constructor-arg解析为Spring ClasspathResource实例,并且不支持getFile(),因为File实例无法引用jar中的某些内容。 The solution to this is pretty simple: change the constructor to take a Resource instead of a file and use the InputStream directly. 解决方案非常简单:将构造函数更改为采用Resource而不是文件,然后直接使用InputStream。 However, this doesn't work for the Axis2 repository path, as I can only specify the full path to the repository and the Axis2 internals figure out where the rampart.mar is located. 但是,这不适用于Axis2存储库路径,因为我只能指定存储库的完整路径,而Axis2内部人员则可以确定rampart.mar的位置。

So, the question basically boils down to: is it possible to use Spring to inject a path inside a jar (even if it's only /) and have other libraries read from that path as if it were a regular filesystem? 因此,问题基本上可以归结为:是否可以使用Spring在jar内注入路径(即使它只是/),并使其他库从该路径读取文件,就像它是常规文件系统一样? I'm guessing it isn't, but I would like to be sure, before installing external 'axis repositories' on the dev/test/production environments and having several copies of the rampart.mar lying around. 我猜不是,但是我想确定一下,然后再在开发/测试/生产环境上安装外部“轴存储库”,并准备好多个raperart.mar副本。

There's only so much that Spring can do to hide the inconsistencies of the underlying JavaSE API. Spring只能做很多事情来隐藏底层JavaSE API的不一致性。 The various getXYZ methods on the Resource interface come with caveats in the documentation, eg for getFile() : Resource接口上的各种getXYZ方法在文档中附带警告,例如,对于getFile()

Throws:
    IOException - if the resource cannot be resolved as absolute file path, 
    i.e. if the resource is not available in a file system

A resource inside a JAR is not "on a filesystem", and so this will never work. JAR内部的资源不是“在文件系统上”,因此它将永远无法工作。

In your case you're going to have to work around Axis2's requirement to operate on files, but manually making sure a file exists. 在您的情况下,您将必须解决Axis2对文件进行操作的要求,但是要手动确保文件存在。 In other words, use Resource.getInputStream() to extract the content of the JAR resource and copy it to a temporary File on the local filesystem, then pass that File to Axis2. 换句话说,使用Resource.getInputStream()提取JAR资源的内容并将其复制到本地文件系统上的临时File ,然后将该 File传递给Axis2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM