【问题标题】:SpringBoot how to Send response to other URLSpring Boot 如何将响应发送到另一个 URL
【发布时间】:2017-11-30 06:46:26
【问题描述】:

我有以下代码:

@RequestMapping(
            consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE},
            path = "api/api1",
            method = RequestMethod.POST,
            produces = MediaType.ALL_VALUE
    )
    public ResponseEntity<?> api1CallBack(@RequestBody String requestBody, HttpServletRequest request) throws IOException, GeneralSecurityException, URISyntaxException {
       String response="{SOME_JSON}";
        URI callbackURL = new URI("http://otherAPIEnv/api2");
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setLocation(callbackURL);
        return new ResponseEntity<String>(response,httpHeaders, HttpStatus.OK);
    }

我尝试了上面的代码,但是当我通过 curl 访问 api1 时,我在同一台机器上得到了响应,但我希望将响应重定向到 otherAPIEnv 机器上的 api2。

有人可以建议如何实现这种请求和响应吗?

【问题讨论】:

    标签: java spring spring-boot response.redirect


    【解决方案1】:

    当您向 URL 发送请求时,它应该响应相同的,否则客户端将等待它直到超时。

    因此,在这种情况下,方法应该有所不同。

    首先,在您的主要休息 API 中,您必须发送响应代码以释放客户端。

    然后,在 API 方法中,您必须异步调用另一个方法,该方法调用 api2 并执行所需的操作。

    这是一个简单的例子。

    @Autowired
    API2Caller api2Caller;
    
    @RequestMapping(
            consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE},
            path = "api/api1",
            method = RequestMethod.POST,
            produces = MediaType.ALL_VALUE
    )
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void api1CallBack(@RequestBody String requestBody, HttpServletRequest request) throws IOException, GeneralSecurityException, URISyntaxException {
        api2Caller.callApi2(requestBody);
    }
    

    APICaller 应该如下所示

    @Component
    public class API2Caller {
    
        @Async
        public SomeResultPojo callApi2() {
            // use RestTemplate to call the api2 
            return restTemplate.postForObject("http://otherAPIEnv/api2", request, SomeResultPojo.class);
        }
    }
    

    但您可以选择最舒适的方式来执行异步操作。

    【讨论】:

    • 是的,看起来是个不错的方法,但是SpringBoot中有没有专门针对这种情况提供更好的方法呢?
    • 如果有人调用了 api1,api1 没有响应,而是向 api2 发送响应,违反了请求/响应的基本原则。每个请求都必须有响应,其次您不能在没有请求的情况下发送响应(api2 的情况)。在 http 协议中。我在我的许多微服务 api 中都有类似的情况,我们也做了同样的事情,但正如我在回答中所说,调用 api2 的方法可能会有所不同,具体取决于您的要求。
    【解决方案2】:

    看起来像是redirect 的工作。

    String redirectMe() {
        return "redirect:http://otherAPIEnv/api2"
    }
    

    至于卷曲。您有该方法的POST 映射,因此请务必尝试使用curl -X POST... 或将其更改为GET

    【讨论】:

    • 所以你的意思是我应该使用 URI callbackURL = new URI("redirect: http://otherAPIEnv/api2");而不是 URI callbackURL = new URI("http://otherAPIEnv/api2");
    【解决方案3】:

    这是做此类事情的更模块化和更通用的方式:

    public @ResponseBody ClientResponse updateDocStatus(MyRequest myRequest) {
        ClientResponse clientResponse = new ClientResponse(CTConstants.FAILURE);
        try {
            HttpHeaders headers = prepareHeaders();
            ClientRequest request = prepareRequestData(myRequest);
            logger.info("cpa request is " + new Gson().toJson(request));
            HttpEntity<ClientRequest> entity = new HttpEntity<ClientRequest>(request, headers);
            String uri = cpaBaseUrl + updateDocUrl ;    
            ClientResponse serviceResponse = Utilities.sendHTTPRequest(uri, entity);
            clientResponse = serviceResponse;
            if (serviceResponse != null) {
                if (CTConstants.SUCCESS.equalsIgnoreCase(serviceResponse.getStatus())) {
                    clientResponse.setStatus(CTConstants.SUCCESS);
                    clientResponse.setMessage(" update success.");
                }
            }
        } catch (Exception e) {
            logger.error("exception occurred ", e);
            clientResponse.setStatus(CTConstants.ERROR);
            clientResponse.setMessage(e.getMessage());
        }
        return clientResponse;
    }
    
    
    
        public static ClientResponse sendHTTPRequest(String uri, HttpEntity<ClientRequest> entity) {
    
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.setRequestFactory(new SimpleClientHttpRequestFactory());
            SimpleClientHttpRequestFactory rf = (SimpleClientHttpRequestFactory) restTemplate.getRequestFactory();
            rf.setReadTimeout(CTConstants.SERVICE_TIMEOUT);
            rf.setConnectTimeout(CTConstants.SERVICE_TIMEOUT);
    
            ParameterizedTypeReference<ClientResponse> ptr = new ParameterizedTypeReference<ClientResponse>() {
            };
            ResponseEntity<ClientResponse> postForObject = restTemplate.exchange(uri, HttpMethod.POST, entity, ptr);
            return postForObject.getBody();
    
        }
    

    【讨论】:

      【解决方案4】:

      你需要使用redirect并修改你的方法的返回类型

      public String api1CallBack(@RequestBody String requestBody, HttpServletRequest request) throws IOException {
             return "redirect:http://otherAPIEnv/api2";
      }
      

      【讨论】:

      • 其实api2 url是一个post url,我们要在上面发布一些数据(响应变量中json的值)
      猜你喜欢
      • 2018-11-30
      • 1970-01-01
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 2017-04-21
      • 2021-03-21
      • 1970-01-01
      • 2017-09-06
      相关资源
      最近更新 更多