The easiest way to proxy HttpServletRequest in Spr

2019-06-04 22:10发布

I'm building REST services using spring-mvc and what I'm looking for now is a way to proxy HTTP request to external REST service from inside Spring MVC controller.

I'm getting HttpServletRequest object and want to proxy it making as few changes as possible. What is essential for me is keeping all the headers and attributes of incoming request as they are.

@RequestMapping('/gateway/**')
def proxy(HttpServletRequest httpRequest) {
    ...
}

I was trying simply to send another HTTP request to external resource using RestTemplate but I failed to find a way to copy REQUEST ATTRIBUTES (which is very important in my case).

Thanks in advance!

3条回答
倾城 Initia
2楼-- · 2019-06-04 22:21

You can use the spring rest template method exchange to proxy the request to a third party service.

@RequestMapping("/proxy")
@ResponseBody
public String proxy(@RequestBody String body, HttpMethod method, HttpServletRequest request, HttpServletResponse response) throws URISyntaxException {
    URI thirdPartyApi = new URI("http", null, "http://example.co", 8081, request.getRequestURI(), request.getQueryString(), null);

    ResponseEntity<String> resp =
        restTemplate.exchange(thirdPartyApi, method, new HttpEntity<String>(body), String.class);

    return resp.getBody();
}

What is the restTemplate.exchange() method for?

查看更多
仙女界的扛把子
3楼-- · 2019-06-04 22:34

if you think of applying the API gateway pattern for microservices, have a look at Netflix zuul which is a good alternative in the spring boot ecosystem. A good example is provided here.

查看更多
祖国的老花朵
4楼-- · 2019-06-04 22:44

I wrote this ProxyController method in Kotlin to forward all incoming requests to remote service (defined by host and port) as follows:

@RequestMapping("/**")
fun proxy(requestEntity: RequestEntity<Any>, @RequestParam params: HashMap<String, String>): ResponseEntity<Any> {
    val remoteService = URI.create("http://remote.service")
    val uri = requestEntity.url.run {
        URI(scheme, userInfo, remoteService.host, remoteService.port, path, query, fragment)
    }

    val forward = RequestEntity(
        requestEntity.body, requestEntity.headers,
        requestEntity.method, uri
    )

    return restTemplate.exchange(forward)
}

Note that the API of the remote service should be exactly same as this service.

查看更多
登录 后发表回答