我已经设置了以下机制,该机制在 CompletableFuture 的帮助下使用异步设置。 doGET 在等待 doPOST 操作完成时被阻塞。
类级哈希映射
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);
}
我尝试构建的响应对象可能有大量数据要返回。我正在寻找一种机制,我可以执行数据或响应正文的流式返回。我该如何解决这个问题?