使用 CompletableFuture 时制作流式响应主体

我已经设置了以下机制,该机制在 CompletableFuture 的帮助下使用异步设置。 doGET 在等待 doPOST 操作完成时被阻塞。

使用 CompletableFuture 时制作流式响应主体

类级哈希映射

private final Map<String,HttpRequestResponse> requests = new HashMap<>();

HttpRequestResponse 包装类

public class HttpRequestResponse {
private final HttpServletRequest request;
private final CompletableFuture<HttpServletResponse> responseSupplier;

public HttpRequestResponse(HttpServletRequest request,CompletableFuture<HttpServletResponse> responseSupplier) {
    this.request = request;
    this.responseSupplier = responseSupplier;
}

public void supplyResponse(HttpServletResponse response) {
    this.responseSupplier.complete(response); //<-- this will release the .get()
}

//getters
public CompletableFuture<HttpServletResponse> getSupplier() {
    return responseSupplier;
}

}

doGET

public void doGET(Request jettyReq,HttpServletRequest request,HttpServletResponse response) {

    // 1. Read request ID for the request
    String xRequestId = request.getHeader("X-Request-ID");

    // 2. Upon receiving the request,create the instance of wrapper
    //    and put it into the map,then wait for the result
    HttpRequestResponse responseSupplier = new HttpRequestResponse(request,new CompletableFuture<>());
    requests.put(xRequestId,responseSupplier); //add supplier to the map (so that doPOST can retrieve it later)

    // perform other processing & perform request to 3rd party server

    try {
        response = responseSupplier.getSupplier().get(); //<- wait until someone completes the future
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
}

所以这里的 .get() 方法是一个阻塞调用,它正在等待对 doPOST 的 3rd 方 API 调用完全处理。一旦 doPOST 完成对 doGET 请求的响应写入,doGET 就可以简单地返回它。

doPOST

public void  doPOST(Request jettyReq,HttpServletResponse response)  {
    // upon receiving the response from the 3rd party API on writeGetObjectResponse,// I will need to get the future by its id,remove it from the map and complete it:
    String xRequestId = request.getHeader("X-Request-ID");
    HttpRequestResponse responseSupplier = requests.remove(xRequestId); // removes the supplier from the map and returns it to you

    // Build a complete response
    HttpServletResponse getObjectResponse = response;

    // set response headers
    getObjectResponse.setContentType("application/json");
    getObjectResponse.setCharacterEncoding("UTF-8");

    // write payload into response body
    String payloadRequest = null;
    try {
        payloadRequest = getBody(request);
    } catch (IOException exception) {
        exception.printStackTrace();
    }
    PrintWriter out = null;
    try {
        out = getObjectResponse.getWriter();
    } catch (IOException exception) {
        exception.printStackTrace();
    }
    out.print(payloadRequest);
    out.flush();

    // complete the future so that getObject() can access it.
    responseSupplier.getSupplier().complete(getObjectResponse);

    response.setStatus(HttpServletResponse.SC_OK);
}

我尝试构建的响应对象可能有大量数据要返回。我正在寻找一种机制,我可以执行数据或响应正文的流式返回。我该如何解决这个问题?

jasonzhyh 回答:使用 CompletableFuture 时制作流式响应主体

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/28464.html

大家都在问