Just a follow up: there is a workaround described in this thread.
In order to pass the extracted data from an interceptor and have it accessible from an endpoint, you need an intermediate bean that has scope="request", so in my case I made a bean called UsernamePassword like so
Code:
public interface UsernamePassword {
public String getUsername();
public void setUsername(String username);
public void getPassword();
public void setPassword(String password);
}
...
public class UsernamePasswordImpl implements UsernamePassword {
...
public String getUsername() {...}
public void setUsername(String username) {...}
public void getPassword() {...}
public void setPassword(String password) {...}
}
now, I create that bean in the application context, but give it request scope that each time it is accessed, you really are accessing a unique copy per http request
Code:
<bean id="requestScopedUsernamePassword" class="pkg.UsernamePasswordImpl" scope="request">
<aop:scoped-proxy/>
</bean>
Next, we can create properties in both the interceptor and the endpoint which point that request scoped instance, allowing both instances to "dirty" the internal state of the UsernamePassword object, but be assured they are always accessing the proper one, depending on the http request!
Code:
public class MyInterceptor extends EndpointInterceptorAdapter {
...
private UsernamePassword usernamePassword;
...
public void setUsernamePassword(UsernamePassword usernamePassword) {
this.usernamePassword = usernamePassword;
}
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
//extract the usernamepassword token from the SOAP headers
....
//this bean will always "point" to the correct one for each request!
usernamePassword.setUsername(username);
usernamePassword.setPassword(password);
....
}
}
public class MyEndpoint extends AbstractDomPayloadEndpoint {
...
private UsernamePassword usernamePassword;
...
public void setUsernamePassword(UsernamePassword usernamePassword) {
this.usernamePassword = usernamePassword;
}
...
protected Element invokeInternal(Element requestElement, Document responseDocument) throws Exception {
// here you can safely access the correct usernamePassword object!
lookupStuffInDatabase(usernamePassword.getUsername(), usernamePassword.getPassword());
}
}
Hope this helps.
The only downside to this approach is that it seems a little unintuitive, and adds a dependency on CGLIB. Also you may need to add a RequestContextListener to your web.xml.
Code:
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>