users@jax-rpc.java.net

Re: Handling mustUnderstand Headers

From: Bobby Bissett - Javasoft <Robert.Bissett_at_Sun.COM>
Date: Thu, 02 Oct 2003 12:25:12 -0400

>
> And of course sod's law says I was just about to try this

That is always the way...

I'll try to answer your other email about "no actor" here to save some
inbox space. Even if you specify no roles in your xml files when
generating the handlers, the special soap actor
"http://schemas.xmlsoap.org/soap/actor/next" will be included for all
soap intermediaries.

So you can't exactly have *no* role in a handler, but the question of
your other email was then how to have the handler act as the ultimate
recipient of the message. You can do this and circumvent the endpoint by
having your handler return false from the handleRequest() method. This
will skip the rest of the processing of the request, including the rest
of the handler chain and the endpoint. You must still handle the
response, except that now you need to manually create the response
message since the endpoint won't do it. You can see it in action: throw
an "if (true) return false;" at the top of your handleRequest() method.
You will then see errors downstream in handleResponse or at the client
since you're returning an unusual message -- in fact, you're returning
the request if you do nothing else. But the endpoint won't be invoked.
So this gives you a way to cut the endpoint out of the app at the
handler level.

>
> I understand the SOAP processing model but based on the way the RI
> worked with actors I was hoping that by not specifying and actor the RI
> would associate the handler chain with 'no actor' such that when I
> returned the QName from getHeaders it would 'know' I had processed the
> header.

It would be easier in some cases if the runtime removed the element for
you, but might be unduly limiting. The whole system of roles/actors,
header names and mustUnderstand is used to determine whether or not the
message will be processed or sent back with a MustUnderstand fault, but
it doesn't affect what you actually do inside the handler. One specific
case where this matters is if you have two handlers that are in the same
role and both say that they understand the same header. In some cases,
the first handler may want to let the header element go through
unchanged (*), and in some cases it may want to detach it and then pass
the message on. Obviously, there's no rule that says you have to be
given a header that you declare that you understand. So while your
handler declares that it understands headers and wants to handle ones
targeted at certain roles, it is still up to the user to fufill the
handler contract and do the right thing in the code.

(*) That statement may sound like I'm contradicting my last email, but
there is an allowance for it: The soap spec says that an intermediary
should remove the header element that was targeted at it, but the spec
allows for the concept of a contract between an intermediary and a
following intermediary or endpoint to have a header with the same name
in it (and the same content as well if you'd like). Here's the text:
"[...] a recipient receiving a header element MUST NOT forward that
header element to the next application in the SOAP message path. The
recipient MAY insert a similar header element but in that case, the
contract is between that application and the recipient of that header
element." And if a header element just happens to be "similar" to
itself, then the handler's job is easy...

>
> As a matter of interest, why does the RI assume that if I return the
> QName from a chain associated with an actor I understand the header, but
> if I return the QName from a chain associated with a header no actor is
> specified.

I may be misunderstanding the question, so let me know if I am. If you
set up a handler with no actor at all, it will still be an actor in the
"next" role, and so all headers can be targeted at it either explicitly
or implicitly (a header element with no actor in it is targeted at the
"next" intermediaries). So you can have a handler that declares it
understands a certain header and not declare that it's in any particular
role.

>
> Also, why do I see the handleResponse method of my headers being called
> if I don't process a mustUnderstand header (with no actor). As the
> runtime throws an exception anyway shouldn't it short-circuit the
> response chain processing?

It's still being returned back to the client as response (or fault), so
the handler chain is still used. This can be pretty useful in some cases
-- imagine that you want to encode/decode the message payload whether
it's a good response or an error. You'll short-circuit the handler chain
(in whatever direction the message is going) if either a handler returns
false or throws an exception.

Good questions! Let me know what I've missed.

Cheers,
Bobby