0

我正在通过我的 JSP 页面运行 Java 应用程序。是否可以将 Java 应用程序打印到 System.out 的所有内容重定向到我的页面?

编辑: 我有一个包pkg,其中包含一个主要功能。这个函数有很多 System.out.println 调用。例如

package pkg;
public class pkg {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
}

在我的index.jsp中,我调用:

<%
    pkg.pkg.main(new String[] {});
%>

我需要查看pkg.pkg.main在页面上打印的所有内容。例如

Hello
4

3 回答 3

2

一种天真的方法是使用适当包装的响应输出流调用System.setOut()。但是,一旦多个并发请求启动,这将不起作用,因为来自不同线程的输出之间没有区别。

您可以创建自己的输出流子类,该子类委托给另一个线程本地输出流,您将其设置为响应的输出流,然后再pkgmain()对每个请求调用您的方法。如果您pkgmain()产生额外的线程,那么这种方法可能不起作用(尽管在这种情况下您可以尝试使用InheritableThreadLocal)。

于 2012-05-26T12:33:15.090 回答
1

重构被调用类的代码,使其接受一个 Writer 作为参数,并打印到这个 Writer 而不是 System.out:

package pkg;
public class pkg {
    public static void main(String[] args) {
        main(new OutputStreamWriter(System.out), args);
    }

    public static void main(Writer writer, String[] args) {
        PrintWriter out = new PrintWriter(writer);
        out.println("Hello");
    }
}

并从您的 JSP(应该是一个 servlet)中调用第二个主要方法:

<%
    pkg.main(out, new String[] {});
%>
于 2012-05-26T12:40:51.750 回答
0

另一种方法,如果你不能编辑要执行Runtime#exec()的类的源代码,是使用命令以编程java方式执行类,就像你在命令提示符下执行它一样,然后捕获它的标准输出(和标准错误) !) 由Process.

Process process = Runtime.getRuntime().exec("java -cp /path/to/your/pkg pkg.pkg");
InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();
// Read and write it to response.getOutputStream() the usual way.

如果您以前从未真正使用Runtime#exec()过,我强烈建议您阅读这篇著名的 JavaWorld 文章(全部 4 页)来学习和理解它的注意事项。

最后但并非最不重要的一点是,请记住 Java/JSP 代码物理运行在运行 Web 服务器的机器(服务器端),而不是运行 Web 浏览器的机器(客户端),并且 Web 服务器的 Java 运行时安全管理器应该允许Runtime#exec()从 webapp 内部执行。如果您打算将此应用程序部署到您无法控制安全管理器的第 3 方主机,则Runtime#exec()调用很可能会被阻止并抛出SecurityException.

不用说,这一切都很臭。如果这些类涉及用户控制的代码,那么您可能会打开巨大的安全漏洞。

于 2012-05-28T16:32:29.127 回答