我正在寻找一种方法,该方法如何转发在@RestController
类中向端点发出的POST请求,然后将其转发到不带正文和标头的外部URL(当然,还要从此API返回响应),是否可以通过使用一些弹簧功能来做到这一点?我发现的唯一解决方案是从@RequestBody
中提取正文,并从HttpServletRequest
中提取标头,然后使用RestTemplate
执行请求。有没有更简单的方法?
@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());
}
}
以上代码摘自此answer。
答案 0 :(得分:1)
与Spring相比,这更多是HTTP规范的问题,在Spring中,服务器应返回307重定向状态,指示客户端应使用相同的方法遵循重定向并发布数据。
通常避免在野外使用,因为存在大量潜在的误用和摩擦,如果您符合W3.org规范,该规范指出应在重新启动新位置之前请求客户端之前提示该客户端。
一种选择是让您的Spring终结点充当代理,而不是发出任何形式的重定向来对目标位置进行POST调用。
307临时重定向(自HTTP / 1.1起)在这种情况下,应使用另一个URI重复请求,但以后的请求仍可以使用原始URI。2与303相比,重新发出请求时,不应更改请求方法原始请求。例如,必须使用另一个POST请求重复POST请求。