【问题标题】:Spring web service client XwsSecurityInterceptor afterCompletion exceptionSpring Web 服务客户端 XwsSecurityInterceptor afterCompletion 异常
【发布时间】:2014-09-29 15:57:04
【问题描述】:

我已经实现了一个 Spring Web Service ServerClient,配置如下。

我已选择使用simplePasswordSecurity 机制,并且双方都已安装以处理此问题。到目前为止,我可以将我的请求从客户端发送到服务器,服务器将处理请求并将响应发送回。

在我的终端日志中,我可以看到客户端收到了响应,但我突然得到了这个异常:

java.lang.AbstractMethodError: org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor.afterCompletion(Lorg/springframework/ws/context/MessageContext;Ljava/lang/Exception;)V
at org.springframework.ws.client.core.WebServiceTemplate.triggerAfterCompletion(WebServiceTemplate.java:806)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:615)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)

....

知道为什么会出现此异常吗?


服务器

spring-config.xml

<bean id="FinancialService" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition" lazy-init="true">
    <property name="schemaCollection">
        <bean class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
            <property name="inline" value="true" />
            <property name="xsds">
                <list>
                    <value>schemas/FinancialServiceOperations.xsd</value>
                </list>
            </property>
        </bean>
    </property>

    <property name="portTypeName" value="FinancialService" />
    <property name="serviceName" value="FinancialService" />
    <property name="locationUri" value="/endpoints" />
</bean>

<sws:interceptors>
    <bean id="authenticationInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
        <property name="policyConfiguration" value="/WEB-INF/spring-security.xml" />
        <property name="callbackHandlers">
            <list>
                <bean id="passwordValidationHandler" class="org.springframework.ws.soap.security.xwss.callback.SimplePasswordValidationCallbackHandler">          
                    <property name="users">  
                        <props>  
                            <prop key="myUser">myPassword</prop>
                        </props>
                    </property>
                </bean>
            </list>
        </property>
    </bean>
</sws:interceptors>

spring-security.xml

<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true">  
    <xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="false"/>  
</xwss:SecurityConfiguration>

pom.xml

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-core</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-security</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>


客户

spring-config.xml

<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
    <property name="soapVersion">
        <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11" />
    </property>
</bean>

<oxm:jaxb2-marshaller id="marshaller" context-path="com.example.domain.service.financial.stub" />

<bean id="financialWebServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    <constructor-arg ref="soapMessageFactory" />
    <property name="marshaller" ref="marshaller" />
    <property name="unmarshaller" ref="marshaller" />
    <property name="defaultUri" value="http://localhost:8080/financial/FinancialService.wsdl" />
    <property name="messageSender" ref="xwsSecurityMessageSender" />
    <property name="interceptors">
        <list>
            <ref bean="xwsSecurityInterceptor" />
        </list>
    </property>
</bean>
<bean id="xwsSecurityMessageSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender" />
<bean id="xwsSecurityInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
    <property name="policyConfiguration" value="/WEB-INF/spring-ws-security.xml" />
    <property name="callbackHandlers">
        <list>
            <ref bean="xwsSecurityCallbackHandler" />
        </list>
    </property>
</bean>
<bean id="xwsSecurityCallbackHandler" class="org.springframework.ws.soap.security.xwss.callback.MockValidationCallbackHandler" />

spring-security.xml

<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true">
     <xwss:UsernameToken name="myUser" password="myPassword" digestPassword="false" useNonce="false"/>
</xwss:SecurityConfiguration>

pom.xml

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-core</artifactId>
    <version>2.2.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-security</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
</dependency>


终端日志

INFO: ==== Sending Message Start ====
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="XWSSGID-140733907019228719200">
<wsse:Username>willapweb</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">****</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns2:OnlinePaymentFormRequest xmlns:ns2="http://com/example/ws">
<ns2:serial>c3hqvk9dejps923m01qrpqrh6f</ns2:serial>
<ns2:amount>200000</ns2:amount>
</ns2:OnlinePaymentFormRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
==== Sending Message End  ====

INFO: ==== Received Message Start ====
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="XWSSGID-140733907019228719200">
<wsse:Username>willapweb</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">****</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns2:OnlinePaymentFormRequest xmlns:ns2="http://com/example/ws">
<ns2:serial>c3hqvk9dejps923m01qrpqrh6f</ns2:serial>
<ns2:amount>200000</ns2:amount>
</ns2:OnlinePaymentFormRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
==== Received Message End  ====

