Forward Httpservletrequest to a Different Server

Forward HttpServletRequest to a different server

Unfortunately there is no easy way to do this. Basically you'll have to reconstruct the request, including:

  • correct HTTP method
  • request parameters
  • requests headers (HTTPUrlConnection doesn't allow to set arbitrary user agent, "Java/1.*" is always appended, you'll need HttpClient)
  • body

That's a lot of work, not to mention it won't scale since each such proxy call will occupy one thread on your machine.

My advice: use raw sockets or netty and intercept HTTP protocol on the lowest level, just replacing some values (like Host header) on the fly. Can you provide more context, why so you need this?

Forward(request,response) doesn't forward the URL

I can see in the displayProducts() method, you have defined the url as follows:

String url= "/maint/products.jps";

shouldn't that be a typo??

String url= "/maint/products.jsp";

file extension is wrong right?

RequestDispatcher for remote server?

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.

TomEE: Forwarding request to a different war

I decided to debug the TomEE and found this code that was causing issues in CXFJAXRSFilter.java:

    @Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
if (!HttpServletRequest.class.isInstance(request)) {
chain.doFilter(request, response);
return;
}

final HttpServletRequest httpServletRequest = HttpServletRequest.class.cast(request);
final HttpServletResponse httpServletResponse = HttpServletResponse.class.cast(response);

if (CxfRsHttpListener.TRY_STATIC_RESOURCES) { // else 100% JAXRS
if (servletMappingIsUnderRestPath(httpServletRequest)) {
chain.doFilter(request, response);
return;
}
final InputStream staticContent = delegate.findStaticContent(httpServletRequest, welcomeFiles);
if (staticContent != null) {
chain.doFilter(request, response);
return;
}
}

try {
delegate.doInvoke(
new ServletRequestAdapter(httpServletRequest, httpServletResponse, request.getServletContext()),
new ServletResponseAdapter(httpServletResponse));
} catch (final Exception e) {
throw new ServletException("Error processing webservice request", e);
}
}

The line that was causing issues:

if (CxfRsHttpListener.TRY_STATIC_RESOURCES) { // else 100% JAXRS

So I found the definition of TRY_STATIC_RESOURCES

public static final boolean TRY_STATIC_RESOURCES = "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.jaxrs.static-first", "true"));

So I updated the system.property of openejb.jaxrs.static-first to false and it worked.

$> curl 'http://localhost:8080/web1/webapp1?op=foo'
Hello From Webapp2 Rest Resource%

I pushed up my changes to my github repo for those of us that are playing along.



Related Topics



Leave a reply



Submit