曾经工作的servlet,现在它神奇地没有

时间:2014-04-27 22:13:51

标签: java tomcat servlets

我很久没有触及过这个项目了,但是我发誓上次尝试它时它起作用了。现在,当然,它没有。

这是一个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的方法:

  1. 我从http://tomcat.apache.org/download-70.cgi
  2. 下载了de 64位Windows版本
  3. 我添加了两个环境变量: JAVA_HOME - &gt; JDK的路径(在我的例子中是C:\ Program Files \ Java \ jdk1.7.0_40) CATALINA_HOME - &gt; tomcat的路径(在我的例子中是C:\ apache-tomcat-7.0.53)
  4. 我编辑了环境路径并添加了%JAVA_HOME%\ jre \ bin。然后我从tomcat运行configtest.bat,它没有出错。
  5. 在tomcat的webapps文件夹中,我为我的项目创建了一个文件夹,其中我放置了包含表单代码的html(如上所示)。
  6. 在“webapps”里面的项目文件夹中,我创建了一个WEB-INF文件夹,其中我放置了web.xml和一个“classes”文件夹,其中包含一个名为“servlet”的子文件夹,其中包含2个已编译的类(.class文件)I如上所示。
  7. 我的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:中没有创建类文件(作为编译任务的结果)。

    我相信上次测试它们时这两个类正常工作,所以我更倾向于认为这是一个配置问题......但是在哪里? 谢谢!

1 个答案:

答案 0 :(得分:0)

没有。 5是你的问题。

您需要将您的类和web.xml放在html文件旁边的webapps目录中。

所以,看起来应该是这样的:

$tomcat/webapps/yourapp
           |
           +-----> your.html
           +-----> WEB-INF
                      |
                      +-----> web.xml
                      +-----> classes
                                 |
                                 +----> servlet
                                           |
                                           +-----> Compiler.class

然后它应该适合你。