如何在React js中从Spring Boot显示或下载StreamingResponseBody响应

时间:2020-05-03 13:01:47

标签: reactjs spring-boot spring-data

我有一个Spring Boot API,当被调用时,它将SSH到服务器以执行Shell脚本。需要捕获shell脚本的输出,并以流方式将其显示在react js UI上。最后,提供下载外壳脚本输出的选项。

Api使用Spring Boot编写,并且UI处于反应状态。 spring boot API使用JSCH库将SSH SSH到远程主机并启动Shell脚本执行。

当前,我能够执行脚本,还可以捕获并以StreamingResponseBody的形式将输出作为流返回。 下面是spring boot code api。

@PostMapping(value = "/{scriptName}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<StreamingResponseBody> executeShellScript(@CurrentUser UserPrincipal currentUser, @PathVariable String scriptName,
        @Valid @RequestBody ExecutionRequest executionRequest,final HttpServletResponse response) throws JSchException, SftpException, IOException {
    return dashboardService.executeScript(currentUser,executionRequest, scriptName, response);
}

public ResponseEntity<StreamingResponseBody> executeScript(UserPrincipal currentUser,
        ExecutionRequest executionRequest, String srcFilePath, final HttpServletResponse response)
        throws JSchException, SftpException, IOException {

    //response.setContentType("application/zip");
    //response.setContentType(MediaType.parseMediaType("application/octet-stream"));
    //response.setHeader("Content-Disposition", "attachment;filename=sample.zip");


    JSch jSch = new JSch();
    Session session = jSch.getSession(executionRequest.getUserName(), executionRequest.getHostName(), 22);
    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);

    jSch.addIdentity(executionRequest.getPrivatekeyPath());
    session.connect();

    ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
    //InputStream in = channelExec.getInputStream();

    String firstCommand = "cat /home/" + executionRequest.getUserName() +"/"+srcFilePath+" | col -b > temp.sh";
    String secondCommand = "mv temp.sh  /home/"+ executionRequest.getUserName() +"/"+srcFilePath;
    String thirdCommand = "sh /home/"+ executionRequest.getUserName() +"/"+srcFilePath +" 2>&1";
    channelExec.setCommand(firstCommand);
    channelExec.setCommand(secondCommand);
    channelExec.setCommand(thirdCommand);

    /*channelExec.setCommand(
            " cat /home/ubuntu/sshtest/testfile.sh | col -b > temp.sh \n mv temp.sh  /home/ubuntu/sshtest/testfile.sh \n sh /home/ubuntu/sshtest/testfile.sh 2>&1");*/
    channelExec.connect();


    StreamingResponseBody stream = out -> {

        //final ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());

        final InputStream inputStream = channelExec.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        int index = 0;

        while ((line = reader.readLine()) != null) {
            System.out.println(++index + " : " + line);
            out.write(line.getBytes());
        }

        inputStream.close();

        //zipOut.close();
        int exitStatus = channelExec.getExitStatus();
        channelExec.disconnect();
        session.disconnect();
        if (exitStatus < 0) {
            System.out.println("Done, but exit status not set!");
        } else if (exitStatus > 0) {
            System.out.println("Done, but with error!" + exitStatus);
        } else {
            System.out.println("Done!");
        }

    };
    int exitStatus = channelExec.getExitStatus();
    //channelExec.disconnect();
    //session.disconnect();
    if (exitStatus < 0) {
        System.out.println("Done, but exit status not set!");
    } else if (exitStatus > 0) {
        System.out.println("Done, but with error!" + exitStatus);
    } else {
        System.out.println("Done!");
    }

    //channelExec.disconnect();
    //session.disconnect();
    logger.info("steaming response {} ", stream);
    //return new ResponseEntity(stream, HttpStatus.OK);
    return ResponseEntity.ok()
            .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION)
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=output.zip")
            .contentType(MediaType.parseMediaType("application/octet-stream"))
            .body(stream);


}

从react UI,我正在使用fetch调用端点。需要帮助以在UI中显示Steam的内容,还需要提供在React中作为文件下载的选项。看到Download Response Data as Stream w/ Axios in React App,表示无法下载。有任何建议。

0 个答案:

没有答案