转发具有完全相同的json正文的请求

时间:2018-12-13 06:15:47

标签: java json api spring-boot

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

我正在探索解决方案,并遇到了涉及RestTemplateMultiValueMap用法的解决方案。但是,由于json主体包含对象而不是简单的String,我相信我必须创建具有相应POJO的DTO才能使解决方案起作用。

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

2 个答案:

答案 0 :(得分:0)

中间人服务器可以公开接受@RequestBody中的Object的端点,并且 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);
    }
}

答案 1 :(得分:0)

即使复杂和嵌套的JSON对象也可以放入键为String且值为Object的Map中。 我相信您应该只使用这样的地图作为请求正文,然后将其转移到另一个API。