INFO: ==== Sending Message Start ====
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:OnlinePaymentFormResponse xmlns:ns2="http://com/example/ws">
<ns2:message>{"form":"&lt;form action='https://bank.om/Payment.aspx' method='post' id='bank-form'&gt;&lt;input type='hidden' name='Amount' value='200000'/&gt;&lt;input type='hidden' name='MID' value='12'/&gt;&lt;input type='hidden' name='ResNum' value='c3hqvk9dejps923m01qrpqrh6f'/&gt;&lt;input type='hidden' name='RedirectURL' value='http://130.185.73.133/payment/verification'/&gt;&lt;\/form&gt;","successful":true}</ns2:message>
</ns2:OnlinePaymentFormResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
==== Sending Message End  ====

INFO: ==== Received Message Start ====
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:OnlinePaymentFormResponse xmlns:ns2="http://com/example/ws">
<ns2:message>{"form":"&lt;form action='https://bank.com/Payment.aspx' method='post' id='bank-form'&gt;&lt;input type='hidden' name='Amount' value='200000'/&gt;&lt;input type='hidden' name='MID' value='12'/&gt;&lt;input type='hidden' name='ResNum' value='c3hqvk9dejps923m01qrpqrh6f'/&gt;&lt;input type='hidden' name='RedirectURL' value='http://130.185.73.133/payment/verification'/&gt;&lt;\/form&gt;","successful":true}</ns2:message>
</ns2:OnlinePaymentFormResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
==== Received Message End  ====

【问题讨论】:

  • 你有没有想过检查你的 JAR 版本(尤其是 spring ws 核心与 spring ws 安全性?)。
  • @GPI 我刚刚添加了 pom.xml 相关依赖项。

标签: java spring web-services jakarta-ee spring-ws


【解决方案1】:

您的类路径中很可能有不兼容的 JAR。

AbstractMethodError

AbstractMethodError 是当一个应该存在的方法实际上不存在时由 JVM 抛出的运行时错误。

这不应该发生在您自己的代码中:编译器会阻止您调用不存在的方法。

但是,当使用外部 JAR(依赖于其他外部 JAR)时,编译器不会警告您。

假设我有 A-1.0.jar,其中包含类 A,它有一个方法 doStuffV1()
然后,A-2.0.jar,其中包含对 A 类的更新,其中添加了另一个方法 doStuffV2()。 最后,假设我有 B-2.0.jar,它是用 A-2.0.jar 编译的,类 B 扩展了 A。

在你的项目中,如果你只导入 B-2.0.jar,并且你使用 B 类并调用 doStuffV2,编译器不会抱怨:你正在使用一个正在工作的类。

但是,如果在运行时,您将类路径 A-1.0.jar 和 B-2.0.jar 放入其中,那么当您的代码执行时,您将得到 AbstractMethodError :编译 B-2.0.jar 时存在的内容,确实在运行时不存在。这是一个崩溃。

适用于 Spring WS Jars 2.0.0 到 2.2.0

在 Spring WS 中,如果您查看您正在引用的 Spring WS 2.0.0 Javadoc,您可以在此处 (http://docs.spring.io/spring-ws/sites/2.0/apidocs/index.html) 看到 afterCompletion 签名:

public void afterCompletion(MessageContext messageContext, 对象端点, 例外)

但是,如果您查看 2.2.0 api (http://docs.spring.io/spring-ws/docs/2.2.0.RELEASE/api/),确实存在相同的方法,只是签名不同。对于 Java 编译器和运行时,这不是同一种方法:

public void afterCompletion(MessageContext messageContext, 例外前) 抛出 WebServiceClientException

来自您的堆栈跟踪的信息

您的堆栈跟踪表明运行时,来自 WSTemplate 类,尝试调用更高版本(见第一行)。

java.lang.AbstractMethodError: ...XwsSecurityInterceptor.afterCompletion(Lorg/springframework/ws/context/MessageContext;Ljava/lang/Exception;)V 在 org...WebServiceTemplate.triggerAfterCompletion(WebServiceTemplate.java:806)

这对我来说是这样的

  1. 您有一个 2.2.0 版本的 Spring-WS-Core (WebServiceTemplate.class)
  2. 带有 Spring WS Security (XwsSecurityInterceptor),它是 2.1.0 版本(或介于两者之间)。

这不兼容。您应该使两个版本保持同步。

编辑:使用你的 POM,这似乎得到了证实。

【讨论】:

  • 感谢您的回复。正如您所建议的,我将 spring-ws-core 和 spring-ws-security 都更改为 2.0.0 此外,有必要将 jaxb2-marshaller 的 context-path 属性的名称更改为 'contextPath' 再次感谢您的回复。
  • 这是一个救命的答案!非常感谢您的回答!!!!!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-04
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
  • 1970-01-01
相关资源
最近更新 更多