我正在使用 Primefaces 的终端组件和 JSch 来 ssh 到远程桌面。使用 exec channel ,执行需要花费太多时间,因为 session 和 channel 都会在每个命令处关闭,而我无法避免这一点。所以我将 channel 更改为 shell,现在我尝试“重定向”标准输入/输出流。我的代码如下:
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@ManagedBean
@SessionScoped
public class TerminalController implements Serializable{
public TerminalController(){
jsch=new JSch();
InputStream in=null;
PrintStream out=System.out;
try{
session=jsch.getSession(user, ip, port);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(passwd);
session.connect();
channel=session.openChannel("shell");
channel.setInputStream(in);
channel.setOutputStream(out);
channel.connect();
}catch(Exception ee){
System.out.println(ee);
} }
public String handleCommand(String command, String[] params) {
command=command+StringUtils.join(params," ");
in=IOUtils.toInputStream(command);
String result=out.toString();
out.flush();
return result;}
我知道这很困惑,我还是java初学者。 我想到的另一个问题是,在从 iostream 到 string 的转换中我可能会失去回车按钮功能!我正在等待您的建议、解决方案和建议。
最佳答案
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.apache.commons.lang.StringUtils;
import org.fusesource.jansi.AnsiConsole;
import org.fusesource.jansi.AnsiString;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
@ManagedBean
@SessionScoped
public class TerminalController {
BufferedReader fromChannel;
PrintWriter toChannel;
Channel channel;
Session session;
JSch jsch;
public TerminalController() {
jsch = new JSch();
try {
session = jsch.getSession("leoks", "localhost", 22);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword("xxx");
session.connect(Integer.MAX_VALUE); // 3 secs timeout
channel = session.openChannel("shell");
InputStream inStream = channel.getInputStream();
fromChannel = new BufferedReader(new InputStreamReader(inStream,
"UTF-8"));
OutputStream outStream = channel.getOutputStream();
toChannel = new PrintWriter(new OutputStreamWriter(outStream,
"UTF-8"));
channel.connect();
StringBuilder result = new StringBuilder();
boolean stop = false;
while (!stop) {
// prompt does not end with newline...
char c = (char) fromChannel.read();
result.append(c);
System.out.print(c);
if (result.toString().endsWith("$")) {
System.out.print("<<<");
stop = true;
}
}
} catch (Exception ee) {
ee.printStackTrace();
}
}
public String handleCommand(String command, String[] params)
throws IOException {
command = command + " " + StringUtils.join(params, " ");
toChannel.println(command);
toChannel.flush();
StringBuilder result = new StringBuilder();
AnsiConsole.systemInstall();
while (true) {
char c = (char) fromChannel.read();
result.append(c);
if (c == '$') {
AnsiString as = new AnsiString(result.toString());
String s = as.getPlain().toString();
s = s.replaceAll("\n", "<br>");
AnsiConsole.systemUninstall();
return s;
}
}
}
}
Jansi 还有一个 HTML 渲染类,需要一些工作才能正确地将\n 替换为 BR,因为终端组件渲染 HTML 并默默地忽略任何充满控制代码的格式错误的字符串。您可能还想用固定宽度字体替换终端 CSS 定义,例如使用诸如
.ui-widget
{
font-family: "Courier New", Courier, monospace;
font-size: 0.8em;
}
和
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Terminal POC</title>
</h:head>
<h:body>
<h:outputStylesheet library="css" name="styles.css" />
<h:form>
<p:terminal
commandHandler="#{terminalController.handleCommand}"
height="300px"
welcomeMessage="Welcome..."
prompt=">" />
</h:form>
</h:body>
</html>
关于java - 将 JSch 的标准 iostream 重定向到 primefaces 的终端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12247470/