java在使用CompletableFuture时生成流式响应主体
在CompletableFuture的帮助下,我设置了一个使用异步设置的以下机制。doGET在等待doPOST操作完成时被阻止
类级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) 个答案