废话不说,让大家等了这么久,先看看截图 :
编译失败图:
编译成功,执行图:
编译完成,执行时出现异常图:
呵呵,这里当然只能执行一些简单的java编程文件,如果要做更强大的功能还需要大家的努力,下面就揭开内幕:
1.文件保存
package com.servlets;
import java.io.File;
import java.io.FileWriter;
public class FileTool {
public static void saveStringToFile(final String content, final String fileName) throws Exception {
final File file = new File(fileName);
if(file.isDirectory()){
throw new Exception("dir is not allowed!");
}
if(file.exists()){
file.delete();
file.createNewFile();
}
FileWriter fileWriter=new FileWriter(file);
fileWriter.write(content);
fileWriter.flush();
fileWriter.close();
}
public static void makeDir(String baseDir) {
File file = new File(baseDir);
file.mkdirs();
}
}
2.Servlet
package com.servlets;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import com.dynamic.DynamicCompile;
/**
* Servlet implementation class JavaProcess
*/
@WebServlet("/JavaProcess.sock")
public class JavaProcess extends HttpServlet {
private static final long serialVersionUID = 1L;
private final static String ABSLUTE_PATH = "E:/Compile";
/**
* @see HttpServlet#HttpServlet()
*/
public JavaProcess() {
super();
}
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
System.out.println(action);
if ("compile".equals(action)) {
compileFile(request, response);
}
else if ("run".equals(action)) {
run(request, response);
}
else {
}
}
private void run(HttpServletRequest request, HttpServletResponse response) {
String className = request.getParameter("name");
className = className.replace('.', '/');
final String baseDir = ABSLUTE_PATH + "/" + request.getSession().getId() + "/";
ByteArrayOutputStream out=new ByteArrayOutputStream();
DynamicCompile.run(className,baseDir, out);
String result = new String(out.toByteArray());
Result result2=new Result(true, result);
JSONObject ob = JSONObject.fromObject(result2);
ServletOutputStream outputStream;
try {
outputStream = response.getOutputStream();
PrintWriter o = new PrintWriter(outputStream);
o.print(ob);
o.flush();
o.close();
}
catch (IOException e) {
}
}
private void compileFile(HttpServletRequest request, HttpServletResponse response) {
String className = request.getParameter("name");
String content = request.getParameter("file");
className=className.substring(className.lastIndexOf('.')+1);
final String baseDir = ABSLUTE_PATH + "/" + request.getSession().getId() + "/";
final String dir = baseDir + className.trim() + ".java";
try {
createDir(baseDir);
savefileToDir(dir, content);
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(out);
compileFile(dir, baseDir, writer);
String result = new String(out.toByteArray());
JSONObject ob;
Result result2;
if (result.isEmpty()) {
result2 = new Result(true, result);
}
else {
result2 = new Result(false, result);
}
ob = JSONObject.fromObject(result2);
ServletOutputStream outputStream = response.getOutputStream();
PrintWriter o = new PrintWriter(outputStream);
o.print(ob);
o.flush();
o.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private void createDir(String baseDir) {
FileTool.makeDir(baseDir);
}
private void compileFile(String dir, String baseDir, PrintWriter writer) {
DynamicCompile.compile(dir, baseDir, writer);
}
private void savefileToDir(String dir, String content) throws Exception {
FileTool.saveStringToFile(content, dir);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
3.执行编译
package com.dynamic;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import com.sun.tools.javac.Main;
public class DynamicCompile {
public static void compile(String dir, String baseDir,PrintWriter writer){
String[] agrs=new String[]{"-d",baseDir,dir};
Main.compile(agrs,writer);
}
public static boolean run(String className,final String baseDir, ByteArrayOutputStream out){
PrintStream out1=new PrintStream(out);
PrintStream err = System.err;
PrintStream out2 = System.out;
System.setErr(out1);
System.setOut(out1);
XClassLoader load=null;
load=new XClassLoader(baseDir);
try {
Class<?> loadClass = load.loadClass(className);
final Method method = loadClass.getMethod("main", new Class[] { String[].class });
method.invoke(null,new Object[]{new String[]{"21","df","dd"}});
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
System.setErr(err);
System.setOut(out2);
return false;
}
}
4.类加载
package com.dynamic;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class XClassLoader extends ClassLoader {
private final String classPath;
public XClassLoader(String classPath) {
super();
this.classPath = classPath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
FileInputStream fs;
try {
final String path = classPath+ name +".class";
fs = new FileInputStream(path);
int s=fs.available();
byte[] bs=new byte[ s];
fs.read(bs, 0, s);
final String className = name.replace('/','.');
return this.defineClass(className, bs, 0, s);
}
catch (FileNotFoundException e) {
throw new ClassNotFoundException("Not Found");
}
catch (IOException e) {
throw new ClassNotFoundException("Not Found");
}
}
}
5.返回数据对象类
package com.servlets;
public class Result {
private boolean success;
private String msg;
public Result(boolean success, String msg) {
super();
this.success = success;
this.msg = msg;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
6.前台界面
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="./extjs3/resources/css/ext-all.css" /> <script type="text/javascript" src="./extjs3/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="./extjs3/ext-all.js"></script> <style type="text/css"> html,body { font: normal 12px verdana; margin: 0; padding: 0; border: 0 none; overflow: hidden; height: 100%; } </style> <title>Java Compile</title> <script type="text/javascript"> Ext.onReady(function() { Ext.BLANK_IMAGE_URL = './extjs3/resources/images/default/s.gif'; var text = new Ext.form.TextArea({ region : 'center' }); var textName = new Ext.form.TextField({ fieldLabel : 'Class Name', allowBlank:false, width : '98%' }); var namePanel = new Ext.Panel({ region : 'north', height : '30px', items : [ { xtype : 'form', layout : 'form', labelWidth :70, layoutConfig : { labelSeparator : ':' }, labelAlign : 'left', frame : false, padding : '8px', items : [ textName ] } ] }); var compileBtn = new Ext.Button({ text : 'Compile' }); var runBtn = new Ext.Button({ text : 'Run' }); var panel_text = new Ext.Panel({ region : 'center', title : 'Java Compile', layout : 'border', items : [ namePanel, text ], buttons : [ compileBtn, runBtn ] }); var console_text = new Ext.form.TextArea({ width : '100%', readOnly : true, height : 200 }); var panel_console = new Ext.Panel({ region : 'south', title : 'Console', collapsible : true, height : 200, items : [ console_text ] }); var viewport = new Ext.Viewport({ layout : 'border', items : [ panel_console, panel_text ] }); var comileSuccess = function(response,ops) { var rs=Ext.util.JSON.decode(response.responseText); console_text.setValue(rs.msg); } var faild = function(e) { } var compile = function(e) { if (e == 'ok') { var javaCode = text.getValue(); var clsName = textName.getValue(); Ext.Ajax.request({ url : 'JavaProcess.sock', method :'GET', success : comileSuccess, failure : faild, params : { action:'compile', file : javaCode, name : clsName } }); } } compileBtn.on('click', function() { Ext.Msg.show({ title : 'Notice', msg : 'Are you sure to compile the code?', buttons : Ext.Msg.OKCANCEL, fn : compile, icon : Ext.MessageBox.QUESTION }); }); runBtn.on('click',function(){ var clsName = textName.getValue(); Ext.Ajax.request({ url : 'JavaProcess.sock', method :'GET', success : comileSuccess, failure : faild, params : { action:'run', name : clsName } }); }); }); </script> </head> </body> </html>
小结:在此例子中使用了java反射技术,java动态编译,加载类技术和Jave EE技术,达到了在网页里面编写简单java程序的功能,抛砖引玉,希望大家看了之后能够想到更多,实现更强大的功能。譬如说把编译后的class存在数据库里面,实现一些匪夷所思的功能:)