完成所有方法后,REST会发回响应

时间:2018-04-11 12:34:57

标签: java rest

您好我正在构建一个带有反应前端的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一样,它返回它在完成需要时间的代码块之前完成。

1 个答案:

答案 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返回给调用它的方法,这样我的休息调用现在只有在有了该字符串时才会响应