Hi Toshiyuki Kimura, Here are my suggestions.. follow the --->> (1): H2(req) generates a response msg and the runtime directly sends back it to the client *** Currently, I'm not sure this path is needed *** --->> According to spec the handler that intends to return false is responsible to set the response message in handleRequest method. but i don't see any need or how to do this. Even i am not sure if we need to handle this.
(2): H1(res) generates a response msg, and after that the runtime sends back it to the client --->> I want to address (2) and (4) together. (3): H2(res) generates a response msg, and the runtime invokes the next handler ( handleResponse of H1 ) *** The spec says "It should be the default". *** ---->> So the runtime system should be able to make a decesion to follow 'default' or look for user customization?? I think this can be achieved by setting a property in context passed to the handler that intends to return false. (4): H3(res) generates a response msg, and the runtime invokes the next handler ( handleResponse of H2 ) ----->> As we ruled out (1) .. atleast for now and we know what default means.. i want to bring up the question i raised last time .. what are the customizations user should be allowed to do??? I think two options mentioned below would be more generic. (a) As in the solution you proposed just let system invoke all the handlers leave the responsibility to user implementation of handleResponse. Option (4) set empty string as "HandlerFault" property in context passed to the handler .. to indicate the ChainImpl to invoke all the handlers and the handleResponse implementations of configured handlers are responsible for how they generate response and pass it over. (This is a convention i came up with .. obviously there should a better way of conveying this) (b) Should be able to say to the system to start from a perticular point in the chain and continue from there. If he configures it to be H1 that would be the only handler invoked and responsible for setting appropriate response SOAP message. set class name of the handler in configured chain from which you want to start as "HandlerFault" propert y in context passed to the handler So now we can mix both our solutions to achieve more generic solution. It doesn't look readable but i tried my best Introduced '--->>' for parts to be noted. I used the same code u sent in prevous mails and changed it a bit. --------- Handler ----------------- public boolean handleRequest( javax.xml.rpc.handler.MessageContext context) { // **** if you want to return false ****: // set the class name of the handler implementation: --->>> //context.setProperty("HandlerFault", this.getClass().getName()); String handlefault = ""; // to invoke all the handlers in chain context.setProperty("HandlerFault", handlefault); or String handlefault = "MyHandlers.handler3" // to start from handler -3 class in chain //Note that this should be an existing handler in configured chain. context.setProperty("HandlerFault", handlefault); or -- DON'T SET THIS PROPERTY TO ALLOW THE SYSTEM TO FOLLOW DEFAULT FLOW --- return false; } public boolean handleResponse( javax.xml.rpc.handler.MessageContext context) { // get the state (class name was set or not) from MsgCtx: String name = (String)context.getProperty("HandlerFault"); //if (name != null && name instanceof String && name.equals(this.getClass().getName())) { ---->> if (name != null && name instanceof String ) { if(name.equals(""){ // this is a fault situation and is upto you how to handle it... } else if(name.equals(this.getClass().getName())){ // this is a fault situation and you are responsible to set SOAP response message } } else { : : } return true; } ------------------HandlerChainImpl ----------------------------------------- protected int lastHandlerIndex = 0; public boolean handleRequest(MessageContext _context) { SOAPMessageContext context = (SOAPMessageContext) _context; boolean processFault = false; for (int i = 0; i < size(); i++) { Handler currentHandler = getHandlerInstance(i); lastHandlerIndex = i; try { if (currentHandler.handleRequest(context) == false) { // get the state (class name was set or not) from MsgCtx: String name = (String)context.getProperty("HandlerFault"); boolean classFound = false; if( (name != null) && name instanceof String ) { if(name.equals("")){ lastHandlerIndex = size() -1; } else if( ! name.equals("")){ // have to traverse back from this handler class that is set by user .. for (int j = 0; j < size(); j++) { if( name.equals(getHandlerInstance(j).getClass().getName())) { // found it .. classFound = true; lastHandlerIndex = j; // set this as the index to start. continue; } }// end find class for if(!classFound){ // automatically falls back to default.. in case of wrong class being set // or we can think of throwing a runtime exception here... } }// end of if name != "" } return false; } } catch (SOAPFaultException sfe) { throw sfe; } } } public boolean handleResponse(MessageContext context) { for (int i = lastHandlerIndex; i >= 0; i--){ Handler currentHandler = getHandlerInstance(i); if (getHandlerInstance(i).handleResponse(context) == false) return false; } return true; } ----------------------------------------------- These chages along with the one u mentoined SOAPService class should take care of everything. Regards, Sreekant >