13

I am trying to create a HttpServlet that forwards all incoming requests as is, to another serlvet running on a different domain.

How can this be accomplished? The RequestDispatcher's forward() only operates on the same server.

Edit: I can't introduce any dependencies.

bjornl
  • 1,222
  • 3
  • 13
  • 27

3 Answers3

21

You can't when it doesn't run in the same ServletContext or same/clustered webserver wherein the webapps are configured to share the ServletContext (in case of Tomcat, check crossContext option).

You have to send a redirect by HttpServletResponse.sendRedirect(). If your actual concern is reusing the query parameters on the new URL, just resend them along.

response.sendRedirect(newURL + "?" + request.getQueryString());

Or when it's a POST, send a HTTP 307 redirect, the client will reapply the same POST query parameters on the new URL.

response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
response.setHeader("Location", newURL);

Update as per the comments, that's apparently not an option as well since you want to hide the URL. In that case, you have to let the servlet play for proxy. You can do this with a HTTP client, e.g. the Java SE provided java.net.URLConnection (mini tutorial here) or the more convenienced Apache Commons HttpClient.

If it's GET, just do:

InputStream input = new URL(newURL + "?" + request.getQueryString()).openStream();
OutputStream output = response.getOutputStream();
// Copy.

Or if it's POST:

URLConnection connection = new URL(newURL).openConnection();
connection.setDoOutput(true);
// Set and/or copy request headers here based on current request?

InputStream input1 = request.getInputStream();
OutputStream output1 = connection.getOutputStream();
// Copy.

InputStream input2 = connection.getInputStream();
OutputStream output2 = response.getOutputStream();
// Copy.

Note that you possibly need to capture/replace/update the relative links in the HTML response, if any. Jsoup may be extremely helpful in this.

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Ok. What if I don't want to expose the target URL to the end user? Nothing like App Engine's URLFetch? http://code.google.com/appengine/docs/python/urlfetch/overview.html – bjornl Oct 12 '10 at 15:30
  • 1
    Then you need to let the servlet act as a proxy using a HTTP client. – BalusC Oct 12 '10 at 15:31
  • Better use HttpClient 4.x instead of 3.x - more flexible in capabilities. – Neeme Praks Oct 12 '10 at 15:40
  • @BalusC i am using the URLconnection to send an HTTPRequest , and its working just fine when i am testing locally , but our production uses clustered weblogic , it gives me java.net.NoRouteToHostException –  Dec 17 '14 at 10:42
3

As others have pointed out, what you want is a proxy. Your options:

  1. Find an open-source Java library that does this. There are a few out there, but I haven't used any of them, so I can't recommend any.

  2. Write it yourself. Shouldn't be too hard, just remember to deal with stuff like passing along all headers and response codes.

  3. Use the proxy module in Apache 2.2. This is the one I'd pick, because I already know that it works reliably.

Mike Baranczak
  • 7,894
  • 6
  • 39
  • 65
2

Jetty has a sample ProxyServlet implementation that uses URL.openConnection() under the hood. Feel free to use as-is or to use as inspiration for your own implementation. ;-)

Or you can use Apache HttpClient, see the tutorial.

Neeme Praks
  • 8,150
  • 5
  • 40
  • 46