我是eclipse和Java开发的新手。如果这听起来像一个微不足道的问题,请耐心等待。
我正在尝试修改现有的Web服务。这最初是使用自顶向下方法开发的(即首先是WSDL然后生成Java bean骨架)。
我已经对WSDL进行了更改,现在需要将它们合并到Web服务中。当我右键单击WSDL生成Java bean骨架时,现有代码将被覆盖。当我将首选项设置为不覆盖现有代码时,它会提示我覆盖每个文件,我不确定应该覆盖哪些以及哪些不应该覆盖。
有没有办法可以更改现有代码而不覆盖它?
这是我们应该如何修改现有的Web服务吗?
答案 0 :(得分:12)
如果这听起来像是一个微不足道的问题,请耐心等待。
这不是一个微不足道的问题。所有的" Hello World"您可以在网上找到的Web服务示例和教程,它们从不提供有关如何管理“真实世界”的任何建议。以后的网络服务。
这是我们应该如何修改现有的Web服务吗?
嗯......不是真的。我会尝试为您的具体案例提供一般性解释和可能的解决方案,所以请您((D)承担,因为这将是一个很长的帖子。
构建Web服务时有两种方法:合同优先和合同最后。
合同首先意味着创建WSDL,然后生成实现WSDL规定的合同的Java代码。合同最后意味着创建Java代码,然后根据代码生成WSDL。
两者都有优点和缺点,但两者的重要性在于合同。
您的WSDL描述了合同。部署Web服务后,合同必须保持冻结状态。合同是Web服务与其客户之间通信的基础(甚至不让我开始web services interoperability)。
网络服务和所有客户在其代码中实施此合同。
我已经对WSDL进行了更改......
这并不总是一个好主意。
当Web服务合同发生变化时,合同用户可能会被破坏。更改WSDL时,重新生成Web服务代码以支持新合同。但客户呢?
如果新修改违反合同,则必须指示所有客户获取新合同并更改其代码以适应更改。你有多少客户为你的这个网络服务?您对WSDL做了哪些更改?
您可以在不破坏客户的情况下对合同进行一些更改。例如,您可以添加新操作。客户在他们的代码中不了解它,他们不知道的东西会伤害他们。您还可以向现有消息添加一些可选参数;由于它们是可选的,这意味着在沟通时可以省略它们,而客户代码不知道它以及它们不知道的可能会伤害它们。这些是非破坏性更改。
突破变化 ......好吧......违反合同。这些包括例如更改操作名称,更改消息参数类型或名称,添加必需参数等。客户端代码现在已损坏。客户刚刚发现它(现有代码不再有效)并且它们受到了伤害。此时您的网络服务已无法使用。
您对WSDL执行了哪些类型的更改?
在契约最后一种方法中,WSDL是基于Web服务代码生成的。这样做的缺点是它将代码实现与WSDL联系起来。如果您对代码进行了更改,则可能会触发WSDL中的更改,从而在您与客户达成一致的合同中。
但是,如果在契约优先方法中您对WSDL进行了更改,然后重新生成Web服务框架代码,那么您再次更改了合同。你没有做得更好......现在你又遇到了另一个问题。您现在再次生成的Web服务现有框架代码会发生什么变化?
当您从WSDL生成代码时,您将获得Web服务框架。这是样板代码,它只是以合同指定的SOAP格式在线上获取您的Web服务消息。
您通常会生成此代码并将其包含在您的项目中以供"重要的" Web服务代码,实际提供的代码"服务"。如何使用此代码非常重要。您必须考虑以后再次生成代码而不覆盖现有代码的情况。
通常,代码生成工具可以将您的框架代码拆分为接口和该接口的实现。 您必须放弃生成的实施并提供您自己的界面实施。您在不同的位置提供实现,以便在生成框架代码时不会被覆盖。如果界面发生变化,你的实现中会遇到编译问题,因为它不符合新合同,但至少你仍然有修改它的代码:D。
不幸的是,这不是大多数项目中发生的事情。人们直接修改生成的实现,当他们再次生成骨架时,他们会松开所有添加的代码。大多数生成工具在代码中插入警告"这是计算机生成的代码。如果再次生成此代码,则所有更改都将丢失..."或类似的东西,但人们听吗?
好的,足够漫无边际......
有没有办法可以更改现有代码而不会覆盖它?
手动完成(假设它是一个非破坏性的变化)!
这需要一些时间,但这并不难。您获取原始WSDL并在单独的文件夹中生成它的代码:Folder1。获取新的WSDL并在另一个单独的文件夹中为它生成代码:Folder2。对两个目录进行区分以查看更改的文件。查看文件内部。
您现在知道如何在现有项目代码中更改代码。现在,您必须确定最初生成的代码在生成后是否以某种方式被修改。将项目文件夹与Folder1进行比较。
然后手动进行修改。
如果这是一个可破坏的更改,您可能希望了解是否可以迁移客户端。如果没有,您可能必须在两个端点上公开您的Web服务,每个端点都有自己的WSDL合同到同一个Web服务并随着时间迁移客户端,如果可能的话。