JAX-WS RI 默认在 import 的 schemaLocation 属性中使用 public URL 在运行时生成 WSDL

JAX-WS RI generates WSDL on runtime with public URL in schemaLocation attribute of import by default

在使用 JAX-WS RI 发布 SOAP 端点时,使用从预先确定的 .wsdl.xsd 文件生成的存根实现,它会自动为发布的端点生成相应的 WSDL 文件。例如,在 http://localhost:8081/ep 发布的端点在 http://localhost:8081/ep?wsdl 有其 WSDL 文件,其中包含其他模式文件的导入,这些文件又可以导入更多文件。

问题是 .xsd 文件中的一个这样的导入是自动生成的,引用 public URL 是这样的:

...
<xs:import namespace="http://www.w3.org/2005/08/addressing" 
           schemaLocation="http://www.w3.org/2006/03/addressing/ws-addr.xsd"/>
...

在没有 public 互联网连接的环境中尝试解析此端点的 WSDL 时,这可能会成为一个问题。生成的存根包括来自 ws-addr.xsd 的 类,因此 JAX-WS RI 应该能够从这些存根生成和发布 .xsd

如何强制它自己生成所需的 .xsd 模式,就像它为其他名称空间模式所做的那样,为什么它首先使用 public 位置?

问题是其他一些依赖项覆盖了架构的默认设置。由于该项目使用 JAX-WS RI,它还包括 jakarta.xml.ws-api 的依赖项,其中包括 javax.xml.ws.wsaddressing 包中的 package-info.java 文件,其中包含以下内容:

@javax.xml.bind.annotation.XmlSchema(namespace=W3CEndpointReference.NS,
                                     location="http://www.w3.org/2006/03/addressing/ws-addr.xsd")
package javax.xml.ws.wsaddressing;

其中 W3CEndpointReference.NShttp://www.w3.org/2005/08/addressing

这通过一些自动配置魔法告诉 JAX-WS RI 在引用指定的命名空间时使用给定的 public 位置。 location 的默认值为 ##generate,这使得架构生成器生成所需的组件。

所以为了覆盖它,我们可以将我们自己的 package-info.java 文件添加到我们自己的代码库中,但是 在同一个包 中,具有相同的注释但是位置的默认值:

@javax.xml.bind.annotation.XmlSchema(namespace=W3CEndpointReference.NS)
package javax.xml.ws.wsaddressing;

(没有location键表示使用默认值)

结果是生成的模式使用生成的寻址 .xsd 文件而不是 public 文件:

<xs:import namespace="http://www.w3.org/2005/08/addressing"
           schemaLocation="http://localhost:8081/ep?xsd=10"/>