web项目实现类文件上传、编译及加载

最近在做的课程网站需要实现将学生的源代码提交,并对学生间的程序进行比赛、排名。

1 网站页面源代码的提交

首先实现网站页面源代码的提交(文件夹下的多文件提交),拷贝至后台相应的文件夹下

前端代码(表单提交):

<div class="col-md-2 title">提交棋手</div>
<div class="col-md-4 data text">
   <input type="file" id="fileFolder" name="fileFolder" webkitdirectory mozdirectory >
</div>

后端代码:

for(MultipartFile f:files) {
     File file1;
     String name = "";
     try {
         if (f instanceof CommonsMultipartFile) {
             //转换成这个对象,然后我们需要通过里面的FileItem来获得相对路径
             CommonsMultipartFile f2 = (CommonsMultipartFile) f;
             name = f2.getFileItem().getName();
             file1 = new File(path + "/" + name);
             file1.mkdirs();
             file1.createNewFile();
             f.transferTo(file1);
          }
      } catch (Exception e) {
           e.printStackTrace();
      }
}

2 编译提交的java源代码

源代码放在相应位置后,就需要调用命令行对提交的代码进行编译,并将文件放到classes文件夹

public static void executeCmd(ArrayList<String> fileList, ArrayList<String> classList) {
        try {
            //把文件夹下所有java文件完整路径存到files数组中,不用考虑引用关系
            String classPath="E:\\program\\course_website\\jago\\target\\classes";
            //class文件存放路径

            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
            Iterable<? extends JavaFileObject> javaFileObjects =
            manager.getJavaFileObjectsFromStrings(fileList);
            //options就是指定编译输入目录,与我们命令行写javac -d C://是一样的
            List<String> options = new ArrayList<String>();
            options.add("-classpath");
            options.add(classPath);
            options.add("-d");
            options.add(classPath);
            JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, options, null, javaFileObjects);
            boolean compileFlag = task.call();
            manager.close();  
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

3 类加载

       将代码编译完成后就需要将class加载进jvm中,刚开始我写了一个自定义的classLoader,继承ClassLoader,但在web项目运行后出现了java.lang.ClassCastException的java类型转换异常,但类型确实是可以转换的,不应该出现这样的问题,百度后发现是因为类加载器的不同所以导致了类型转换失败。tomcat 拥有不同的自定义类加载器,通过getClassLoader()方法发现强转的类加载器是ParallelWebappClassLoader,那么我们刚刚编译后的class文件也通过此加载器加载就不会出现类型强转错误了。

public class MyClassLoader extends URLClassLoader {
    //该路径是classpath路径
    public static File file = new File("E:\\program\\course_website\\jago\\target\\classes");

    //MyClassLoader从上面的classpath路径加载类
    public MyClassLoader() throws Exception {
        super(new URL[] {file.toURL()}, null, null);
    }
    public MyClassLoader(ClassLoader parent) throws Exception {
        super(new URL[] {file.toURL()}, parent);
    }
}

这里需要指出 JVM中确定一个类型的坐标是通过类加载器和全类名做到的 。

在JVM中,如何确定一个类型实例?答:全类名吗?不是,是类加载器加上全类名。在JVM中,类型被定义在一个叫SystemDictionary 的数据结构中,该数据结构接受类加载器和全类名作为参数,返回类型实例。

     SystemDictionary 如图所示:

      类型加载时,需要传入类加载器和需要加载的全类名,如果在 SystemDictionary 中能够命中一条记录,则返回class 列上对应的类型实例引用,如果无法命中记录,则会调用loader.loadClass(name);进行类型加载。

      想要了解ClassLoader的内容可以看一下这篇博客:https://blog.csdn.net/liangxw1/article/details/51353572/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值