我很久没有触及过这个项目了,但是我发誓上次尝试它时它起作用了。现在,当然,它没有。
这是一个java servlet,它接受一些java代码,编译它并返回一些带有结果的html(“编译成功”或“在xxx行编译错误”)。它只用2个类构建:“编译器”从HttpServlet扩展,“JavaObjectFromString”从SimpleJavaFileObject扩展。
类JavaObjectFromString如下所示:
package servlet;
import java.io.IOException;
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
public class JavaObjectFromString extends SimpleJavaFileObject{
private String contents;
private String name;
public JavaObjectDesdeString(String className, String cont){
super(URI.create(className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
contents=cont);
name=className);
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return contents;
}
}
Class Compiler看起来像这样:
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
@WebServlet("/compiler")
public class Compiler extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
StringBuffer sb = new StringBuffer();
String code = request.getParameter("usercodefromhtml").toString();
String results = this.compileCode(code);
sb.append("<html><body bgcolor=pink text=black>");
sb.append("<h1 align=center>" + results + "</h1>");
sb.append("<body></html>");
out.println(sb);
}
private String compileCode(String codeToCompile){
String results = null;
/*Creating dynamic java source code file object*/
SimpleJavaFileObject fileObject = new JavaObjectFromString ("userclass", codeToCompile);
JavaFileObject javaFileObjects[] = new JavaFileObject[]{fileObject} ;
/*Instantiating the java compiler*/
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
/*Create a diagnostic controller, which holds the compilation problems*/
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
/*get a standard file manager from compiler, this file manager helps us to customize how a compiler reads and writes to files*/
StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(diagnostics, null, null);
/* Prepare a list of compilation units (java source code file objects) to input to compilation task*/
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(javaFileObjects);
/*Prepare any compilation options to be used during compilation
//In this example, we are asking the compiler to place the output files under bin folder.*/
String[] compileOptions = new String[]{"-d", "c:"} ;
Iterable<String> compilationOptions = Arrays.asList(compileOptions);
/*Create a compilation task from compiler by passing in the required input objects prepared above*/
CompilationTask compilerTask = compiler.getTask(null, stdFileManager, diagnostics, compilationOptions, null, compilationUnits) ;
/*Perform the compilation by calling the call method on compilerTask object.*/
boolean status = compilerTask.call();
/*On compilation failure, we can use the diagnostic collector to read the error messages and log them in specific format.*/
if (!status){//If compilation error occurs
/*Iterate through each compilation problem and print it*/
for (@SuppressWarnings("rawtypes") Diagnostic diagnostic : diagnostics.getDiagnostics()){
results = "Error en la línea "+diagnostic.getLineNumber();
}
}
else
results = "Compilación exitosa";
/*Finally close the fileManager instance to flush out anything that is there in the buffer.*/
try {
stdFileManager.close() ;//Close the file manager
} catch (IOException e) {
e.printStackTrace();
}
return results;
}
}
我将这两个文件编译成旧版Eclipse中的.class文件(从那以后我没有重新编译)。
我在html文件中也有这个表单,我想调用servlet并将“usercodefromhtml”参数和用户在该textarea中写入的代码一起传递给它:
<form action="compiler" method="post">
<textarea rows="18" cols="70" name="usercodefromhtml"></textarea>
<input type="submit">
</form>
(我也试过“/ compiler”和“Compiler”作为动作值,但没有运气)。
这是我安装和配置tomcat的方法:
我的web.xml如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>Compiler</servlet-name>
<servlet-class>servlet.Compiler</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Compiler</servlet-name>
<url-pattern>/Compiler</url-pattern>
</servlet-mapping>
</web-app>
然后,从cmd我从tomcat文件夹运行startup.bat。我在浏览器中打开了html文件,在textarea中输入了一些随机代码并按下了提交按钮。没有。 在c:中没有创建类文件(作为编译任务的结果)。
我相信上次测试它们时这两个类正常工作,所以我更倾向于认为这是一个配置问题......但是在哪里? 谢谢!
答案 0 :(得分:0)
没有。 5是你的问题。
您需要将您的类和web.xml放在html文件旁边的webapps目录中。
所以,看起来应该是这样的:
$tomcat/webapps/yourapp
|
+-----> your.html
+-----> WEB-INF
|
+-----> web.xml
+-----> classes
|
+----> servlet
|
+-----> Compiler.class
然后它应该适合你。