简体   繁体   中英

redirect System.out to page

I am running a Java application through my JSP page. is it possible to redirect everything that the Java app prints into System.out into my page?

Edit: I have a package pkg which contains a main function. this function has lots of System.out.println calls. eg

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

In my index.jsp I call:

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

I need to see everything the pkg.pkg.main prints on the page. eg

Hello

A naive approach would be to call System.setOut() with a suitably wrapped response output stream . However, this would not work once multiple concurrent requests kick in, as there would be no differentiation between the outputs from the different threads.

You could create your own output stream subclass that delegates to another thread-local output stream which you set to your response's output stream before invoking your pkgmain() method on each request. If your pkgmain() spawns additional threads then this approach might not work (though you could try using InheritableThreadLocal in this case).

Refactor the code of the called class so that it takes a Writer as argument, and print to this Writer rather than 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");
    }
}

and call this second main method from your JSP (which should be a servlet):

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

Another approach, if you can't edit the source code of the to be executed class, is to use Runtime#exec() to execute the class programmatically using the java command the usual way like as you would execute it in command prompt and then capture its stdout (and stderr!) by 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.

If you have never really used Runtime#exec() before, I strongly recommend to read this well known JavaWorld article (all the 4 pages) to learn and understand its caveats.

Last but not least, keep in mind that Java/JSP code runs physically in the machine where the webserver runs (the server side), not where the webbrowser runs (the client side) and also that the webserver's Java run time security manager should allow executing Runtime#exec() from inside a webapp. If you intend to deploy this app to a 3rd party host on which you don't have control over the security manager, chances are big that Runtime#exec() call will be blocked and throw SecurityException .

Needless to say, this is all pretty smelly. If those classes concerns user-controlled code, you're putting possibly huge security exploit holes open.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM