您好我正在构建一个带有反应前端的REST应用程序,我遇到了一个问题 在我执行REST中的所有方法之前,我得到了一种响应方式
这是REST
@POST
@Path("{userName}/{oysterName}/{backupFile}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response createOyster(@PathParam("userName") String userName, @PathParam("backupFile") String backupFile,
@PathParam("oysterName") String oysterName, String version) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
NexusResource resource = mapper.readValue(version, NexusResource.class);
restUtil.restoreDatabase(userName, backupFile);
restUtil.createOyster(userName, oysterName);
restUtil.installOyster(oysterName);
restUtil.getVersionFromNexus(resource,oysterName);
return Response.ok().build();
}
}
最后一个方法调用resUtil.getVersionFromNexus可能需要很长时间。所有方法都需要3分钟到20分钟才能完成。我想要的是,无论需要多长时间,我只想在完成所有工作并准备就绪时发送响应。我应该让最后一个方法返回一些东西或者什么是最佳实践,因为这是我第一次创建REST
public void getVersionFromNexus(NexusResource version, String oysterName){
Path unzipDirectory = util.getTempFolder("unzipped");
TomcatNexusLayout.downloadZip(version, util.getTempFolder(version.getText()), c -> {
List<Path> customerFiles = TomcatNexusLayout.restUnzip(c, unzipDirectory);
Files.delete(c);
deployOysterVersion(oysterName, (ArrayList<Path>) customerFiles);
});
}
private void deployOysterVersion(String oysterName, ArrayList<Path> esaFiles) {
TomcatResource tomcatResource =
new TomcatResource(oysterName, Paths.get(tomcatsPath).resolve(oysterName).toString());
List<Path> esFile = new ArrayList<>();
List<Path> warFiles= new ArrayList<>();
List<Path> sqlFiles = new ArrayList<>();
for (Path path: esaFiles){
if(path.toString().contains("ncc") && path.toString().endsWith(".esa")){
esFile.add(path.toAbsolutePath());
}
else if(path.toString().endsWith(".war")) {
warFiles.add(path.toAbsolutePath());
}
}
tomNexLay.restDeploy(esFile, tomcatResource,warFiles,sqlFiles);
startOyster(oysterName);
}
private void startOyster(String oysterName){
TomcatResource tomcatResource =
new TomcatResource(oysterName, Paths.get(tomcatsPath).resolve(oysterName).toString());
serCtrl.restStart(tomcatResource);
System.out.println("HEJ HEJ");
}
}
所以这是最后一次调用的方法序列需要一些时间才能完成。我真正需要的是,当它到达印刷品时,HEJ HEJ&#34;然后发送响应。需要时间的部分是这个
TomcatNexusLayout.downloadZip(version, util.getTempFolder(version.getText()), c -> {
List<Path> customerFiles = TomcatNexusLayout.restUnzip(c, unzipDirectory);
Files.delete(c);
deployOysterVersion(oysterName, (ArrayList<Path>) customerFiles);
});
这使得使用CompleteableFuture变得困难,就像我将方法变为CompleteableFuture一样,它返回它在完成需要时间的代码块之前完成。
答案 0 :(得分:1)
正如Lino在评论中提到的,我的问题的解决方案是CompleteableFuture,它确保在返回任何内容之前完成所有操作。
所以这是解决方案
public String getVersionFromNexus(NexusResource version, String oysterName, String customer) {
CompletableFuture<String> completableFuture = new CompletableFuture<>();
Path unzipDirectory = util.getTempFolder("unzipped");
TomcatNexusLayout.downloadZip(version, util.getTempFolder(version.getText()), c -> {
List<Path> customerFiles = TomcatNexusLayout.restUnzip(c, unzipDirectory);
Files.delete(c);
deployOysterVersion(oysterName, (ArrayList<Path>) customerFiles, customer);
completableFuture.complete(startOyster(oysterName));
});
try {
return completableFuture.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return "FAILED";
}
所以首先我初始化CompleteableFuture
CompletableFuture<String> completableFuture = new CompletableFuture<>();
然后确保完成最后一个方法
completableFuture.complete(startOyster(oysterName));
});
try {
return completableFuture.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
这里我首先确保completeableFuture.complete()基本上返回一个String并告诉我的completeableFuture,一旦我得到了字符串我就完成了
return completableFuture.get();
completeableFuture.get()被锁定,除非触发了completeableFuture.complete(),否则不会发生任何事情。一旦完成完成,.get()就会解锁,并且可以将startOyster()中的String返回给调用它的方法,这样我的休息调用现在只有在有了该字符串时才会响应