Hi,
we solved our problem as the following. So thanks for your help Aaron.
We created our own handler which is derived from the
org.apache.axis.transport.http.HttpSender.
In this handler we implemented the following:
We overwrote the method invoke and called the handleRequest-Method.
We registered the handler by changing the client-config.wsdd:
from
<transport name="http" pivot="java:net.tipp24.soap_axis.HttpSender"/>
to
<transport name="http" pivot="java:net.tipp24.soap_axis.MyHTTPHandler"/>
In the stub of the application we set the required header by using the
setProperty of the call-Object.
call.setProperty("PROP_KEY", "some value");
this is the derived handler:
public class MyHTTPHandler extends HTTPSender
{
public void invoke(MessageContext msgContext) throws AxisFault {
handleRequest(msgContext);
super.invoke(msgContext);
}
public boolean handleRequest( MessageContext context )
{
Hashtable headers = ( Hashtable )
context.getProperty( HTTPConstants.REQUEST_HEADERS );
if ( headers == null )
{
headers = new Hashtable();
context.setProperty( HTTPConstants.REQUEST_HEADERS, headers );
}
String value = (String ) context.getProperty( "PROP_KEY" );
headers.put( "MyHeader", value );
return true;
}
}
Because of, our Header is no official header we didnt need the other class,
but someday maybe ;-)
This is it. It works.
Greets Andrew & Benjamin
....
> Did you configureNonBrokenHTTPSender before calling createCall? Make
> sure you call createCall after the configuring the HTTPSender because
> it overwrites the service config. I don't know why the registration
> wouldn't work afterwards in that case. Maybe Axis developers can
> chime in here?
>
> You could try using the wsdd: open up the class I sent you and search
> for where it creates the wsdd. Now add typemapping statements to that
> hardcoded wsdd file. Then try configureNonBrokenHTTPSender and send
> it the uwsewsdd flag as 'true', it should use the hardcoded wsdd you
> just edited.
>
> Aaron
>
> Benjamin Flohr wrote:
>
> > Tried that but unfortunately it didn't do it for us... Our problem seems
> to
> > be that the handler registration, which we do in the generated stub
> > (call.setClientHandlers( handler, handler );) destroys any reference to
> previously
> > registered typemappings in the call. Even if we reregister them they
> don't
> > work.... We could try the client side deployment descriptor but don't
> know where
> > to put it.....
> > thanks
> >
> > Andrew and Benjamin
> > here's our code:
> >
> > in this method we set the header, we call this mehtods in all our
> > service-methods:
> >
> > private Call writeHeader( Call call )
> > {
> > MyHTTPHandler handler = new MyHTTPHandler();
> >
> > StringBuffer sb = new StringBuffer();
> > String key = this.getKeyedDigest( this.getEnvelopeAsString( call
> )
> > );
> >
> > //set the header info here
> > sb.append("HMAC_KEY: \"" + key + "\"\n" );
> >
> > handler.setOtherHeaders( sb );
> >
> > call.setClientHandlers( handler, handler );
> >
> >
> > return call;
> > }
> >
> >
> >
> > here the Call is created in the stub:
> >
> > private org.apache.axis.client.Call createCall()
> > throws java.rmi.RemoteException
> > {
> > try
> > {
> > org.apache.axis.client.Call _call = (
> > org.apache.axis.client.Call ) super.service.createCall();
> >
> > if ( super.maintainSessionSet )
> > {
> > _call.setMaintainSession( super.maintainSession );
> > }
> >
> > if ( super.cachedUsername != null )
> > {
> > _call.setUsername( super.cachedUsername );
> > }
> >
> > if ( super.cachedPassword != null )
> > {
> > _call.setPassword( super.cachedPassword );
> > }
> >
> > if ( super.cachedEndpoint != null )
> > {
> > _call.setTargetEndpointAddress( super.cachedEndpoint );
> > }
> >
> > if ( super.cachedTimeout != null )
> > {
> > _call.setTimeout( super.cachedTimeout );
> > }
> >
> > if ( super.cachedPortName != null )
> > {
> > _call.setPortName( super.cachedPortName );
> > }
> >
> > java.util.Enumeration keys = super.cachedProperties.keys();
> >
> > while ( keys.hasMoreElements() )
> > {
> > java.lang.String key = ( java.lang.String )
> > keys.nextElement();
> > _call.setProperty( key, super.cachedProperties.get( key
> ) );
> > }
> >
> > // All the type mapping information is registered
> > // when the first call is made.
> > // The type mapping information is actually registered in
> > // the TypeMappingRegistry of the service, which
> > // is the reason why registration is only needed for the
> first
> > call.
> > synchronized ( this )
> > {
> > if ( firstCall() )
> > {
> > // must set encoding style before registering
> > serializers
> > _call.setSOAPVersion(
> > org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS );
> > _call.setEncodingStyle(
> > org.apache.axis.Constants.URI_SOAP11_ENC );
> >
> > for ( int i = 0; i < cachedSerFactories.size(); ++i
> )
> > {
> > java.lang.Class cls = ( java.lang.Class )
> > cachedSerClasses.get( i );
> > javax.xml.namespace.QName qName = (
> > javax.xml.namespace.QName ) cachedSerQNames.get( i );
> > java.lang.Class sf = ( java.lang.Class )
> > cachedSerFactories.get( i );
> > java.lang.Class df = ( java.lang.Class )
> > cachedDeserFactories.get( i );
> > _call.registerTypeMapping( cls, qName, sf, df,
> false
> > );
> > }
> > }
> > }
> >
> > return _call;
> > }
> > catch ( java.lang.Throwable t )
> > {
> > throw new org.apache.axis.AxisFault( "Failure trying to get
> the
> > Call object",
> > t );
> > }
> > }
> >
> >
> >
> >
> >>Try this, I edited it in this message to remove some inapplicable
> >>things, so your mileage may vary. Just call: myservice =
> >>HTTPTransportHelper.configureNonBrokenHTTPTransport(myservice);
> >>
> >>Make SURE to edit HANDLER_CLASS field to refer to YOUR HTTPSender class.
> >>
> >>There are technically two ways to register the handler:
> >>programmatically, and through the client side deployment descriptor.
> >>In practice, to my knowledge, nobody uses client side deployment
> >>descriptors because they are rather superfluous (you don't really
> >>"deploy" clients). The flag usewsdd is there in case you want to test
> >>this path.
> >>
> >>---------------------------------------
> >>
> >>package your.package.name;
> >>
> >>import org.apache.axis.Handler;
> >>import org.apache.axis.configuration.XMLStringProvider;
> >>import org.apache.axis.deployment.wsdd.WSDDConstants;
> >>
> >>import org.apache.axis.EngineConfiguration;
> >>import org.apache.axis.client.AxisClient;
> >>import org.apache.axis.SimpleTargetedChain;
> >>import org.apache.axis.configuration.EngineConfigurationFactoryFinder;
> >>import org.apache.axis.configuration.SimpleProvider;
> >>
> >>public final class HTTPTransportHelper {
> >> private static final Class HANDLER_CLASS =
> >>your.package.name.YourHTTPSender.class;
> >>
> >> private HTTPTransportHelper() {}
> >>
> >> public static org.apache.axis.client.Service
> >>configureNonBrokenHTTPTransport(org.apache.axis.client.Service
> >>service) throws TransportNotFoundException {
> >> return configureNonBrokenHTTPTransport(service, false);
> >> }
> >>
> >> public static org.apache.axis.client.Service
> >>configureNonBrokenHTTPTransport(org.apache.axis.client.Service
> >>service, boolean usewsdd) throws TransportNotFoundException {
> >> EngineConfiguration config;
> >>
> >> Class handlerclass = HANDLER_CLASS
> >>
> >> if (usewsdd) {
> >> System.out.println("Using wsdd to configure non-broken http
> >>transport");
> >> String wsdd =
> >> "<deployment xmlns=\"http://xml.apache.org/axis/wsdd/\" " +
> >> "xmlns:java=\"" + WSDDConstants.URI_WSDD_JAVA +
> >>"\">\n" +
> >> " <transport name=\"http\" pivot=\"java:" +
> >> handlerclass + "\"/>\n" +
> >> /*" <service name=\"" + WSDDConstants.URI_WSDD + "\"
> >>provider=\"java:MSG\">\n" +
> >> " <parameter name=\"allowedMethods\"
> >>value=\"AdminService\"/>\n" +
> >> " <parameter name=\"className\"
> >>value=\"org.apache.axis.utils.Admin\"/>\n" +
> >> " </service>\n" +*/
> >> "</deployment>";
> >> config = new XMLStringProvider(wsdd);
> >> } else {
> >> System.out.println("Programmatically configuring non-broken
> >>http transport");
> >>
> >> /*org.apache.axis.client.Call.addTransportPackage("transport");
> >> org.apache.axis.client.Call.setTransportForProtocol("http",
> >>transport.HTTPTransport.class);*/
> >>
> >> EngineConfiguration defaultConfig =
> >>(EngineConfigurationFactoryFinder.newFactory()).getClientEngineConfig();
> >> SimpleProvider provider = new SimpleProvider(defaultConfig);
> >> Handler handler = null;
> >> try {
> >> handler = (Handler) handlerclass.newInstance();
> >> } catch (IllegalAccessException iae) {
> >> throw new TransportNotFoundException("Error instantiating
> >>handler class " + handlerclass + ": " + iae);
> >> } catch (InstantiationException ie) {
> >> throw new TransportNotFoundException("Error instantiating
> >>handler class " + handlerclass + ": " + ie);
> >> } catch (ClassCastException cce) {
> >> throw new TransportNotFoundException("handler class " +
> >>handlerclass + " is not an org.apache.axis.Handler: " + cce);
> >> }
> >>
> >> SimpleTargetedChain c = new SimpleTargetedChain(handler);
> >> provider.deployTransport("http", c);
> >> config = provider;
> >> }
> >>
> >> //service.setDefaultConfiguration(config);
> >> //service.setEngineConfiguration(config);
> >>
> >> AxisClient client = new AxisClient(config);
> >> service.setEngine(client);
> >>
> >> return service;
> >> }
> >>
> >> public static class TransportNotFoundException extends Exception {
> >> /*public TransportNotFoundException(String message, Throwable t) {
> >> super(message, t);
> >> }*/
> >> public TransportNotFoundException(String message) {
> >> super(message);
> >> }
> >> }
> >>}
> >>
> >>Benjamin Flohr wrote:
> >>
> >>
> >>>Hi Aaron,
> >>>
> >>>I have implemented a modified HttpSender and I think my problem is to
> >>>register this one dynamically. If you could send me the example code,
> >>
> >>that would be
> >>
> >>>great-
> >>>thanks, benjamin
> >>>
> >>>
> >>>
> >>>>By the way, I forgot to mention, if you are sending some "official"
> >>>>HTTP headers, Axis will forcibly strip them. The only solution for
> >>>>now is to either modify the distributed HTTPSender or create your own
> >>>>modified HTTPSender and register it dynamically (again, I can provide
> >>>>code illustrating this dynamic registration).
> >>>>
> >>>>See this bug:
> >>>>
> >>>>http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21812
> >>>>
> >>>>Aaron
> >>>>
> >>>>
> >>>>Aaron Hamid wrote:
> >>>>
> >>>>
> >>>>
> >>>>>Implement a javax.xml.rpc.handler.GenericHandler and register it on
> >>
> >>your
> >>
> >>>>>client (if sending headers) or server (if receiving headers). On the
>
> >>>>>client side you need to dynamically register your handler through the
>
> >>>>>handlerregistry of your service. On the server side it is a matter
> of
> >>>>>editing the deployment descriptor to include your handler.
> >>>>>
> >>>>>In your client handler you can do:
> >>>>>
> >>>>>public boolean handleRequest(MessageContext context) {
> >>>>> // get the headers object
> >>>>> Hashtable headers = (Hashtable)
> >>>>>context.getProperty(HTTPConstants.REQUEST_HEADERS);
> >>>>> if (headers == null) {
> >>>>> headers = new Hashtable();
> >>>>> context.setProperty(HTTPConstants.REQUEST_HEADERS, headers);
> >>>>> }
> >>>>>
> >>>>> // add a header
> >>>>> String someheadervalue = (String)
> context.getProperty("PROPS_KEY");
> >>>>> headers.put("MYHEADER", someheadervalue);
> >>>>>
> >>>>> return true;
> >>>>>}
> >>>>>
> >>>>>Now, you ask how the handler will know what header to set. Well, you
>
> >>>>>have to use the _setProperty() call on your stub to propagate
> >>>>>information to the handler. e.g.
> >>>>>
> >>>>>((javax.xml.rpc.Stub)yourapi)._setProperty("PROPS_KEY", "here is the
> >>>>>value of the header I want to set, thank you");
> >>>>>
> >>>>>As an additional treat, these properties are apparently not
> accessible
> >>>>>>>from the handler prior to Axis 1.1.
> >>>>>
> >>>>>On the server side your handler needs to do something like:
> >>>>>
> >>>>>public boolean handleRequest(javax.xml.rpc.handler.MessageContext
> >>>>>context) {
> >>>>> // get the servletrequest object
> >>>>> HttpServletRequest request = (HttpServletRequest)
> >>>>>context.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);
> >>>>> if (request == null) return true;
> >>>>>
> >>>>> // look up your header
> >>>>> String myheadervalue = (String) request.getHeader("MYHEADER");
> >>>>>
> >>>>> System.out.println("my header was propagated with this value!: " +
>
> >>>>>myheadervalue);
> >>>>>
> >>>>> return true;
> >>>>>}
> >>>>>
> >>>>>Note that this requires usage of specific internal Axis classes/APIs
> >>>>>(e.g. HTTPConstants properties set in the context), so it will
> probably
> >>
> >>>>>not be portable (although I imagine other frameworks will provide
> >>>>>similar mechanisms).
> >>>>>
> >>>>>I can provide sample code and/or libraries if you need.
> >>>>>
> >>>>>Aaron Hamid
> >>>>>CIT/I&D
> >>>>>Cornell University
> >>>>>
> >>>>>Benjamin Flohr wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>>>Hi*,
> >>>>>>
> >>>>>>we need to access the http headers and set them using information
> >>>>>>taken from
> >>>>>>the fully formed SOAP envelope before it is posted. We managed to do
>
> >>>>>>this by
> >>>>>>modifying the HttpSender and assigning it to the call as its
> handler.
> >>>>>>Unfortunately we lose the typemapping for the
> serializer/deserializer
> >>>>
> >>>>and
> >>>>
> >>>>
> >>>>>>can no
> >>>>>>longer parse the incoming SOAP message. Is there a straightforward
> way
> >>>>
> >>>>to
> >>>>
> >>>>
> >>>>>>alter
> >>>>>>Http headers? Can anyone help?
> >>>>>>
> >>>>>>thanks
> >>>>>>
> >>>>>>Andrew and Benjamin
> >>>>>
> >>>>>
> >>>>>
> >>
> >
>
>
--
benjamin - portfolio - www.instamatic.net
NEU F�R ALLE - GMX MediaCenter - f�r Fotos, Musik, Dateien...
Fotoalbum, File Sharing, MMS, Multimedia-Gru�, GMX FotoService
Jetzt kostenlos anmelden unter http://www.gmx.net
+++ GMX - die erste Adresse f�r Mail, Message, More! +++