有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在使用CompletableFuture时生成流式响应主体

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

enter image description here

类级hashmap

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进行的第三方API调用完成。doPOST一写完对doGET请求的响应,doGET就可以简单地返回它

doPOST

public void  doPOST(Request jettyReq, HttpServletRequest request, 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);
}

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


共 (0) 个答案