有些場景下需要在java中執行Bat指令或者Shell指令,如使用wkhtmltopdf生成pdf報表等,這時可以借助apache的commons-exec,指定ExecuteWatchdog 可以完整控制整個執行聲明周期,不會産生失控程序。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>1.3</version>
</dependency>
/**
* 執行不需要傳回結果的指令
* @throws Exception
*/
public void execCmdWithoutResult() throws Exception{
//開啟windows telnet: net start telnet
//注意:第一個空格之後的所有參數都為參數
CommandLine cmdLine = new CommandLine("net");
cmdLine.addArgument("start");
cmdLine.addArgument("telnet");
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
//設定60秒逾時,執行超過60秒後會直接終止
ExecuteWatchdog watchdog = new ExecuteWatchdog(60 * 1000);
executor.setWatchdog(watchdog);
DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
executor.execute(cmdLine, handler);
//指令執行傳回前一直阻塞
handler.waitFor();
}
/**
* 帶傳回結果的指令執行
* @return
*/
private String execCmdWithResult() {
try {
String command = "ping 192.168.1.10";
//接收正常結果流
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//接收異常結果流
ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
CommandLine commandline = CommandLine.parse(command);
DefaultExecutor exec = new DefaultExecutor();
exec.setExitValues(null);
//設定一分鐘逾時
ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);
exec.setWatchdog(watchdog);
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream,errorStream);
exec.setStreamHandler(streamHandler);
exec.execute(commandline);
//不同作業系統注意編碼,否則結果亂碼
String out = outputStream.toString("GBK");
String error = errorStream.toString("GBK");
return out+error;
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
}