首页 > 解决方案 > 转发具有完全相同 json 正文的请求

问题描述

我有一个 SpringBoot 应用程序,它只是充当中间人。它接收 JSON 格式的 API 请求,并通过使用完全相同的主体调用 S 的 API 将其转发到另一个服务器 S。

我正在探索解决方案,并遇到了一个涉及使用RestTemplate和的解决方案MultiValueMap。但是,由于 json 正文包含对象而不是简单的字符串,我相信我必须创建一个具有相应 POJO 的 DTO 才能使解决方案正常工作。

请问以上是唯一的解决方案,还是有一种简单的方法可以转发请求并取回响应?

标签: javajsonapispring-boot

解决方案


中间人服务器可以公开一个接受 a @RequestBodyofObject然后 HttpServletRequest用于RestTemplate将其转发到远程服务器的端点。

中间人

@RestController
@RequestMapping("/middleman")
public class MiddleManRestController {

    private RestTemplate restTemplate;

    @PostConstruct
    public void init() {
        this.restTemplate = new RestTemplate();
        this.restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(this.restTemplate.getRequestFactory()));
    }

    @RequestMapping(value = "/forward", method = RequestMethod.POST)
    public ResponseEntity<Object> forward(@RequestBody Object object, HttpServletRequest request) throws RestClientException {

        //setup the url and path
        final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("Remote server URL").path("EnpointPath");

        //add query params from previous request
        addQueryParams(request, builder);

        //specify the method
        final RequestEntity.BodyBuilder requestBuilder = RequestEntity.method(HttpMethod.POST, builder.build().toUri());

        //add headers from previous request
        addHeaders(request, requestBuilder);

        RequestEntity<Object> requestEntity = requestBuilder.body(object);
        ParameterizedTypeReference<Object> returnType = new ParameterizedTypeReference<Object>() {};

        //forward to the remote server
        return this.restTemplate.exchange(requestEntity, returnType);
    }

    private void addHeaders(HttpServletRequest request, RequestEntity.BodyBuilder requestBuilder) {
        Enumeration<String> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            String headerValue = request.getHeader(headerName);
            requestBuilder.header(headerName, headerValue);
        }
    }

    private void addQueryParams(HttpServletRequest request, UriComponentsBuilder builder) {
        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        Map<String, String[]> parameterMap = request.getParameterMap();
        if (parameterMap != null) {
            parameterMap.forEach((key, value) -> queryParams.addAll(key, Arrays.asList(value)));
        }
        builder.queryParams(queryParams);
    }
}

推荐阅读