On Thu October 22 2009 5:08:26 pm Brenda Coulson wrote:
> Dan
> 
> This does help enormously. I need to process my options to figure out which
> works best. Our system already runs like a dog so performance is a real
> issue. Just a quick question - since the Soap message I am receiving is
> technically wrong, is there any way to get the validator/parser to choke at
> that point - ie if my soap body is not namespace-qualified? That seems like
> the easiest thing to do and something that a web service processor should
> automatically have in place?

If using JAXB databinding (default) or XMLBeans, just turn on schema 
validation.  

<jaxws:endpoint name="{http://apache.org/hello_world_soap_http}SoapPort";
        wsdlLocation="wsdl/hello_world.wsdl"
        ......>
        <jaxws:properties>
            <entry key="schema-validation-enabled" value="true" />
        </jaxws:properties>
    </jaxws:endpoint>

That should automatically catch and schema related issues and send an 
exception back.

If using Aegis, not much can be done until CXF 2.3.   :-(

For Provider based endpoints, there in the latest SNAPSHOTS that turn on 
validation with the above flag as well.  Not available in a release yet 
though.

Dan



> 
> brenda
> 
> dkulp wrote:
> > On Thu October 22 2009 4:31:21 pm Brenda Coulson wrote:
> >> That is great to know! I am so confused between the difference between
> >> Interceptors and Handlers and when to use them. Ok so I have a Soap
> >> message
> >> that I am trying to ultimately validate. However, there are times when I
> >>  may receive a message that does not specify the namespace for the soap
> >>  payload. Example as follows:
> >>
> >> <soapenv:Envelope
> >>  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";>
> >>  <soapenv:Header/>
> >>    <soapenv:Body>
> >>       <getReference>
> >>          <agcHcsId>80640</agcHcsId>
> >>       </getReference>
> >>    </soapenv:Body>
> >> </soapenv:Envelope>
> >
> > Oi..  Ick..  Technically, that's an invalid soap message as, according to
> > spec, direct child elements of soap:Body must be namespace qualified.
> > But
> > let's ignore that issue for a second.   :-)
> >
> >> Technically the XML inside the payload is well-formed so the validator
> >> does
> >> not complain. However, there is a required element, referenceId,
> >> missing. So as I am validating, I would like to just get to the Soap
> >> payload, aka
> >>
> >>       <getReference>
> >>          <agcHcsId>80640</agcHcsId>
> >>       </getReference>
> >>
> >> And validate it against my schema, regardless of whether or no the
> >>  namespace is specified. I need to do this for all methods on my web
> >>  service, one of which has a Soap attachment, which based on other posts
> >> I
> >>  saw, may cause some problems with the different processing phases.
> >>
> >> Net effect is how do I just get the Soap payload part of the message? If
> >> I
> >> don't need to use a Logical Handler, great. If I do, great too. Does not
> >> matter to me.
> >
> > OK.  There are a couple of options that you could pursue for this.
> >
> > 1) You COULD write an interceptor that lives just before the
> > DocLiteralInInterceptor that takes the XMLStreamReader and wrappers it
> > with a
> > new XMLStreamReader that would "correct" the namespace issue.   (override
> > the
> > getNamespace calls and such to return the correct value).   If you do
> > that,
> > you could just turn on the CXF built in schema validation stuff.    See:
> > http://cxf.apache.org/faq.html
> > That option would have the best performance as the built in jaxb
> > validation
> > doesn't need to load the whole message while unmarshalling.
> >
> > 2) Next easiest is to configure in the SAAJInInterceptor (or have your
> > interceptor call it) and work with the SAAJ model directly.   Your
> > interceptor
> > would just look something like:
> >
> >
> >     public MyInterceptor() {
> >         super(Phase.PRE_PROTOCOL);
> >         getAfter().add(SAAJInInterceptor.class.getName());
> >     }
> >     public void handleMessage(SoapMessage msg) throws Fault {
> >         SOAPMessage doc = msg.getContent(SOAPMessage.class);
> >         if (doc == null) {
> >             saajIn.handleMessage(msg);
> >             doc = msg.getContent(SOAPMessage.class);
> >         }
> >        //process doc here
> >     }
> >
> > Not quite as good as it loads the whole message into memory, but
> > certainly easy to work with.
> >
> > 3) Register a jaxws LogicalHandler with the endpoint.   The
> > LogicalMessageContext that is passed in has a
> > getLogicalMessage().getPayload()
> > method that returns a Source.    (I think a DOMSource is what we return)
> > Advantage here is that it would be portable to other jaxws
> > implementations.
> > Disadvantage is that performance is way worse than option 2.   Also,
> > JAX-WS
> > handlers have to be registered per-endpoint whereas an interceptor can be
> > configured on the Bus and thus be more "global".
> >
> > Hope that helps!
> 

-- 
Daniel Kulp
dk...@apache.org
http://www.dankulp.com/blog

Reply via email to