RequestDispatcher for remote server?
Asked Answered
S

3

14

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.

Sigil answered 12/10, 2010 at 15:19 Comment(0)
D
22

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.

Den answered 12/10, 2010 at 15:26 Comment(5)
Ok. What if I don't want to expose the target URL to the end user? Nothing like App Engine's URLFetch? code.google.com/appengine/docs/python/urlfetch/overview.htmlSigil
Then you need to let the servlet act as a proxy using a HTTP client.Den
Better use HttpClient 4.x instead of 3.x - more flexible in capabilities.Preferment
@Den 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.NoRouteToHostExceptionShing
If using Java 11+, you can also use the native java.net.http.HttpClient, which makes things pretty easy.Enforcement
B
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.

Breed answered 13/10, 2010 at 2:20 Comment(0)
P
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.

Preferment answered 12/10, 2010 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.