How to forward a request using JAX-RS?

2019-04-09 10:23发布

问题:

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?

回答1:

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:

  • Response.seeOther(URI): Used in the redirect-after-POST (aka POST/redirect/GET) pattern.
  • Response.temporaryRedirect(URI): Used for temporary redirection.

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;