9

I want to forward a REST request to another server.

I use JAX-RS with Jersey and Tomcat. I tried it with setting the See Other response and adding a Location header, but it's not real forward.

If I use:

request.getRequestDispatcher(url).forward(request, response); 

I get:

  • java.lang.StackOverflowError: If the url is a relative path
  • java.lang.IllegalArgumentException: Path http://website.com does not start with a / character (I think the forward is only legal in the same servlet context).

How can I forward a request?

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
user2313423
  • 745
  • 3
  • 7
  • 12
  • 1
    You should probably be sending a redirect. `HttpServletResponse#sendRedirect(String)` – Sotirios Delimanolis Jul 15 '13 at 16:05
  • @SotiriosDelimanolis But this HttpServletResponse#sendRedirect(String) method basically sends a 302 HTTP response code, with the URL in the LOCATION header I think. So it's almost the same as my SEE_OTHER "solution", but it's not a real forward. Or am I wrong? – user2313423 Jul 16 '13 at 08:06
  • Did you find a solution for this other than using the `302` redirect? When using the RequestDispatcher.forward, I get a `java.lang.ClassCastException: org.glassfish.jersey.message.internal.TracingLogger$1 cannot be cast to org.glassfish.jersey.message.internal.TracingLogger` – ulrich Apr 09 '15 at 11:14

1 Answers1

10

Forward

The RequestDispatcher allows you to forward a request from a servlet to another resource on the same server. See this answer for more details.

You can use the JAX-RS Client API and make your resource class play as a proxy to forward a request to a remote server:

@Path("/foo")
public class FooResource {

    private Client client;

    @PostConstruct
    public void init() {
        this.client = ClientBuilder.newClient();
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public Response myMethod() {

        String entity = client.target("http://example.org")
                              .path("foo").request()
                              .post(Entity.json(null), String.class);   

        return Response.ok(entity).build();
    }

    @PreDestroy
    public void destroy() {
        this.client.close();
    }
}

Redirect

If a redirect suits you, you can use the Response API:

See the example:

@Path("/foo")
public class FooResource {

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public Response myMethod() {

        URI uri = // Create your URI
        return Response.temporaryRedirect(uri).build();
    }
}

It may be worth it to mention that UriInfo can be injected in your resource classes or methods to get some useful information, such as the base URI and the absolute path of the request.

@Context
UriInfo uriInfo;
cassiomolin
  • 124,154
  • 35
  • 280
  • 359