Wildfly,Apache CXF和@SchemaValidation

在过去的几天中,我一直在进行从JBoss 4到Wildfly 8的应用程序迁移。 该应用程序使用了不同的技术,但是我们这里将重点放在XML Web Services JAX-WS上 。 是的,我知道它们已不再流行,但是这些是很久以前开发的,因此需要维护以解决兼容性问题。

无论如何,迁移这些服务的方法并不容易。 我正在分享一些问题和修补程序,希望这些可以帮助其他开发人员解决同样的问题。

样本定义

这是旧系统JBoss 4中Web服务定义的示例:

@javax.jws.WebService(endpointInterface = "some.pack.age.WebService")
@javax.jws.soap.SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
@org.jboss.ws.annotation.EndpointConfig(configName = "Standard WSSecurity Endpoint")
@javax.jws.HandlerChain(file = "handlers.xml")
@org.jboss.ws.annotation.SchemaValidation(enabled = true, errorHandler = CustomErrorHandler.class)
public class WebServiceImpl implements WebService {

幸运的是,大多数定义都使用标准的Java EE注释。 只有@org.jboss.ws.annotation.EndpointConfig@org.jboss.ws.annotation.SchemaValidation来自旧的JBossWS库。

我们可以轻松摆脱@org.jboss.ws.annotation.EndpointConfig因为我们在新应用程序中将不需要它。 作为参考,它用于设置要通过端点预定义的额外配置数据。 检查文档预定义的客户端和端点配置

我们要保留@org.jboss.ws.annotation.SchemaValidation 。 作为参考,此批注根据端点wsdl契约中的相关模式验证传入和传出SOAP消息。 由于注释不再存在于JBossWS中,因此我们必须使用Apache CXF ,这是WildflyJAX-WS的基础实现。

问题

这是我遇到的一些问题:

SchemaValidation批注

注释@org.jboss.ws.annotation.SchemaValidation不再存在。 您必须使用Apache CXF的注释org.apache.cxf.annotations.SchemaValidation

添加以下Maven依赖项以使用Apache CXF批注:

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-api</artifactId>
    <version>2.7.11</version>
    <scope>provided</scope>
</dependency>

另外,请注意,在原始批注中,我们可以定义errorHandler属性。 旧的应用程序使用自定义错误处理程序来针对架构验证错误设置自定义错误消息。 新注释中没有等效项,因此我们需要以另一种方式进行。 为了复制旧的行为,我使用了Apache CXF拦截器 。 创建一个拦截器类并扩展AbstractPhaseInterceptor 。 这是一个示例:

public class SchemaValidationErrorInterceptor 
        extends AbstractPhaseInterceptor<Message> {
    public SchemaValidationErrorInterceptor() {
        super(Phase.MARSHAL);
    }

    @Override
    public void handleMessage(Message message) throws Fault {
        Fault fault = (Fault) message.getContent(Exception.class);
        Throwable cause = fault.getCause();
        while (cause != null) {
            if (cause instanceof SAXParseException) {
                fault.setMessage("Invalid XML: " + fault.getLocalizedMessage());
                break;
            }

            cause = cause.getCause();
        }
    }
}

您可以像这样使用它:

@org.apache.cxf.interceptor.OutFaultInterceptors(
    classes = SchemaValidationErrorInterceptor.class
)

CXF客户端和CXF服务器都使用拦截器。 执行传入和传出拦截链以进行常规处理以及发生错误时。 在这种情况下,我们要覆盖Schema Validation消息,因此我们需要将拦截器绑定到错误输出拦截器链中。 您可以为该行为使用注释@OutFaultInterceptors 。 每个链都分为多个阶段。 您可以通过在构造函数中传递Phase.MARSHAL来定义希望拦截器运行的Phase.MARSHAL 。 还有其他阶段,但是由于我们要更改错误消息,因此我们在MARSHAL阶段进行此操作。

不同的WSDL

旧的Web服务具有在部署时自动生成的WSDL文件。 不幸的是,在某些情况下,JBoss 4和Wildfly 8生成的WSDL是不同的。 这可能会导致您的外部呼叫者出现问题。 在这种情况下,主要问题在于架构验证。 在Wildfly 8中执行时,在JBoss 4中有效的请求不再有效。

此行为的原因是在目标名称空间中。 如果在Web Service参数中使用带注释的@XmlRootElement ,而未在注释中定义namespace属性,则JBoss 4 WS会生成带有黑色名称空间的目标WSDL元素。 如果CWSF元素为空,则Apache CXF将使用Web服务默认名称空间来绑定WSDL元素。 作为参考,这是通过CXF代码完成的: org.apache.cxf.jaxws.support.JaxWsServiceConfiguration#getParameterName

可以通过更改CXF代码来解决此问题,但是我们选择将旧生成的WSDL文件放置在迁移的应用程序源中,并将其包含在发行版中。 它不再自动生成,这意味着如果我们更改API,则需要手动生成WSDL。 我们需要小心确保未在WSDL中破坏任何内容。 这种方法似乎比必须维护我们自己的CXF版本更好。 我们可能也可以为此提交修复程序,但是我们认为JBoss 4行为不是故意的。

启动CXF

要使用CXF中的特定API,还不足以为其具有项目依赖关系。 实际上,在最初的几次尝试更改之前,似乎没有与CXF相关的功能。 发生这种情况是因为Wildfly只在寻找标准的Java EE JAX-WS注释。 为了使所有CXF行为正常工作,我们需要告诉Wildfly我们的应用程序依赖于CXF ,即使这些库已经在服务器上了。 是的,这有点令人困惑。

该应用程序部署在EAR文件中。 因此,您需要创建一个jboss-deployment-structure.xml并添加以下内容:

<jboss-deployment-structure>

    <sub-deployment name="application.war">
        <dependencies>
            <module name="org.apache.cxf"/>
        </dependencies>
    </sub-deployment>

</jboss-deployment-structure>

如果将WAR文件中的MANIFEST.MF部署在EAR文件中,则显然无法使用。 有关更多信息,请检查WildFly中的类加载

如果您想使用其他CXF功能,尤其是与Spring链接的功能,则可能会有些棘手。 看一下这篇文章: 有关JBoss的各种事实。 事实6:JBoss和CXF:天造地设的对决

最终定义

这应该是我们对Web服务的最终定义:

@WebService(
        wsdlLocation = "WebService.wsdl",
        endpointInterface = "some.pack.age.WebService"
)
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
@HandlerChain(file = "/handlers.xml")
@SchemaValidation(type = SchemaValidation.SchemaValidationType.IN)
@OutFaultInterceptors(classes = SchemaValidationErrorInterceptor.class)
public class WebServiceImpl implements BDNSWebService {

如您所见,将Web服务从JBoss 4迁移到Wildfly所需的更改只是其中的一部分。 但是,如果您不了解一些细微的细节,可能会长时间阻止您。 也许您有不同的设置,并且遇到的问题也有所不同。 如果您只是想通过Wildfly设置CXF ,这也可以有所帮助,我希望本文对您有所帮助。

翻译自: https://www.javacodegeeks.com/2015/05/wildfly-apache-cxf-and-schemavalidation.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值