6

I've a third-party servlet inside a JAR that I cannot change. I've extended that servlet and been using it normally as a servlet should be used, the client side makes an HTTP request that invokes my servlet.

But now the client wants an automatic service, that is, I will need to do some requests to that third party servlet from the same webapp where the servlet is.

I looked at the the third party servlet code but I didn't found a place to bypass the servlet because the HttpServletRequest and HttpServletResponse objects are passed from method to method... Basically it seems that I would need to re-implement all the third party code.

Solutions I found but do not satisfy me:

Call servlet from URL with HttpURLConnection: My common sense says that calling the third party servlet from a url is not the best way to go, besides the overhead added, I don't want to expose the third party servlet. Calling my servlet from a url also brings problems with sessions and other things.

Call the doGet directly: This seems to be out of the question because there is no implementation for the HttpServletRequest and HttpServletResponse.

Use jMock or something like that: Didn't explore this solution yet, but it seams wrong to use a test-driven library in the real environment.

Anyone has an idea how to interact with that third party servlet?

EDIT:

Since my English is not very good and I'm finding difficult to explain myself here goes a schematic to try to explain better

Schematic

EDIT2: After a meeting the third party maker they offer to isolate the methods I need to avoid calling the servlet. If you don't have the same luck I did check out both gigadot and BalusC answers.

Jose Antonio
  • 444
  • 4
  • 15
  • What do you want to do with the servlet? The answer will depend on it. Since you are not saying anything about that I don't think there is a generic solution for you. – gigadot Nov 29 '11 at 18:29
  • 2
    "an automatic service" what is it? – gigadot Nov 29 '11 at 18:31
  • Forwarding the request to that servlet is not an option? – Bhesh Gurung Nov 29 '11 at 18:31
  • @gigadot The servlet its a complex third party solution that does a lot of things, basically it is like a report utility. In this case I will need to ask the servlet to make me a report for specific report type at moment in time (and other parameters), then I will not need the results but they will be kept in session, and then I will do another call to the servlet to ask for an xls file with the results in session. I don't know if I'm explaining well, but is a really complex system. – Jose Antonio Nov 29 '11 at 18:39
  • You can try to use existing stub implementations of Servlet API classes. There are many such implementations, though usually they are parts of big projects, such as Spring Test. – axtavt Nov 29 '11 at 18:40
  • @gigadot The "automatic saervice" is a scheduler. It will call the servlet at a given time – Jose Antonio Nov 29 '11 at 18:41
  • @Bhesh The problem is I don't have anywhere to forwarding from, since there is no servlet request. – Jose Antonio Nov 29 '11 at 18:44
  • @JoseAntonio how many client requests in order to get your xls file? two? – gigadot Nov 29 '11 at 18:45
  • @gigadot Actually I need three requests, one identifies the report, the second the params and the third returns the xls – Jose Antonio Nov 29 '11 at 18:48
  • Your diagram is obviously wrong! Your scheduler cannot access the third party servlet object since it does not exist in your web application. That's because you have extend the thrid party servlet class. The scheduler should only be able to find the obeject of your extended servlet. – gigadot Nov 29 '11 at 20:01

3 Answers3

1

Calling my servlet from a url also brings problems with sessions and other things.

If that's the sole problem, then just use the CookieManager to maintain the cookies (and thus also the session) in subsequent URLConnection calls.

// First set the default cookie manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

// All the following subsequent URLConnections will use the same cookie manager.
URLConnection connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

See also:

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • That is useful info. It doesn't exactly resolve the problem but I can use some of the knowledge. My problem with sessions goes deeper, since it's is not the http session I have to care but a system session also that must be associated to a user name. Probably will have to create a specific user for this porpoise. – Jose Antonio Nov 29 '11 at 19:13
  • Do you want to use the currently running `HttpSession` for that other servlet as well? In other words, you're invoking that other servlet from inside a servlet? (which was what I initially understood, see also the edit history, but I changed my minds and the answer when I reinterpreted the "automatic service" phrase in your question; an automatic service can (should) of course never be initiated from inside a servlet). – BalusC Nov 29 '11 at 19:15
  • No, I'm trying to invoke the third party servlet by itself. The third party servlet is not mapped (mine is, but it runs a lot of code that is not necessary in this case), I can map it as a last resource. But where do I get the request in the first place, since there is no request to the server (since the running code is already inside the server). //See the schematic I've added in the question – Jose Antonio Nov 29 '11 at 19:50
  • Thank you for the help, fortunately the third party offer to isolate the methods I need. I marked gigadot answer as correct but since I cannot mark both answers as correct I've added a suggestion in my question to check out your answer too. Thanks! – Jose Antonio Nov 30 '11 at 10:45
1

If I understand your question correctly, you have implemented or have a third party servlet that generate the report for you.

Now what you want to do is to periodically generate the report and store in session so that when user want to get the report they can retrieve it using another servlet.

If this is the case then you want the task to be running periodically on your server. You will need some sort of task scheduler to run on your server and what the task does is just make a http request to your servlet (this can be http GET or POST).

gigadot
  • 8,743
  • 7
  • 33
  • 49
  • It's something like that, but it is similar to the first solution I found, I would have to expose the servlet (I'm not very keen to do that since it doesn't have any type os security implemented) and it seems very correct to make a loopback with the requests. But it seems that will be the the only way to go. – Jose Antonio Nov 29 '11 at 19:05
  • how about writing a filter to reject all requests that do not come from your own servlet? – gigadot Nov 29 '11 at 19:08
  • Also read BalusC's answer if you want to use session since it may not be visible to user. – gigadot Nov 29 '11 at 19:09
  • But a filter will also reject my requests if I have to do a loopback. I will have to think more about your idea, It can lead me somewere – Jose Antonio Nov 29 '11 at 19:55
  • You can make a filter that only reject the request that doesn't come from your own ip. – gigadot Nov 29 '11 at 19:58
  • Thank you for the help, fortunately the third party offer to isolate the methods I need. I marked your answer as correct so it can help others. Thanks! – Jose Antonio Nov 30 '11 at 10:42
0

You could try to separate out your servlet logic into several phases. The entry point that takes the request/result, the action that processes parameters sent and generates the output.

public void doGet(HttpServletRequest req, HttpServletResponse rsp){
    relay(rsp,act(req.getParameter("a"));
}

public static String act(String a){
    return "You provided: " + a;
}

public static void relay(HttpServletResponse rsp, String content){
    rsp.setResponseCode(200);
    rsp.getOutputStream().write(content.getBytes());
}

This lets you call act(whatever) to do what you want, and then do what you want with the response. If returning a string is not enough, you could make any return type you want, probably something that could contain a list of headers, response code, and content template.

Nthalk
  • 3,606
  • 1
  • 23
  • 19