编写 jax-ws web 服务并在没有 XSD 的情况下生成 WSDL
Posted
技术标签:
【中文标题】编写 jax-ws web 服务并在没有 XSD 的情况下生成 WSDL【英文标题】:Write jax-ws web service and generate WSDL without XSD 【发布时间】:2013-06-28 07:02:50 【问题描述】:我为 java 上的 tomcat 应用服务器编写了一个简单的 JAX-WS Web 服务。
我有一个接口和实现类: 界面
@WebService(name = "myWs")
@SOAPBinding(style = Style.RPC)
public interface IMyWs
@WebMethod(operationName = "getUser")
Response getUser(@WebParam(name = "phone", mode = Mode.IN) String phone);
实施
@WebService(endpointInterface = "ge.mari.IMyWs")
public class MyWs implements IMyWs
@Override
public Response getUser(String phone)
// SOME CODE
return response;
我的问题是,在我的 wsdl 文件中,响应类是在 xsd 文件中定义的。 这是我的 wsdl 文件中的 sn-p
<types>
<xsd:schema>
<xsd:import namespace="http://ws.mari.ge/" schemaLocation="http://localhost:8080/MyServcie/MyWs?xsd=1">
</xsd:import>
</xsd:schema>
</types>
如何让 Web 服务生成 WSDL 文件中的所有类型,而不是单独的 XSD 文件? 我应该更改任何配置或向我的 Web 服务添加一些注释吗?
【问题讨论】:
【参考方案1】:AFAIK 不可能让 JAX 生成带有内联模式的 WSDL。
顺便说一句:分离 WSDL 定义和 XSD 架构是一个不错的举措(您可能希望在不同的上下文中使用架构定义的对象结构,例如将数据存储到文件或类似的东西)。
也就是说:如果您需要一个“一体式”WSDL(因为一些古老的客户端需要它),您总是可以让jax-ws
最初生成 WSDL,然后根据您的需要对其进行编辑.可以使用 @WebService
注释的 wsdlLocation
参数包含编辑后的 WSDL。
【讨论】:
确实可以指示 JAX-WS 内联模式。有关如何实现这一点的说明,请参见我上面的回答。 @Kallja:我认为 OP 指的是应用程序服务器生成的 WSDL(因为 WSDL 片段中有一个schemaLocation="http://localhost:8080/MyServcie/MyWs?xsd=1"
。我不知道有什么方法可以说服应用服务器来生成一个多合一的 WSDL...但是你的观点很好。我需要记住你使用的 wsgen
参数。:-)【参考方案2】:
您可以使用 JAX-WS 将生成的模式插入到您的 WSDL 文件中
-inlineSchemas
命令行开关。 [1]
如果您在项目中使用 Maven,则可以配置 JAX-WS maven 插件,以在执行配置中对 inlineSchemas 配置元素执行相同操作,如下所示:[2]
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>SomeId</id>
<goals>
<goal>wsgen</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<sei>some.class.Name</sei>
<genWsdl>true</genWsdl>
<keep>true</keep>
<resourceDestDir>some/target/dir</resourceDestDir>
<inlineSchemas>true</inlineSchemas>
</configuration>
</execution>
</executions>
</plugin>
无需更改您的 Java 类。
[1]http://jax-ws.java.net/nonav/2.2.1/docs/wsgen.html
[2]http://jax-ws-commons.java.net/jaxws-maven-plugin/wsgen-mojo.html
【讨论】:
谢谢。你的救命稻草。【参考方案3】:实际上不可能将inlineSchemas
与运行时 WSDL 生成器一起使用。我调试了 WSDL 生成并在EndpointFactory
中找到了这一行,其中inlineSchemas
功能(实际上 存在于wsgen
工具中)只是设置为false
: p>
/**
* Generates the WSDL and XML Schema for the endpoint if necessary
* It generates WSDL only for SOAP1.1, and for XSOAP1.2 bindings
*/
private static SDDocumentImpl generateWSDL(WSBinding binding, AbstractSEIModelImpl seiModel, Collection<SDDocumentImpl> docs,
Container container, Class implType)
// [...]
WSDLGenInfo wsdlGenInfo = new WSDLGenInfo();
// [...]
wsdlGenInfo.setInlineSchemas(false);
// [...]
seiModel.getDatabinding().generateWSDL(wsdlGenInfo);
// [...]
https://github.com/eclipse-ee4j/metro-jax-ws/blob/f37dae6bdfd03bafdad63ed05b27dbfc3c38af1b/jaxws-ri/rt/src/main/java/com/sun/xml/ws/server/EndpointFactory.java#L658
JAX-WS 也有一个未解决的问题来改变这一点(但我想 JAX-WS 的改变已经没有太大希望了)。 https://github.com/eclipse-ee4j/metro-jax-ws/issues/49
【讨论】:
以上是关于编写 jax-ws web 服务并在没有 XSD 的情况下生成 WSDL的主要内容,如果未能解决你的问题,请参考以下文章
如何从 JAX-WS Web 服务中访问 ServletContext?
如何使用 oAuth 2.0 保护 apache cxf webservice(jax-ws)