In the latest release of TimeMachine scheduler project, I've added a Groovy scripting console to the web app and allow user to script the scheduler. This feature is actually very useful for any servlet application as well. Imagine that if you have a script/shell console for your web application that allow you to dynamically inspect any variables or data?
With the same idea, I've written a very basic JSP file script-console.jsp
that provides a great ad hoc tool. For simplicity sake, I put everything into single file. All you need is just add this one file into your java webapp root directory, and you'll have an instant scripting console shell! (Yes, I am aware having code in JSP is bad, but having everything in one page is convenient, specially if you plan to just use this as one time inspection.)
The JSP will automatically detect all the scripting engine available in your JVM (1.6+) and let you choose any one to use. In the text area you can enter any script codes. All the JSP implicit variables are available for you to use as well. JVM 1.6 or higher will have at least JavaScript engine available, so you can use it immediately.
Be aware that this is a huge security risk since the script console not only expose your application, it also expose your entire JVM! It must be use with care, and if possible, it needs to be added as protected resources in your web application.
<%@ page import="java.io.*,java.util.*,javax.script.*" %> | |
<% | |
// A script console jsp for Java | |
// Last modified: Zemian Deng <saltnlight5@gmail.com> 05/15/2014 | |
ScriptEngineManager factory = new ScriptEngineManager(); | |
// Get all the script engine names available by inspecting the classpath | |
List<String> scriptEngineNames = new ArrayList<String>(); | |
for (ScriptEngineFactory fac : factory.getEngineFactories()) { | |
String name = fac.getLanguageName(); | |
if (name.toLowerCase().equals("ecmascript")) { | |
name = "JavaScript"; | |
} | |
scriptEngineNames.add(name); | |
} | |
// Process Form | |
String scriptText = request.getParameter("scriptText"); | |
String scriptEngineName = request.getParameter("scriptEngineName"); | |
if (scriptEngineName == null) | |
scriptEngineName = "JavaScript"; | |
request.setAttribute("scriptText", scriptText); | |
request.setAttribute("scriptEngineName", scriptEngineName); | |
if (scriptText != null) { | |
ScriptEngine scriptEngine = factory.getEngineByName(scriptEngineName); | |
if (scriptEngine == null) | |
throw new RuntimeException("Failed to find ScriptEngine " + scriptEngineName); | |
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); | |
PrintWriter webOut = new PrintWriter(outStream); | |
// Script engine binding variables. | |
Bindings bindings = scriptEngine.createBindings(); | |
bindings.put("page", page); | |
bindings.put("config", config); | |
bindings.put("pageContext", pageContext); | |
bindings.put("request", request); | |
bindings.put("response", response); | |
bindings.put("out", out); | |
bindings.put("session", session); | |
bindings.put("application", application); | |
bindings.put("scriptEngine", scriptEngine); | |
bindings.put("webout", webOut); | |
// Run the scriptText | |
try { | |
Object scriptingOutput = scriptEngine.eval(scriptText, bindings); | |
if (scriptingOutput == null) | |
scriptingOutput = ""; | |
request.setAttribute("scriptingOutput", scriptingOutput); | |
} catch (Exception e) { | |
throw new RuntimeException("Failed execute scriptText.", e); | |
} finally { | |
webOut.close(); | |
String webOutResult = outStream.toString(); | |
if (webOutResult == null) | |
webOutResult = ""; | |
request.setAttribute("webOutResult", webOutResult); | |
} | |
} else { | |
request.setAttribute("scriptText", ""); | |
request.setAttribute("scriptingOutput", ""); | |
request.setAttribute("webOutResult", ""); | |
} | |
%> | |
<html> | |
<head> | |
<!-- | |
Use a nice and simple JavaScript editor from http://codemirror.net | |
--> | |
<script src="//raw.githubusercontent.com/marijnh/CodeMirror/4.1.0/lib/codemirror.js"></script> | |
<script src="//raw.githubusercontent.com/marijnh/CodeMirror/4.1.0/mode/javascript/javascript.js"></script> | |
<script src="//raw.githubusercontent.com/marijnh/CodeMirror/4.1.0/mode/groovy/groovy.js"></script> | |
<link rel="stylesheet" href="//raw.githubusercontent.com/marijnh/CodeMirror/4.1.0/lib/codemirror.css"> | |
</head> | |
<body> | |
<h4>Script Console for Java</h4> | |
<form method="post"> | |
<textarea id="code" name="scriptText" rows="20" cols="80"><%= request.getAttribute("scriptText") %></textarea> | |
<br/> | |
<select name="scriptEngineName"> | |
<% | |
for (String engineName : scriptEngineNames) { | |
if (scriptEngineName.equals(engineName)) | |
out.println("<option selected='true'>" + engineName + "</option>"); | |
else | |
out.println("<option>" + engineName + "</option>"); | |
} | |
%> | |
</select> | |
<input name="Run" type="submit" value="run"/> | |
<hr/> | |
<pre> | |
<%= request.getAttribute("scriptingOutput") %> | |
<%= request.getAttribute("webOutResult") %> | |
</pre> | |
</form> | |
<script> | |
var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | |
lineNumbers: true | |
}); | |
</script> | |
</body></html> |
No comments:
Post a Comment