如何在Spring Boot中处理来自外部API的即时响应和单个控制器中的回调响应?

How to handle an instant response from an external API and a callback response in a single controller in Spring Boot?

提问人:Md. Sakhawath Hossain 提问时间:6/14/2023 更新时间:6/15/2023 访问量:192

问:

我有一个控制器,我试图从中尝试使用标头和请求正文触发 POST 外部 api 调用。

外部 API URL 示例:

http://sample:7070/test

示例标头:

Content-type: application/json
Authorization : someEncryptedData
CallBack: http://mycallback:8080/sendCallback

样品主体:

{
"A": {
    "B": 100,
    "C": "TEST",
},
"ReceiverParty": {
    "A": 41,
    "D": "123214526"
},
"Reference": [
    {
        "Key": "A",
        "Value": "B"
    }
]
}

现在,此 api 将在触发时发送即时响应。此外,它还将向标头中提供的回调 url(POST) 发送另一个响应。

我想在一个控制器中获得两个响应。获得它的方法是什么?请参考任何主题博客以更好地理解。

我的示例代码:

@RestController
@RequestMapping("/main")
public class MainController {

@Autowired
private RestTemplate restTemplate;

@PostMapping("/call-api")
public ResponseEntity<String> callApi() {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);

    // Create the request body
    SamplePlayload requestPayload = createRequestPayload();

    HttpEntity<SamplePlayload> requestEntity = new HttpEntity<>(requestPayload, headers);

    ResponseEntity<String> responseEntity = restTemplate.exchange(
            "http://sample:7070/test",
            HttpMethod.POST,
            requestEntity,
            String.class
    );

    String initialResponse = responseEntity.getBody();
    System.out.println("Received initial response: " + initialResponse);

    String callbackUrl = "http://mycallback:8080/sendCallback"; 

    CompletableFuture.supplyAsync(() -> restTemplate.postForObject(callbackUrl, 
    requestPayload, String.class))
            .thenAccept(callbackResponse -> {
                System.out.println("Received callback response: " + 
    callbackResponse);
                // Perform further actions as needed
            });

    return responseEntity;
}

private SamplePlayload createRequestPayload() {
    //make the request body
}

回调控制器:

@RestController
@RequestMapping("/sendCallback")
public class CallbackController {

@PostMapping
public void handleCallback(@RequestBody CallbackResponse callbackResponse) {
    // Process the callback response
    System.out.println("Received callback response: " + callbackResponse);
    // Perform further actions as needed
    }
}

即时响应示例:

{
"Header": {
//some elements
},
"Body": {
//Some elements
}
}

回调响应示例:

{
"Header": {
//some elements
},
"Body": {
//Some elements
}
}
java spring-boot rest callback completable-future

评论

0赞 lane.maxwell 6/15/2023
如果希望将调用的响应返回到调用它的方法,则不要异步执行此操作,或者在获得响应之前阻止。除非您想从控制器返回 CompletableFuture,否则您没有其他选择。restTemplate.postForObject

答:

0赞 abi rajasekar 6/15/2023 #1

您可以将其作为服务,并向另一个微服务提供 resttemplate 调用,例如并获取响应

评论

0赞 Md. Sakhawath Hossain 6/15/2023
你能举个例子吗?或者任何博客或文章都提到这个?谢谢
0赞 Community 6/17/2023
您的答案可以通过额外的支持信息得到改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。
0赞 Rashin 6/15/2023 #2

不能只修改回调url路径吗?

将方法移动到标头并对齐修改后的路径。handleCallbackMainController

@RestController
@RequestMapping("/main")
public class MainController {
 
   ...
    
    @PostMapping("/sendCallback")
    public void handleCallback(@RequestBody CallbackResponse callbackResponse) {
        // Process the callback response
        System.out.println("Received callback response: " + callbackResponse);
        // Perform further actions as needed
    }
}

新标题:

Content-type: application/json
Authorization : someEncryptedData
CallBack: http://mycallback:8080/main/sendCallback

评论

0赞 Md. Sakhawath Hossain 6/15/2023
从回调中获取数据后,我有类似的两个 api 调用操作。从前端,它们将直接命中 /call-api 端点。我将从此方法返回什么?我是否需要对句柄回调方法执行剩余的 api 调用和操作?谢谢