Issue Details (XML | Word | Printable)

Key: XFIRE-243
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Tomasz Sztelak
Reporter: Kamal Fariz
Votes: 1
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
XFire

Server did not recognize the value of HTTP Header SOAPAction: .

Created: 23/Jan/06 05:28 AM   Updated: 08/Jul/06 03:56 PM
Component/s: None
Affects Version/s: None
Fix Version/s: None

Time Tracking:
Not Specified

Environment: Windows XP, Java 1.4


 Description  « Hide
I am trying to access the following web service as an exercise: http://www.webservicex.net/CurrencyConvertor.asmx?WSDL . I am using XFire in a Spring container. The following is my Spring bean configuration:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <import resource="classpath:org/codehaus/xfire/spring/xfire.xml" />

    <bean id="currencyConvertor" class="org.codehaus.xfire.spring.remoting.XFireProxyFactoryBean">
        <property name="service" ref="currencyConvertorService" />
        <property name="serviceUrl" value="http://www.webservicex.net/CurrencyConvertor.asmx" />
        <property name="xfire" ref="xfire" />
    </bean>

    <bean id="currencyConvertorService" class="org.codehaus.xfire.spring.ServiceBean">
        <property name="serviceClass" value="com.accenture.spring.example.CurrencyConvertor" />
    </bean>
</beans>

When I run, I get a Fault with the following message: Server did not recognize the value of HTTP Header SOAPAction: .

The stack trace is:

org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: .
   at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
   at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
   at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
org.codehaus.xfire.fault.XFireFault: System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: .
   at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
   at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
   at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
	at org.codehaus.xfire.fault.Soap11FaultSerializer.readMessage(Soap11FaultSerializer.java:31)
	at org.codehaus.xfire.fault.SoapFaultSerializer.readMessage(SoapFaultSerializer.java:28)
	at org.codehaus.xfire.soap.handler.ReadHeadersHandler.checkForFault(ReadHeadersHandler.java:108)
	at org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:67)
	at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:100)
	at org.codehaus.xfire.client.Client.onReceive(Client.java:346)
	at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:176)
	at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:81)
	at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
	at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:100)
	at org.codehaus.xfire.client.Client.invoke(Client.java:261)
	at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
	at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
	at $Proxy0.ConversionRate(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.codehaus.xfire.spring.remoting.XFireClientInterceptor.invoke(XFireClientInterceptor.java:88)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
	at $Proxy1.ConversionRate(Unknown Source)
	at com.accenture.spring.example.SimpleConsumer.main(SimpleConsumer.java:16)
Exception in thread "main"


 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Kamal Fariz added a comment - 23/Jan/06 05:31 AM
I forgot to add that I am using 1.0-SNAPSHOT from January 23, 2006.

Tomasz Sztelak added a comment - 27/Jan/06 01:52 PM
It looks like .NET server don't recognize an empty SOAPAction header (what is perfectly valid due to soap spec ) until its configured to do so. MS support adice to add [SoapDocumentService(RoutingStyle=SoapServiceRoutingStyle.RequestElement)] to service definiton , but since you don't have access to that service i'll try to find some workaround.

Kamal Fariz added a comment - 29/Jan/06 09:29 AM
If using the default ObjectServiceFactory and ServiceBean, the only way workaround I can see is to expose the action as a configurable property.

Tomasz Sztelak added a comment - 29/Jan/06 03:23 PM
Can you send me you test project? I was a little busy last time and it would make it a little easer to fix.

Dan Diephouse added a comment - 29/Jan/06 03:32 PM
The SoapAction going out should be "" - I am not sure why .NET would be having a problem with that. I think you can create a handler which does:

public void invoke(MessageContext context) {
OutMessage msg = context.getOutMessage();
msg.setProperty(SoapConstants.SOAP_ACTION, "");
}

Maybe that will fix things for you?


Tomasz Sztelak added a comment - 30/Jan/06 05:07 PM
Ok, i think i know where is the problem. You service object isn't configured properly. Creating service in the way you did so, cause a tiny problem with ServiceFactory.
In your config, default ServiceFactory is used instead of AnnotationServiceFactory, thats why all information from annotation are lost ( including SaopAction ).
When you create currencyConvertorService bean, you must specify a valid serviceFactory ( you can look at CurrencyConvertorClient class where all configuration is done )
or you can use CurrencyConvertorClient class directly to get service object configured like :
CurrencyConvertorClient client = new CurrencyConvertorClient();
CurrencyConvertorSoap soap = client.getCurrencyConvertorLocalPort();
That should do the trick.

In case you will have problems with this ( or emergency just let me know.


Kamal Fariz added a comment - 31/Jan/06 07:19 AM
I am purposely not instantiating a special ServiceFactory as ServiceBean will instantiate the default ObjectServiceFactory. I am sure that if I use AnnotationServiceFactory I should be able to get this example working. I realize that using a bare interface file is not enough for XFire to be able to to have all the relevant information to generate the request XML. I assume that is why certain parameters are configurable, like namespace. The alternative to annotations is to use the WSDL document to provide all the necessary information.

I have looked at ServiceBean's code and made some changes for it to be able to call ServiceFactory's create(Class, QName, URL, Map) instead*. There are some other changes, like exposing portType etc. Most things work, SoapAction is populated and the server doesn't raise a Fault. The only stumbling block right now is that the binding provider does not use the WSDL for getSuggestedParamName, leaving me with <in0>, <in1>. I'm looking into how I can modify the Aegis binding provider or should implement a new binding provider that is backed by the WSDL document.

Any thoughts on this?

  • changes:
    Modified ServiceBean as AbstractServiceBean and refactored the servicefactory create call as an abstract method. Provided a DefaultServiceBean that calls the create(Class, String, String, Map) and a WsdlServiceBean that calls create(Class, QName, URL, Map).

Thomas Kämmerer added a comment - 17/Feb/06 08:13 AM
The SOAP-Action attribute isn't handled on the server side correctly to. Given a WSDL with SOAP binding (snippet shown below)

<snip />
<wsdl:operation name="getFOOs">
<soap:operation soapAction="/getFOOs" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="InternalError">
<soap:fault name="InternalError" use="literal" />
</wsdl:fault>
<wsdl:fault name="FOOsNotFound">
<soap:fault name="FOOsNotFound" use="literal" />
</wsdl:fault>
</wsdl:operation>
<snap />

a successfully generated and deployed ws-server results in the expected HTTP transport binding — including the
mandatory SOAP-Action attributes — but the attributes are empty!

<snip />
<wsdl:operation name="getFOOs">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getFOOsRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getFOOsResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<snap />


Mika Goeckel added a comment - 17/Feb/06 09:22 AM
XFire always generates an empty String as soapAction, this is because of the ambiguity from the spec what the purpose of soapAction should be.
Additionally, because Aegis mapping/XmlBeans is used on Thomas side, there is no connection through generation between the wsdl and the service, only the types are generated.

Tomasz Sztelak added a comment - 08/Jul/06 03:56 PM
SOAPAction is generated correctly now, ( i hope