废话不说,让大家等了这么久,先看看截图 :
呵呵,这里当然只能执行一些简单的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存在数据库里面,实现一些匪夷所思的功能:)