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