wsimport - 如何在不同的项目/文件夹中生成服务端点类和JAXB类

12
我们正在使用自上而下的方法处理一个包含多个 Web 服务(多个 WSDL)的项目。每个 Web 服务都需要设置为一个独立的项目,并部署为一个独立的 war 包。
问题在于,这些 WSDL 共享一些通用的 .xsd 文件。目前,如果我们为每个 WSDL 运行 wsimport,则共同的 JAXB 类将在每个 Web 服务项目中被复制。
理想情况下,我们希望在一个共享的常见项目中单独生成 JAXB 类,然后在每个 Web 服务项目中重用 JAXB 类项目,但 wsimport 不提供跳过 JAXB 类生成或指定不同位置的选项。
你有什么想法可以在不同的 JAX-WS Web 服务端点之间共享 JAXB 类?

1
我认为(但我可能错了),你所问的两个选项都不可能。JAXB生成不能被跳过,因为Web服务依赖于各种存根以进行生成。另外,指定不同目录也不是一个选项,因为所有导入都会出问题。我最好的猜测是你必须自己手动重构代码。但我可能错了。让我们看看是否有人确切知道这一点。 - Cratylus
@ChrisAldrich 我正在使用IBM RAD 7.5.5进行这个项目。 - PrasadB
@user384706 感谢您的建议。我也无法找到指定jax-ws源和jaxb类源的不同位置的方法。最后的办法是手动移动/重新排列生成的源代码。 - PrasadB
4个回答

15

我知道这个问题很老,但是我想分享答案给那些正在寻找的人。我知道我花了一段时间才找到答案。

从JAXB 2.1 RI开始,有一个叫做“episodes”的特性可以用来简化此操作。

假设您有一个名为myschema.xsd的模式。然后你需要调用以下内容:

xjc -episode myschema.episode myschema.xsd

如果你使用单个调用编译多个 xsd 文件,这个方法同样适用。该调用将生成绑定以及 myschema.episode 文件。

episode 文件是一个特殊的绑定文件。然后可以像下面这样使用 wsimport:

wsimport mywsdl.wsdl -b myschema.episode

wsimport现在将使用先前生成的JAXB文件,并生成缺失的任何内容。

有关更多信息,请参见此页面


7
您可以使用JAXB/JAX-WS自定义来实现此目的。假设您在WSDL中嵌入了XSD类型,则您的自定义将如下所示:
<jaxws:bindings version="2.0"
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="../wsdl/some.wsdl">

    <jaxws:package name="org.company.project.ws" />

    <!-- XSD types customization within WSDL -->
    <jaxb:bindings node="//xsd:schema">
        <jaxb:schemaBindings>
            <jaxb:package name="org.company.project.beans" />
        </jaxb:schemaBindings>
    </jaxb:bindings>
</jaxws:bindings>

上述配置是指以下项目目录结构:
+-- binding
|   +-- jaxws-binding.xml
+-- wsdl
|   +-- some.wsdl
+-- src
    ...

如果您使用org.codehaus.mojo:jaxws-maven-plugin插件,则需要指定<bindingDirectory>binding</bindingDirectory>
如果您的XSD外部于WSDL,则需要单独指定自定义内容:
+-- binding
|   +-- jaxb-binding.xml
|   +-- jaxws-binding.xml
+-- wsdl
    ...

然后jaxb-binding.xml会像这样:
<jaxb:bindings version="1.0"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <jaxb:bindings schemaLocation="my.xsd" node="//xsd:schema">
        <jaxb:schemaBindings>
            <jaxb:package name="org.company.project.beans" />
        </jaxb:schemaBindings>
    </jaxb:bindings>
</jaxb:bindings>
  • 对于Ant构建,您只需为不同的软件包生成两个jar文件。
  • 由于我个人不知道如何从一个Maven项目中创建两个JAR工件 :),因此最简单的解决方案是在project-beans项目中从XSD生成JAXB类,在运行wsimport后在project-ws项目中删除生成的JAXB类(您可以使用ant插件进行操作)。

2
非常有用,特别是你需要为导入的模式文件准备一个单独的绑定文件。谢谢! - Michael-O
非常有用,我通过这个解决方案解决了“已经在使用中的相同名称的类/接口”的问题。 - Alessandro C

1
通常我使用IBM Rational工具集时看到的做法是:
生成所有JAXB和服务类并将它们存储在服务项目中。然后重新生成JAXB和服务客户端类并将它们存储在客户端项目中。
是的,这是重复的。但我认为背后的原因是将服务提供者和服务消费者的关注点分离开来。从工具集的角度来看,你怎么知道你的客户端是.NET、C++还是Java?反之亦然。如果你是客户端,你怎么知道提供者是.NET、C++还是Java等?你不知道。因此,IBM提供了这种关注点分离的方式。
现在的缺点是,如果你恰好拥有服务提供者和消费者的源代码,你就会有重复的代码。这可能很难维护。
也许最好将服务和客户端生成为Java项目(不是J2EE项目或Web项目),并制作成jar包。这样,所有的JAXB类都在那里(只有一次)。WSDL是一次性的。服务只有一次,并且可以部署到服务器上的EAR或WAR中。如果你想让别人使用你的服务,客户端也存在。如果你的客户端允许基于WSDL位置进行动态创建, 那就更好了。
我有一篇可能会有帮助的文章,从向导驱动的角度来看,它与安全性更相关,但你可能会从中找到一些有用的提示。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接