手记

用Java实现一个小的OJ

在学习算法的时候,经常到leetcode上刷题,对OJ(online judge)有点兴趣,于是就在猜测的基础上用Java写了一个小的OJ,虽然程序非常简单,只能做简单加法运算,但作为一个小练习也是很有意思的。

我并没有看过OJ的具体实现方法,估计实现方法千差万别,因此猜测之下,我假定具体的流程为:

前端输送字符串--->Rest Service传送到后端--->后端进行编译处理--->发送前端

具体代码如下:
前端部分:

前端文件结构

simpleojUI
    --js
        --jquery-3.1.0.min.js
        --service.js
        --simple.js
    --node_modules
        --connect
        --serve-static
    --index.html
    --package.json

前端项目构建的时候,首先需要在simpleojUI的文件夹目录下运行npm指令npm init从而得到package.json,接着依次运行npm install connect --savenpm install serve-static --save

这样就快速搭建起来了一个静态的服务器,然后到js目录下创建server.js,其具体内容如下

var connect = require('connect'),
serveStatic = require('serve-static');

var app = connect();

app.use(serveStatic("../../simpleojUI"));
app.listen(5000);

这样就将文件夹监听在5000端口,任何发送5000端口的request都会被该文件夹中的内容处理

Html部分,也就是index.html(没有美工,很丑,大家轻喷):

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Simple OJ project</title>
  <script src="./js/jquery-3.1.0.min.js"></script>
  <script src="./js/simple.js"></script>
  <style type="text/css">
    body{
      margin:0;
      padding: 0;
    }
    h1{
      text-align: center;
    }

    .textarea{
      display: block;
      margin: auto;
      font-size: 20px;
      font-weight: bold;
    }
    button{
      display: block;
      margin: auto;
      margin-top: 20px;
      font-size: 20px;
    }
    .result{
      text-align: center;
      margin-top: 30px;
      font-size: 30px;
    }

  </style>
  <!--[if lt IE 9]>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
  <![endif]-->
</head>

<body>
    <h1>Simple Project</h1>
    <div id="container">
      <textarea class="textarea" name="code" rows="20" cols="50"></textarea>
    </div>
    <button id="submit" type="button" name="button">submit</button>
    <div class="result">
      <span>Result is: </span>&nbsp;<span id="finalResult"></span>
    </div>
</body>
</html>

jQuery 简单编写的simple.js用来实现简单的前端逻辑:

;$(function() {

    var sendCode = function(){
      var code = $(".textarea").val();
      console.log(code);
      var url = "http://localhost:8080/simpleoj";
      var success = function(data){
        $("#finalResult").html(data);
      }

      $.ajax({
        type: "POST",
        url: url,
        contentType: "plain/text; charset=utf-8",
        dataType: "text",
        data: code,
        success: success
      });
    }

    $("#submit").on("click",()=>{
      sendCode();
    });
});

后端使用Spring boot去构建代码,只需要构建一个最基本的架构即可,具体的构建过程可以参考Spring的官网或者相关书籍资料。 后端代码(WebController):

import org.springframework.web.bind.annotation.*;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

@RestController
public class WebController{

    @CrossOrigin(origins = "*")
    @RequestMapping(value = "/simpleoj",method = RequestMethod.POST, headers = "Accept=text/plain")
    public String greetings(@RequestBody String bodyContent) throws Exception{

        String source =  bodyContent;
        System.out.println(source);
        File folder = new File("./src/main/java/com/imooc/controller");
        File sourceFile = new File(folder, "Solution.java");
        try {
            Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        if (compiler == null) {
            System.out.println("JDK required (running inside of JRE)");
        } else {
            System.out.println("you got it!");
        }

        int compilationResult = compiler.run(null, null, null, sourceFile.getPath());
        if (compilationResult == 0) {
            System.out.println("Compilation is successful");
        } else {
            System.out.println("Compilation Failed");
        }
        try {
            URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {folder.toURI().toURL() });
            Class<?> cls = Class.forName("Solution", true, classLoader);
            Object instance = cls.newInstance();
            Method method = cls.getDeclaredMethod("add", null);
            System.out.println(method.invoke(instance, null));
            Integer res = (Integer) method.invoke(instance, null);

            //delete temp file
            File classfile = new File(folder, "Solution.class");
            sourceFile.delete();
            classfile.delete();
            return res.toString();
        } catch (Exception e) {
            e.printStackTrace();
            sourceFile.delete();
            return "something wrong";
        }
    }
}

连接后的效果图如下 :

第一次发的手记,不好的地方还请见谅。

PS: 慕课网的这个手记Editor还是太不完善了,编辑的时候保存只能显示一半的内容,保存之后真的就只剩下一半的内容了,剩下的内容只有再次补上了

3人推荐
随时随地看视频
慕课网APP

热门评论

没有写怎么限制内存和cpu吗?

查看全部评论