У меня есть один API загрузки Spring, при вызове которого s sh отправляется на сервер для выполнения сценария оболочки. Выходные данные сценария оболочки должны быть записаны и отображены в пользовательском интерфейсе реагирования js в потоковом режиме. И в конце предоставьте возможность скачать вывод сценария оболочки.
API написан с использованием Spring Boot, а пользовательский интерфейс реагирует. API весенней загрузки использует библиотеку JSCH для S SH на удаленном хосте и запускает выполнение сценария оболочки.
В настоящее время я могу выполнить сценарий, а также захватить и вернуть выходные данные как StreamingResponseBody в качестве потока , Ниже приведен весенний загрузочный код 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);
}
Из интерфейса реакции я вызываю конечную точку, используя fetch
. Нужна помощь, чтобы отобразить содержимое steam в пользовательском интерфейсе, а также предоставить возможность загрузки в файл в качестве реакции. Видел Загрузка данных ответа в виде потока с Ax ios в приложении React , которое говорит, что его невозможно загрузить. Любые предложения, пожалуйста.