繁体   English   中英

完成所有方法后,REST将返回响应

[英]REST send back response once all methods are done

您好,我正在构建一个具有React前端的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”时发送响应。 需要时间的部分是这个

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一样,它会返回它的完成工作,而这需要花费时间。

正如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,一旦我得到String,我就完成了

return completableFuture.get();

completeableFuture.get()处于锁定状态,除非已触发completeableFuture.complete(),否则不会进行任何操作。 一旦完成,.get()就会被解锁,并且可以将字符串从startOyster()返回给调用它的方法,因此我的rest调用现在仅在拥有该字符串的情况下响应

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM