I’ve got a JAX-WS WebService that is using Spring 3 IOC. I have coded a Spring Aspect to handle any exceptions and ensure that they are properly handled in the WebService class prior to completing a call. Within my Aspect, I would like to get access to the user’s locale (defined in my SOAP Header), however I am not sure how to do this.
I know I can get the Locale in a handler, but that doesn’t help me within my aspect. I tried injecting the WebServiceContext, but that is always null.
A little digging around pointed me to https://issues.apache.org/jira/browse/CXF-2674 which seems to indicate that:
- Spring intentionally does not inject a WebServiceContext object
- the WebServiceContext is a thin wrapper for the SOAPMessageContext
However, if I try to autowire the SOAPMessageContext instead, that fails as well with the following error message:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.xml.ws.handler.soap.SOAPMessageContext com.cws.cs.lendingsimulationservice.error.ServiceErrorInterceptor.webServiceContext; nested exception is java.lang.IllegalArgumentException: Can not set javax.xml.ws.handler.soap.SOAPMessageContext field com.cws.cs.lendingsimulationservice.error.ServiceErrorInterceptor.webServiceContext to java.util.LinkedHashMap
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502) [spring-beans-3.0.5.RELEASE.jar:]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) [spring-beans-3.0.5.RELEASE.jar:]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282) [spring-beans-3.0.5.RELEASE.jar:]
... 21 more
Caused by: java.lang.IllegalArgumentException: Can not set javax.xml.ws.handler.soap.SOAPMessageContext field com.cws.cs.lendingsimulationservice.error.ServiceErrorInterceptor.webServiceContext to java.util.LinkedHashMap
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146) [:1.6.0_29]
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150) [:1.6.0_29]
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63) [:1.6.0_29]
at java.lang.reflect.Field.set(Field.java:657) [:1.6.0_29]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:498) [spring-beans-3.0.5.RELEASE.jar:]
... 23 more
I figure that there must be a way I can access this information from within an aspect, but cannot seem to figure out how.
If I try to inject a SOAPMessage object instead, I get a org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.xml.soap.SOAPMessage] found for dependency error message.
Can someone point me in the right direction please?
Thanks,
Eric
My solution uses a handler and a request-scoped object. Hopefully someone else might find this useful in the future
Handler:
Defn of SOAPHeaderData:
where SOAPHeaderDataImpl is a basic POJO (with an interface so as to not need CGLIB).
Hope this helps! If anything is unclear, let me know.
Thanks,
Eric