How to forward a request using JAX-RS?

user2313423 picture user2313423 · Jul 15, 2013 · Viewed 10k times · Source

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?

Answer

cassiomolin picture cassiomolin · Oct 15, 2015

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;