spring mvc rest service redirect / forward / proxy spring mvc rest service redirect / forward / proxy java java

spring mvc rest service redirect / forward / proxy


You can mirror/proxy all requests with this:

private String server = "localhost";private int port = 8080;@RequestMapping("/**")@ResponseBodypublic String mirrorRest(@RequestBody String body, HttpMethod method, HttpServletRequest request) throws URISyntaxException{    URI uri = new URI("http", null, server, port, request.getRequestURI(), request.getQueryString(), null);    ResponseEntity<String> responseEntity =        restTemplate.exchange(uri, method, new HttpEntity<String>(body), String.class);    return responseEntity.getBody();}

This will not mirror any headers.


Here's my modified version of the original answer, which differs in four points:

  1. It does not make the request body mandatory, and as such does not let GET requests fail.
  2. It copies all headers present in the original request. If you are using another proxy/web server, this can cause issues due to content length/gzip compression. Limit the headers to the ones you really need.
  3. It does not reencode the query params or the path. We expect them to be encoded anyway. Note that other parts of your URL might also be encoded. If that is the case for you, leverage the full potential of UriComponentsBuilder.
  4. It does return error codes from the server properly.

@RequestMapping("/**")public ResponseEntity mirrorRest(@RequestBody(required = false) String body,     HttpMethod method, HttpServletRequest request, HttpServletResponse response)     throws URISyntaxException {    String requestUrl = request.getRequestURI();    URI uri = new URI("http", null, server, port, null, null, null);    uri = UriComponentsBuilder.fromUri(uri)                              .path(requestUrl)                              .query(request.getQueryString())                              .build(true).toUri();    HttpHeaders headers = new HttpHeaders();    Enumeration<String> headerNames = request.getHeaderNames();    while (headerNames.hasMoreElements()) {        String headerName = headerNames.nextElement();        headers.set(headerName, request.getHeader(headerName));    }    HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);    RestTemplate restTemplate = new RestTemplate();    try {        return restTemplate.exchange(uri, method, httpEntity, String.class);    } catch(HttpStatusCodeException e) {        return ResponseEntity.status(e.getRawStatusCode())                             .headers(e.getResponseHeaders())                             .body(e.getResponseBodyAsString());    }}


You can use Netflix Zuul to route requests coming to a spring application to another spring application.

Let's say you have two application: 1.songs-app, 2.api-gateway

In the api-gateway application, first add the zuul dependecy, then you can simply define your routing rule in application.yml as follows:

pom.xml

<dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>    <version>LATEST</version></dependency>

application.yml

server:  port: 8080zuul:  routes:    foos:      path: /api/songs/**      url: http://localhost:8081/songs/

and lastly run the api-gateway application like:

@EnableZuulProxy@SpringBootApplicationpublic class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

Now, the gateway will route all the /api/songs/ requests to http://localhost:8081/songs/.

A working example is here: https://github.com/muatik/spring-playground/tree/master/spring-api-gateway

Another resource: http://www.baeldung.com/spring-rest-with-zuul-proxy