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! +++

Reply via email to