views:

35

answers:

3

I am currently implementing an OpenID Relying Party (RP) and Identity Provider (IdP) with Java HttpServlets using the OpenID4Java library. I have run into trouble getting two servlets to communicate with each other. I believe the problem I am having is to do more with how Servlets behave, however I have included info about my application for a better sense as to what is happening.

The scenario is as follows:

Servlet #1 (my RP) sends a request to Servlet #2 (my IdP) as follows:

httpResp.sendRedirect(authReq.getDestinationUrl(true));

Essentially authReq = a message with various OpenID specific parameters. By invoking getDestinationUrl(true) it encodes the request into a url to send via a GET.

Servlet #2 catches the above GET in its doGet method. It parses the information, and crafts a reply to send back to Servlet #1 in the following fashion:

String responseText = processRequest(httpReq, httpResp);

        httpResp.setContentType("text/html");
        OutputStream outputStream = httpResp.getOutputStream();
        //
        outputStream.write(responseText.getBytes());
        outputStream.close();

My problem is, this response never makes it back to Servlet #1. I would expect that when Server #1 receives the response from Servlet #2 that its' doGet or doPost method would catch the message. However neither case happens.

Any advice would be greatly appreciated.

Thanks!

+1  A: 

Hi,

The response of 2nd servlet will directly go on client side i think because its is the original client right? Your 1st servlet is just redirecting the request.

So, if you want to communicate between servlets, Use URLConnection or Apache HttpClient to communicate with 2nd servlet.

You can also make JSP instead of 2nd servlet, then pass you data from 1st servlet to that JSP. That JSP's response will be sent to client then. After all you can do all logic in JSP what you can in servlet.

Hope this helps.

parth.

Paarth
A: 

If you want two servlets to communicate with each other within an application, you can use the ServletContext object and share data via ServletContext.setAttribute and ServletContext.getAttribute and RequestDispatcher obtained via HttServletRequest or ServletContext

In your case can the Servlet#2 be invoked directly by the client? If not then you should probably refactor the processRequest(request, response) into a Utility class or a library. Which in turn can be called by both Servlet#1 and Servlete#2.

response.sendRedirect sends a redirect (301 moved permenently, ithink) to the browser. So your servlet actually sends a response to browser with 301 and then browser makes a request to servlet#2 again.

naikus
A: 

You can use RequestDispatcher to include your second servlet's response. In this way, the control returns to the first servlet after the method completes.

RequestDispatcher dispatcher = request.getRequestDispatcher(authReq.getDestinationUrl(true));
dispatcher.include(request, response);

However, with this, the response generated by the called servlet will be sent to the browser. If you want your calling servlet to capture the message from called servlet without sending to browser, you can either create a response wrapper (A wrapper writing the contents in a string) and pass this wrapper when you include the second servlet or better you can share the data in either of the scopes (Preferably 'request' scope): You can set the data in the request scope in called servlet and you can retrieve it in the calling servlet after include() completes.

When you redirect, you are telling the browser to make a new request for the URL. So there will be new request/response objects created as if you had clicked on a link in your page.

Hope this helps.

Marimuthu Madasamy