java版本的在线OJ项目

在线oj项目

项目介绍

该项目基于java,servlet,JDBC,ajax技术实现的,该项目实现了登录和注册功能,给用户更好的体验,此外还新增管理员用户,其比普通用户多了几个功能:新增题目,删除题目,删除用户,添加用户,查看题目这些功能,这些功能能让用户体验更加完好,用户提交代码后会给用户提示代码通过情况,此外在运行用户代码前进行安全性检测,这特别适合将目前所有学的知识给运用一下,让自己更好熟练相关技术。

编译模块设计

创建Question类

package compile;

public class Question {
    
    
    private String code;

    public String getCode() {
    
    
        return code;
    }

    public void setCode(String code) {
    
    
        this.code = code;
    }
}

创建Answer类

package compile;
//返回前端以该类为标准

public class Answer {
    
    
    private int error;
    private String reason;
    private String stdout;
    private String stderr;

    public int getError() {
    
    
        return error;
    }

    public void setError(int error) {
    
    
        this.error = error;
    }

    public String getReason() {
    
    
        return reason;
    }

    public void setReason(String reason) {
    
    
        this.reason = reason;
    }

    public String getStdout() {
    
    
        return stdout;
    }

    public void setStdout(String stdout) {
    
    
        this.stdout = stdout;
    }

    public String getStderr() {
    
    
        return stderr;
    }

    public void setStderr(String stderr) {
    
    
        this.stderr = stderr;
    }

    @Override
    public String toString() {
    
    
        return "Answer{" +
                "error=" + error +
                ", reason='" + reason + '\'' +
                ", stdout='" + stdout + '\'' +
                ", stderr='" + stderr + '\'' +
                '}';
    }
}

创建FileUtil类

package compile;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileUtil {
    
    
    //读取文件内容
    public static String readFile(String filePath){
    
    
            StringBuffer buffer=new StringBuffer();
            try (FileReader fileReader=new FileReader(filePath)){
    
    
                while(true){
    
    
                    int ch=fileReader.read();
                    if (ch==-1){
    
    
                        break;
                    }
                    buffer.append((char)ch);
                }
                fileReader.close();
            }
            catch (IOException e) {
    
    
                e.printStackTrace();
            }
            return buffer.toString();
    }
    //向指定文件写内容
    public static void writeFile(String filePath,String content){
    
    
        try(FileWriter fileWriter=new FileWriter(filePath)){
    
    
            fileWriter.write(content);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
    
    
        FileUtil.writeFile("d:/test.txt","hello world");
        String content=FileUtil.readFile("d:/test.txt");
        System.out.println(content);
    }
}

创建CommandUtil类

package compile;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class CommandUtil {
    
    
    public static int run(String cmd,String stdoutFile, String stderrFile){
    
    
        try {
    
    
            //创建进程
            Process process=Runtime.getRuntime().exec(cmd);
            if (stdoutFile!=null){
    
    
                InputStream stdoutFrom=process.getInputStream();
                FileOutputStream stdoutTo=new FileOutputStream(stdoutFile);
                while (true){
    
    
                    int ch=stdoutFrom.read();
                    if (ch==-1){
    
    
                        break;
                    }
                    //讲内容输入进文件stdoutFile
                    stdoutTo.write(ch);
                }
                stdoutFrom.close();
                stdoutTo.close();
            }
            if(stderrFile!=null){
    
    
                InputStream stderrFrom=process.getErrorStream();
                FileOutputStream stderrTo=new FileOutputStream(stderrFile);
                while (true){
    
    
                    int ch=stderrFrom.read();
                    if (ch==-1){
    
    
                        break;
                    }
                    //讲内容输入进文件stderrFile
                    stderrTo.write(ch);
                }
                stderrFrom.close();
                stderrTo.close();
            }
            int exitCode=process.waitFor();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        return 1;
    }

    public static void main(String[] args) {
    
    
        CommandUtil.run("javac","stdout.txt","stderr.txt");
    }
}

创建Task类

package compile;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class Task {
    
    
    private static  String WORK_DIR=null;
    private static  String CLASS=null;
    private static  String CODE=null;
    private static  String COMPILE_ERROR=null;
    private static  String STDOUT=null;
    private static  String STDERR=null;
    public Task(){
    
    
        //是每次文件夹名字不同
        WORK_DIR="./tmp/"+ UUID.randomUUID().toString()+"/";
        CODE=WORK_DIR+"Solution.java";
        CLASS="Solution";
        COMPILE_ERROR=WORK_DIR+"compileError.txt";
        STDOUT=WORK_DIR+"stdout.txt";
        STDERR=WORK_DIR+"stderr.txt";
    }
    public Answer compileAndRun(Question question){
    
    
        Answer answer=new Answer();
        File workDir=new File(WORK_DIR);
        if (!workDir.exists()){
    
    
            workDir.mkdirs();
        }
        //如果用户提交的代码不安全则直接反馈给用户
        if (!checkCodeSafe(question.getCode())){
    
    
            System.out.println("用户提交了不安全代码");
            answer.setError(3);
            answer.setReason("你提交的代码不安全!");
            return answer;
        }
        FileUtil.writeFile(CODE,question.getCode());
        //编译该代码
        String compileCmd=String.format("javac -encoding utf8 %s -d %s",CODE,WORK_DIR);
        System.out.println("编译命令:"+compileCmd);
        CommandUtil.run(compileCmd,null,COMPILE_ERROR);
        String compileError= FileUtil.readFile(COMPILE_ERROR);
        System.out.println(compileError);
        if (!compileError.equals("")){
    
    
            System.out.println("编译出错");
            answer.setError(1);
            answer.setReason(compileError);
            return answer;
        }
        //运行该代码
        String runCmd=String.format("java -classpath %s %s",WORK_DIR,CLASS);
        System.out.println("运行命令:"+runCmd);
        CommandUtil.run(runCmd,STDOUT,STDERR);
        String runError= FileUtil.readFile(STDERR);
        if (!runError.equals("")){
    
    
            System.out.println("运行出错");
            answer.setError(2);
            answer.setReason(runError);
            return answer;
        }
        answer.setError(0);
        answer.setStdout(FileUtil.readFile(STDOUT));
        return answer;
    }

    private boolean checkCodeSafe(String code) {
    
    
        List<String> blackList=new ArrayList<>();
        blackList.add("Runtime");
        blackList.add("exec");
        blackList.add("java.io");
        blackList.add("java.net");
        for (String string:blackList) {
    
    
            int pos =code.indexOf(string);
            if (pos>=0){
    
    
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
    
    
        Task task=new Task();
        Question question=new Question();
        question.setCode("public class Solution {\n" +
                "    public static void main(String[] args) {\n" +
                "        System.out.println(\"sdfasdasd\");\n" +
                "    }\n" +
                "}\n");
        Answer answer=task.compileAndRun(question);
        System.out.println(answer.toString());
    }
}

此外为了用户提交恶意代码或者空代码交了两个CodeInValidException和ProblemNotFoundException类进行 抛出异常。
在这里插入图片描述

题目用户管理设设计

设计数据库和库

create database if not exists oj_database;
use oj_database;
drop table if exists oj_table;
create table oj_table(
    id int primary key auto_increment,
    title varchar(50),
    level varchar(50),
    description varchar(4096),
    templateCode varchar(4096),
    testCode varchar(4096)
);
drop table if exists oj_user;
create table oj_user(
    id int primary key auto_increment,
    username varchar(50) unique,
    password varchar(50) not null,
    isAdmin int
);

关于oj_table表单:id是自增主键,title是题目标题,level是代表该题目的难易程度,description是题目描述,templateCode是代码模板,testCode是测试代码。
关于oj_user表单:id是自增主键,username是用户名账号,password是用户密码,isAdmin是判断该用户是否为管理员。

创建DBUtil类

该类是进行数据库连接操作,此外为了线程安全采用了单例模式、

package common;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DBUtil {
    
    
    private static final String URL="jdbc:mysql://127.0.0.1:3306/oj_database?characterEncoding=utf8&useSSL=false";//数据库地址
    private static final String USERNAME="root";//数据库账号
    private static final String PASSWORD="123456wjh.";//数据库命名
    private static DataSource dataSource=null;
    //单例模式
    private static DataSource getDataSource(){
    
    
        if (dataSource==null){
    
    
            synchronized (DBUtil.class){
    
    
                if (dataSource==null){
    
    
                    MysqlDataSource mysqlDataSource=new MysqlDataSource();
                    mysqlDataSource.setURL(URL);
                    mysqlDataSource.setUser(USERNAME);
                    mysqlDataSource.setPassword(PASSWORD);
                    dataSource=mysqlDataSource;
                }
            }
        }
        return dataSource;
    }
    public static Connection getConnection() throws SQLException {
    
    
        return getDataSource().getConnection();
    }
    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) throws SQLException {
    
    
        if (resultSet!=null){
    
    
            resultSet.close();
        }
        if (statement!=null){
    
    
            statement.close();
        }
        if (connection!=null){
    
    
            connection.close();
        }
    }
}

实现题目管理

创建Problem类

创建该类为了以后得到数据库中的数据返回

package dao;

public class Problem {
    
    
    private int id;
    private String level;
    private String description;
    private String title;
    private String templateCode;
    private String testCode;
    @Override
    public String toString() {
    
    
        return "Problem{" +
                "id=" + id +
                ", level='" + level + '\'' +
                ", description='" + description + '\'' +
                ", title='" + title + '\'' +
                ", templateCode='" + templateCode + '\'' +
                ", testCode='" + testCode + '\'' +
                '}';
    }

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public String getLevel() {
    
    
        return level;
    }

    public void setLevel(String level) {
    
    
        this.level = level;
    }

    public String getDescription() {
    
    
        return description;
    }

    public void setDescription(String description) {
    
    
        this.description = description;
    }

    public String getTitle() {
    
    
        return title;
    }

    public void setTitle(String title) {
    
    
        this.title = title;
    }

    public String getTemplateCode() {
    
    
        return templateCode;
    }

    public void setTemplateCode(String templateCode) {
    
    
        this.templateCode = templateCode;
    }

    public String getTestCode() {
    
    
        return testCode;
    }

    public void setTestCode(String testCode) {
    
    
        this.testCode = testCode;
    }
}

创建ProblemDAO类

该类作用于题目的管理,与数据库进行交互

package dao;

import common.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ProblemDAO {
    
    
    //插入新题目
    public void insert(Problem problem){
    
    
    
    }
    //删除题目
    public void delete(int id){
    
    
        
    }
    //返回题目的基本信息
    public List<Problem> selectAll(){
    
    
        
    }
    //获取指定问题的详细问题
    public Problem selectOne(int id){
    
    
        
    }

}

insert()方法
//插入新题目
    public void insert(Problem problem){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        try {
    
    
            connection= DBUtil.getConnection();//获取数据库连接
            String sql="insert into oj_table values(null,?,?,?,?,?)";
            statement=connection.prepareStatement(sql);
            statement.setString(1,problem.getTitle());
            statement.setString(2,problem.getLevel());
            statement.setString(3,problem.getDescription());
            statement.setString(4,problem.getTemplateCode());
            statement.setString(5,problem.getTestCode());
            int ret=statement.executeUpdate();//执行sql语句
            if (ret==1){
    
    
                System.out.println("插入成功!");
            }else {
    
    
                System.out.println("题目新增失败!");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,null);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
delete()方法
//删除题目
    public void delete(int id){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="delete from oj_table where id=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            int ret=statement.executeUpdate();//执行sql语句
            if (ret==1){
    
    
                System.out.println("删除题目成功!");
            }else {
    
    
                System.out.println("删除题目失败!");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,null);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
selectAll()方法
//返回题目的基本信息
    public List<Problem> selectAll(){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        List<Problem> list=new ArrayList<>();
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select id,title,level from oj_table";
            statement=connection.prepareStatement(sql);
            resultSet=statement.executeQuery();//执行sql语句
            while (resultSet.next()){
    
    
                Problem problem=new Problem();
                problem.setId(resultSet.getInt("id"));
                problem.setTitle(resultSet.getString("title"));
                problem.setLevel(resultSet.getString("level"));
                list.add(problem);
            }
            if (list!=null){
    
    
                return list;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }
selectOne()方法
//获取指定问题的详细问题
    public Problem selectOne(int id){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select * from oj_table where id=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            resultSet=statement.executeQuery();//执行sql语句
            if (resultSet.next()){
    
    
                Problem problem=new Problem();
                problem.setId(resultSet.getInt("id"));
                problem.setTitle(resultSet.getString("title"));
                problem.setLevel(resultSet.getString("level"));
                problem.setDescription(resultSet.getString("description"));
                problem.setTemplateCode(resultSet.getString("templateCode"));
                problem.setTestCode(resultSet.getString("testCode"));
                return problem;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }

ProblemDAO完整代码

package dao;

import common.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ProblemDAO {
    
    
    //插入新题目
    public void insert(Problem problem){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        try {
    
    
            connection= DBUtil.getConnection();//获取数据库连接
            String sql="insert into oj_table values(null,?,?,?,?,?)";
            statement=connection.prepareStatement(sql);
            statement.setString(1,problem.getTitle());
            statement.setString(2,problem.getLevel());
            statement.setString(3,problem.getDescription());
            statement.setString(4,problem.getTemplateCode());
            statement.setString(5,problem.getTestCode());
            int ret=statement.executeUpdate();//执行sql语句
            if (ret==1){
    
    
                System.out.println("插入成功!");
            }else {
    
    
                System.out.println("题目新增失败!");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,null);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
    //删除题目
    public void delete(int id){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="delete from oj_table where id=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            int ret=statement.executeUpdate();//执行sql语句
            if (ret==1){
    
    
                System.out.println("删除题目成功!");
            }else {
    
    
                System.out.println("删除题目失败!");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,null);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
    //返回题目的基本信息
    public List<Problem> selectAll(){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        List<Problem> list=new ArrayList<>();
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select id,title,level from oj_table";
            statement=connection.prepareStatement(sql);
            resultSet=statement.executeQuery();//执行sql语句
            while (resultSet.next()){
    
    
                Problem problem=new Problem();
                problem.setId(resultSet.getInt("id"));
                problem.setTitle(resultSet.getString("title"));
                problem.setLevel(resultSet.getString("level"));
                list.add(problem);
            }
            if (list!=null){
    
    
                return list;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }
    //获取指定问题的详细问题
    public Problem selectOne(int id){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select * from oj_table where id=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            resultSet=statement.executeQuery();//执行sql语句
            if (resultSet.next()){
    
    
                Problem problem=new Problem();
                problem.setId(resultSet.getInt("id"));
                problem.setTitle(resultSet.getString("title"));
                problem.setLevel(resultSet.getString("level"));
                problem.setDescription(resultSet.getString("description"));
                problem.setTemplateCode(resultSet.getString("templateCode"));
                problem.setTestCode(resultSet.getString("testCode"));
                return problem;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }
}

实现用户管理

创建User类

创建User类以便于数据库进行交互

package dao;

public class User {
    
    
    private int id;
    private String username;
    private String password;
    private int isAdmin;

    public int getId() {
    
    
        return id;
    }

    @Override
    public String toString() {
    
    
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", isAdmin=" + isAdmin +
                '}';
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public String getUsername() {
    
    
        return username;
    }

    public void setUsername(String username) {
    
    
        this.username = username;
    }

    public String getPassword() {
    
    
        return password;
    }

    public void setPassword(String password) {
    
    
        this.password = password;
    }

    public int getIsAdmin() {
    
    
        return isAdmin;
    }

    public void setIsAdmin(int isAdmin) {
    
    
        this.isAdmin = isAdmin;
    }
}

创建UserDAO类

创建UserDAO类作为用户管理器类, 负责和数据库交互.

package dao;

import common.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserDao {
    
    
    //新增用户
    public void insert(User user){
    
    

    }
    //删除用户
    public void delete(int id){
    
    

    }
    //返回所有用户的信息
    public List<User> selectAll(){
    
    

    }
    //通过姓名返回用户信息
    public User selectOneByName(String username){
    
    

    }
    //通过id返回用户的信息
    public User selectOneById(int id){
    
    
    
    }

}

insert()方法
//新增用户
    public void insert(User user){
    
    
        Connection connection= null;
        PreparedStatement statement=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="insert into oj_user values(null,?,?,?)";
            statement=connection.prepareStatement(sql);
            statement.setString(1,user.getUsername());
            statement.setString(2,user.getPassword());
            statement.setInt(3,user.getIsAdmin());
            int ret =statement.executeUpdate();//执行sql语句
            if (ret==1){
    
    
                System.out.println("插入成功!");
            }else {
    
    
                System.out.println("插入失败!");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,null);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
delete()方法
//删除用户
    public void delete(int id){
    
    
        Connection connection= null;
        PreparedStatement statement=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="delete from oj_user where id=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            int ret =statement.executeUpdate();//执行sql语句
            if (ret==1){
    
    
                System.out.println("删除成功!");
            }else {
    
    
                System.out.println("删除失败!");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,null);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
selectAll()方法
//返回所有用户的信息
    public List<User> selectAll(){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        List<User> list=new ArrayList<>();
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select * from oj_user";
            statement=connection.prepareStatement(sql);
            resultSet=statement.executeQuery();//执行sql语句
            while (resultSet.next()){
    
    
                User user=new User();
                user.setId(resultSet.getInt("id"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                user.setIsAdmin(resultSet.getInt("isAdmin"));
                list.add(user);
            }
            if (list==null){
    
    
                return null;
            }else {
    
    
                return list;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }
selectOneByName()方法
//通过姓名返回用户信息
    public User selectOneByName(String username){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select * from oj_user where username=?";
            statement=connection.prepareStatement(sql);
            statement.setString(1,username);
            resultSet=statement.executeQuery();//执行sql语句
            if (resultSet.next()){
    
    
                User user=new User();
                user.setId(resultSet.getInt("id"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                user.setIsAdmin(resultSet.getInt("isAdmin"));
                return user;
            }else {
    
    
                return null;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }
selectOneById()方法
//通过id返回用户的信息
    public User selectOneById(int id){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select * from oj_user where id=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            resultSet=statement.executeQuery();//执行sql语句
            if (resultSet.next()){
    
    
                User user=new User();
                user.setId(resultSet.getInt("id"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                user.setIsAdmin(resultSet.getInt("isAdmin"));
                return user;
            }else {
    
    
                return null;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }

UserDAO完整代码

package dao;

import common.DBUtil;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserDao {
    
    
    //新增用户
    public void insert(User user){
    
    
        Connection connection= null;
        PreparedStatement statement=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="insert into oj_user values(null,?,?,?)";
            statement=connection.prepareStatement(sql);
            statement.setString(1,user.getUsername());
            statement.setString(2,user.getPassword());
            statement.setInt(3,user.getIsAdmin());
            int ret =statement.executeUpdate();//执行sql语句
            if (ret==1){
    
    
                System.out.println("插入成功!");
            }else {
    
    
                System.out.println("插入失败!");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,null);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
    //删除用户
    public void delete(int id){
    
    
        Connection connection= null;
        PreparedStatement statement=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="delete from oj_user where id=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            int ret =statement.executeUpdate();//执行sql语句
            if (ret==1){
    
    
                System.out.println("删除成功!");
            }else {
    
    
                System.out.println("删除失败!");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,null);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
    //返回所有用户的信息
    public List<User> selectAll(){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        List<User> list=new ArrayList<>();
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select * from oj_user";
            statement=connection.prepareStatement(sql);
            resultSet=statement.executeQuery();//执行sql语句
            while (resultSet.next()){
    
    
                User user=new User();
                user.setId(resultSet.getInt("id"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                user.setIsAdmin(resultSet.getInt("isAdmin"));
                list.add(user);
            }
            if (list==null){
    
    
                return null;
            }else {
    
    
                return list;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }
    //通过姓名返回用户信息
    public User selectOneByName(String username){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select * from oj_user where username=?";
            statement=connection.prepareStatement(sql);
            statement.setString(1,username);
            resultSet=statement.executeQuery();//执行sql语句
            if (resultSet.next()){
    
    
                User user=new User();
                user.setId(resultSet.getInt("id"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                user.setIsAdmin(resultSet.getInt("isAdmin"));
                return user;
            }else {
    
    
                return null;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }
    //通过id返回用户的信息
    public User selectOneById(int id){
    
    
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
    
    
            connection=DBUtil.getConnection();//获取数据库连接
            String sql="select * from oj_user where id=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,id);
            resultSet=statement.executeQuery();//执行sql语句
            if (resultSet.next()){
    
    
                User user=new User();
                user.setId(resultSet.getInt("id"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                user.setIsAdmin(resultSet.getInt("isAdmin"));
                return user;
            }else {
    
    
                return null;
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }finally {
    
    
            try {
    
    
                DBUtil.close(connection,statement,resultSet);
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
        return null;
    }
}

服务器API

实现Util类

package common;

import dao.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class Util {
    
    
    //判断用户是否登录
    public static User checkUser(HttpServletRequest req){
    
    
        HttpSession session=req.getSession(false);
        if (session==null){
    
    
            return null;
        }
        User user= (User) session.getAttribute("user");
        if (user==null){
    
    
            return null;
        }
        return user;
    }
}

实现addProblemServlet

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import dao.Problem;
import dao.ProblemDAO;

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 java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

@WebServlet("/addProblem")
public class addProblemServlet extends HttpServlet {
    
    
    private ObjectMapper objectMapper=new ObjectMapper();
    //编译响应
    static class isCorrect{
    
    
        public int correct;
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        req.setCharacterEncoding("utf8");
        resp.setContentType("application/json; charset=utf8");
        String body=readBody(req);
        isCorrect correct=new isCorrect();
        //body为空则返回
        if (body==null){
    
    
            resp.setContentType("text/html; charset=utf8");
            String html="<h3>提交的题目有问题,无法新加成功!</h3>";
            resp.getWriter().write(html);
            return;
        }
        Problem problem=objectMapper.readValue(body,Problem.class);
        ProblemDAO problemDAO=new ProblemDAO();
        problemDAO.insert(problem);
        correct.correct=1;
        String html=objectMapper.writeValueAsString(correct);
        resp.getWriter().write(html);
    }
    //实现 readBody 方法, 用来把请求中的 body 部分全读出来。
    private static String readBody(HttpServletRequest req) throws UnsupportedEncodingException {
    
    
        int contentLength=req.getContentLength();
        byte[] bytes=new byte[contentLength];
        try (InputStream inputStream = req.getInputStream()){
    
    
            inputStream.read(bytes);
            inputStream.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return new String(bytes,"utf8");
    }
}

实现CompileServlet

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import common.CodeInValidException;
import common.ProblemNotFoundException;
import common.Util;
import compile.Answer;
import compile.Question;
import compile.Task;
import dao.Problem;
import dao.ProblemDAO;
import dao.User;

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 java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

@WebServlet("/compile")
public class CompileServlet extends HttpServlet {
    
    
    private ObjectMapper objectMapper=new ObjectMapper();
    //编译请求
    static class CompileRequest{
    
    
        public int id;
        public String code;
    }
    //编译响应
    static class CompileResponse{
    
    
        public int error;
        public String reason;
        public String stdout;
    }
    @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
            resp.setContentType("application/json;charset=utf8");
            User user= Util.checkUser(req);
            if (user==null){
    
    
                resp.setStatus(403);
                String html="<h3>当前用户未登录</h3>";
                resp.getWriter().write(html);
                return;
            }
            CompileResponse compileResponse=new CompileResponse();
            CompileRequest compileRequest=null;
            Problem problem=null;
            try{
    
    
                resp.setStatus(200);
                String body=readBody(req);
                compileRequest=objectMapper.readValue(body,CompileRequest.class);
                ProblemDAO problemDAO=new ProblemDAO();
                problem=problemDAO.selectOne(compileRequest.id);
                if (problem==null){
    
    
                    throw new ProblemNotFoundException();
                }
                String testCode=problem.getTestCode();
                String requestCode=compileRequest.code;
                String finalCode=mergeCode(requestCode,testCode);
                if (finalCode==null){
    
    
                    throw new CodeInValidException();
                }
                System.out.println(finalCode);
                Task task=new Task();
                Question question=new Question();
                question.setCode(finalCode);
                Answer answer=task.compileAndRun(question);
                compileResponse.error=answer.getError();
                compileResponse.reason=answer.getReason();
                compileResponse.stdout=answer.getStdout();
            } catch (ProblemNotFoundException e) {
    
    
                compileResponse.error=3;
                compileResponse.reason="题目没有找到 id="+compileRequest.id;
            }catch (CodeInValidException e) {
    
    
                compileResponse.error=3;
                compileResponse.reason="提交的代码不符合要求";
            }finally {
    
    String respString=objectMapper.writeValueAsString(compileResponse);
                resp.getWriter().write(respString);
            }

    }
    //合并用户提交的代码
    private static String mergeCode(String requestCode, String testCode) {
    
    
        int pos=requestCode.lastIndexOf("}");
        if (pos==-1){
    
    
            return null;
        }
        String string=requestCode.substring(0,pos);
        string+=testCode+"\n}";
        return string;
    }
    //实现 readBody 方法, 用来把请求中的 body 部分全读出来。
    private static String readBody(HttpServletRequest req) throws UnsupportedEncodingException {
    
    
        int contentLength=req.getContentLength();
        byte[] bytes=new byte[contentLength];
        try (InputStream inputStream = req.getInputStream()){
    
    
            inputStream.read(bytes);
            inputStream.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return new String(bytes,"utf8");
    }
}

实现deleteProblemServlet

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import common.Util;
import dao.Problem;
import dao.ProblemDAO;
import dao.User;

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 java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

@WebServlet("/deleteProblem")
public class deleteProblemServlet extends HttpServlet {
    
    
    //获取前端页面的数据
    static class Accept{
    
    
        public int id;
    }
    //响应
    static class Result{
    
    
        public int result;
    }
    private ObjectMapper objectMapper=new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        req.setCharacterEncoding("utf8");
        resp.setContentType("application/json; charset=utf8");
        String body=readBody(req);
        //body为空则返回
        if (body==null){
    
    
            resp.setContentType("text/html; charset=utf8");
            String html="<h3>无法删除成功!</h3>";
            resp.getWriter().write(html);
            return;
        }
        Accept accept=objectMapper.readValue(body,Accept.class);
        //调用ProblemDAO
        ProblemDAO problemDAO=new ProblemDAO();
        problemDAO.delete(accept.id);
        Result result=new Result();
        result.result=1;
        String html=objectMapper.writeValueAsString(result);
        resp.getWriter().write(html);
    }
    //实现 readBody 方法, 用来把请求中的 body 部分全读出来。
    private static String readBody(HttpServletRequest req) throws UnsupportedEncodingException {
    
    
        int contentLength=req.getContentLength();
        byte[] bytes=new byte[contentLength];
        try (InputStream inputStream = req.getInputStream()){
    
    
            inputStream.read(bytes);
            inputStream.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        return new String(bytes,"utf8");
    }
}

实现isAdminServlet

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import common.Util;
import dao.User;

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 java.io.IOException;
@WebServlet("/admin")
public class isAdminServlet extends HttpServlet {
    
    
    private ObjectMapper objectMapper=new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        resp.setContentType("application/json;charset=utf8");
        User user= Util.checkUser(req);
        if (user==null){
    
    
            resp.setStatus(403);
            String html="<h3>当前用户未登录</h3>";
            resp.getWriter().write(html);
//                resp.sendRedirect("login.html");
            return;
        }
        //给前端返回用户的信息
        String html=objectMapper.writeValueAsString(user);
        resp.getWriter().write(html);
    }
}

实现LoginoutServlet

package api;

import common.Util;
import dao.User;
import dao.UserDao;

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.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/logout")
public class LoginoutServlet extends HttpServlet {
    
    
    //注销登录
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        HttpSession session = req.getSession(false);
        if (session == null) {
    
    
            resp.setContentType("text/txt; charset=utf-8");
            String html = "<h3>当前尚未登录</h3>";
            resp.getWriter().write(html);
            return;
        }
        session.removeAttribute("user");
        resp.sendRedirect("login.html");
    }
    //管理员删除用户
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        req.setCharacterEncoding("utf8");
        String username=req.getParameter("username");
        resp.setContentType("text/html; charset=utf8");
        User user=Util.checkUser(req);
        if (user==null){
    
    
            String html="<h3> 当前用户未登录 </h3>";
            resp.getWriter().write(html);
//            resp.sendRedirect("login.html");
            return;
        }
        if (user.getUsername().equals(username)){
    
    
            String html="<h3>不能删除自己</h3>";
            resp.getWriter().write(html);
            return;
        }
        UserDao userDao=new UserDao();
        User user1=userDao.selectOneByName(username);
        if (user1==null){
    
    
            String html="<h3>删除用户不存在</h3>";
            resp.getWriter().write(html);
            return;
        }
        userDao.delete(user1.getId());
        resp.sendRedirect("function.html");
    }
}

实现LoginServlet

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import dao.User;
import dao.UserDao;

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.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    
    
    //用户登录操作
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        req.setCharacterEncoding("utf8");
        resp.setContentType("text/html; charset=utf8");
        UserDao userDao=new UserDao();
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        if (username==null||password==null||"".equals(username)||"".equals(password)){
    
    
            String h3="<h3>输入格式错误</h3>";
            resp.getWriter().write(h3);
            return;
        }
        User user=userDao.selectOneByName(username);
        if (user==null){
    
    
            String h3="<h3>当前用户为空</h3>";
            resp.getWriter().write(h3);
            return;
        }
        if (!user.getUsername().equals(username)||!user.getPassword().equals(password)){
    
    
            String h3="<h3>当前密码或者账号 错误!</h3>";
            resp.getWriter().write(h3);
            return;
        }
        //将登录用户放进session中
        HttpSession session=req.getSession(true);
        session.setAttribute("user",user);
        resp.sendRedirect("index.html");
    }
}

实现ProblemServlet

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import common.Util;
import dao.Problem;
import dao.ProblemDAO;
import dao.User;

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 java.io.IOException;
import java.util.List;

@WebServlet("/problem")
public class ProblemServlet extends HttpServlet {
    
    
    private ObjectMapper objectMapper=new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //设置为json格式
        resp.setContentType("application/json;charset=utf8");
        User user= Util.checkUser(req);
        if (user==null){
    
    
            resp.setContentType("text/html; charset=utf-8");
            resp.setStatus(403);
            String html="<h3>当前用户未登录</h3>";
            resp.getWriter().write(html);
            return;
//            resp.sendRedirect("login.html");
//            return;
        }
            resp.setStatus(200);
            String id=req.getParameter("id");
            ProblemDAO problemDAO=new ProblemDAO();
            if (id==null||"".equals(id)){
    
    
                List<Problem> list=problemDAO.selectAll();
                //讲后台数据进行json格式化,方便前台获取后进行后续操作
                String respString=objectMapper.writeValueAsString(list);
                resp.getWriter().write(respString);
                return;
            }else {
    
    
                Problem problem=problemDAO.selectOne(Integer.parseInt(id));
                //讲后台数据进行json格式化,方便前台获取后进行后续操作
                String respString=objectMapper.writeValueAsString(problem);
                resp.getWriter().write(respString);
                return;
            }
        }

}

实现RegisterServlet

package api;

import dao.User;
import dao.UserDao;

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 java.io.IOException;
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
    
    
    //注册用户
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        req.setCharacterEncoding("utf8");
        resp.setContentType("text/html; charset=utf8");
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        
        String admin=req.getParameter("admin");
        UserDao userDao=new UserDao();
        if (username==null||password==null||"".equals(username)||"".equals(password)){
    
    
            String h3="<h3>输入格式错误</h3>";
            resp.getWriter().write(h3);
            return;
        }
        User user=userDao.selectOneByName(username);
        if (user!=null){
    
    
            String h3="<h3>该用户名字已被使用!</h3>";
            resp.getWriter().write(h3);
            return;
        }
        User registerUser=new User();
        registerUser.setUsername(username);
        registerUser.setPassword(password);
        if (admin==null||"".equals(admin)){
    
    
            registerUser.setIsAdmin(0);
            userDao.insert(registerUser);
            resp.sendRedirect("login.html");
        }
        else {
    
    
            registerUser.setIsAdmin(Integer.parseInt(admin));
            userDao.insert(registerUser);
            resp.sendRedirect("function.html");
        }
    }
}

前端页面实现

前端的页面都是来源于网上免费的模板,这里只会出现前后端交互的相关代码。

login.html

			<div class="login-agileits-top"> 	
						<!-- 使用form表单将前端输入的数据返回给后端 -->
						<form action="login" method="post"> 
							<p>User Name </p>
							<input type="text" class="name" name="username" >
							<p>Password</p>
							<input type="password" class="password" name="password">
							<input type="submit" value="Sign In">
						</form>
						<!-- 点击该按钮则跳转到注册页面 -->
						<div style=" text-align: center;">
							<button style="font-size: large;"><a href="register.html" style=" text-align: center;">SignUp</a></button>
						</div>
					
					</div>

register.html

					<div class="login-agileits-top" >
						<!-- 使用form表单将前端输入的数据返回给后端  -->
						<form action="register" method="post"> 
							<p>User Name </p>
							<input type="text" class="name" name="username" required=""/>
							<p>Password</p>
							<input type="password" class="password" name="password" required=""/>  
							<input type="submit" value="SignUp">
						</form> 	
					</div>  

index.html

					<tbody id="problemTable">
                                                            
                                </tbody>
                                <script src="js/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
        <script src="js/app.js"></script>
        <script>
            //获取问题的部分信息,获取失败则返回登录页面
            function getProblem(){
     
     
                $.ajax({
     
     
                    url:"problem",
                    type:"GET",
                    success:function(data,status){
     
     
                        makeProblemTable(data);
                    },error:function(data,status){
     
     
                        location.assign("login.html");
                    }
                })
            }
            //获取用户登录信息,获取失败则返回登录页面
            function getUser(){
     
     
                $.ajax({
     
     
                    url:"admin",
                    type:"GET",
                    success:function(data,status){
     
     
                        isAdminUser(data);
                    },error:function(data,status){
     
     
                        location.assign("login.html");
                    }
                })
            }//判断目前登录用户是否为管理员,是增加‘管理员页面’
            function isAdminUser(user){
     
     
                let div=document.querySelector("#javaoj");
                if(user.isAdmin){
     
     
                    let a=document.createElement("a");
                    a.innerHTML="管理员页面";
                    a.href="function.html";
                    a.target="_blank";
                    div.appendChild(a);
                }
            }
            function makeProblemTable(data){
     
     
                //获取id为problemTable的元素
                let problemTable=document.querySelector("#problemTable");
                for(let problem of data){
     
     
                    let tr=document.createElement("tr");
                    let tdId=document.createElement("td");
                    tdId.innerHTML=problem.id;
                    tr.appendChild(tdId);
                    let tdTitle=document.createElement("td");
                    let a=document.createElement("a");
                    a.innerHTML=problem.title;
                    a.href="problemDetail.html?id="+problem.id;
                    a.target='_blank';
                    tdTitle.appendChild(a);
                    tr.appendChild(tdTitle);
                    let tdlevel=document.createElement("td");
                    tdlevel.innerHTML=problem.level;
                    tr.appendChild(tdlevel);
                    problemTable.appendChild(tr);
                }
            }
            getUser();
            getProblem();
            
        </script>

problemDetail.html

 <section class="my-5 pt-5">
            <div class="container">
                <div class="row mt-4">
                    <div class="col-sm-12 pb-4">
                        <div class="jumbotron jumbotron-fluid">
                            <div class="container" id="problemDesc">
                                
                            </div>
                        </div>
                    </div>
                </div>
                <div class="row mt-4">
                    <div class="col-sm-12 pb-4">
                        <div class="form-group">
                            <label for="codeEditor">代码编辑框</label>
                            <div id="editor" style="min-height:400px">
                                <textarea class="form-control" id="codeEditor" style="width: 100%; height: 400px;"></textarea>
                            </div>
                        </div>
                    </div>
                </div>
                <button type="button" class="btn btn-primary" id="submitButton">提交</button>

                <div class="row mt-4">
                    <div class="col-sm-12 pb-4">
                        <div class="jumbotron jumbotron-fluid">
                            <div class="container">
                                <pre id="problemResult">
                                </pre>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
        <!-- 引入 ace.js ,给用户有更好的体验感-->
        <script src="https://cdn.bootcdn.net/ajax/libs/ace/1.2.9/ace.js"></script>
        <script src="https://cdn.bootcdn.net/ajax/libs/ace/1.2.9/ext-language_tools.js"></script>
        <script>
            function initAce() {
     
     
                // 参数 editor 就对应到刚才在 html 里加的那个 div 的 id
                let editor = ace.edit("editor");
                editor.setOptions({
     
     
                    enableBasicAutocompletion: true,
                    enableSnippets: true,
                    enableLiveAutocompletion: true
                });
                editor.setTheme("ace/theme/twilight");
                editor.session.setMode("ace/mode/java");
                editor.resize();
                document.getElementById('editor').style.fontSize = '20px';
                return editor;
            }
            let editor = initAce();
            // 通过 ajax 从服务器获取到题目的详情
            function getProblem() {
     
     
                // 1. 通过 ajax 给服务器发送一个请求
                $.ajax({
     
     
                    url: "problem" + location.search,
                    type: "GET",
                    success: function (data, status) {
     
     
                        makeProblemDetail(data);
                    },error: function(data,status){
     
     
                        location.assign('login.html');
                    }
                })
            }

                $.ajax({
     
     
                    url: "problem",
                    type: "GET",
                    error: function(data,status){
     
     
                        location.assign('login.html');
                    }
                });

            function makeProblemDetail(problem) {
     
     
                // 1. 获取到 problemDesc, 把题目详情填写进去
                let problemDesc = document.querySelector("#problemDesc");

                let h3 = document.createElement("h3");
                h3.innerHTML = problem.id + "." + problem.title + "_" + problem.level
                problemDesc.appendChild(h3);

                let pre = document.createElement("pre");
                let p = document.createElement("p");
                p.innerHTML = problem.description;
                pre.appendChild(p);
                problemDesc.appendChild(pre);

                // 2. 把代码的模板填写到编辑框中. 
                // let codeEditor = document.querySelector("#codeEditor");
                // codeEditor.innerHTML = problem.templateCode;
                editor.setValue(problem.templateCode)

                // 3. 给提交按钮注册一个点击事件
                let submitButton = document.querySelector("#submitButton");
                submitButton.onclick = function () {
     
     
                    // 点击这个按钮, 就要进行提交. (把编辑框的内容给提交到服务器上)
                    let body = {
     
     
                        id: problem.id,
                        // code: codeEditor.value,
                        code: editor.getValue(),
                    };
                    $.ajax({
     
     
                        type: "POST",
                        url: "compile",
                        data: JSON.stringify(body),
                        success: function (data, status) {
     
     
                            let problemResult = document.querySelector("#problemResult");
                            if (data.error == 0) {
     
     
                                // 编译运行没有问题, 把 stdout 显示到页面中
                                problemResult.innerHTML = data.stdout;
                            } else {
     
     
                                // 编译运行没有问题, 把 reason 显示到页面中
                                problemResult.innerHTML = data.reason;
                            }
                        },error: function(data,status){
     
     
                            location.assign('login.html');
                        }
                    });
                }
            }
            getProblem();
        </script>

function.html

<script src="js/jquery.min.js"></script>
        <!-- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
        <script src="js/app.js"></script>
        <script>
            //判断该用户是否为管理员不是则返回登录页面
            function getUser(){
     
     
                $.ajax({
     
     
                    url:"admin",
                    type:"GET",
                    success:function(data,status){
     
     
                        if(!data.isAdmin){
     
     
                            location.assign("index.html");
                        }
                    },
                    error:function(data,status){
     
     
                        location.assign("login.html");
                    }
                })
            }
            getUser();
        </script>

deleteUser.html

<div class="agile-row" >
					<h3>SignUp Form</h3>
					<div class="login-agileits-top" >
						<!-- 使用form表单将前端输入的数据返回给后端 -->
						<form action="logout" method="post"> 
							<p>UserName</p>
							<input type="text" class="name" name="username"> 
							<input type="submit" value="Delete">
						</form> 	
					</div>  
				</div>
				<script src="js/jquery.min.js"></script>
	<script>
        //判断该用户是否为管理员不是则返回登录页面
		function getUser(){
     
     
                $.ajax({
     
     
                    url:"admin",
                    type:"GET",
                    success:function(data,status){
     
     
                        if(!data.isAdmin){
     
     
                            location.assign("index.html");
                        }
                    },
                    error:function(data,status){
     
     
                        location.assign("login.html");
                    }
                })
            }
            getUser();
	</script>

deleteProblem.html

<div class="mt-3 mb-5">
                            <h3>题目列表</h3>
                            <table class="table table-striped">
                                <thead>
                                    <tr>
                                        <th>编号</th>
                                        <th>标题</th>
                                        <th>难度</th>
                                    </tr>
                                </thead>
                                <tbody id="problemTable">
                                                                    
                                </tbody>
                            </table>
                        </div>
                        <script src="js/jquery.min.js"></script>
        <!-- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
        <script src="js/app.js"></script>
        <script>
            //获取题目信息
            function getProblem(){
     
     
                $.ajax({
     
     
                    url:"problem",
                    type:"GET",
                    success:function(data,status){
     
     
                        makeProblemTable(data);
                    },error:function(data,status){
     
     
                        location.assign("login.html");
                    }
                })
            }
        //判断该用户是否为管理员不是则返回登录页面
            function getUser(){
     
     
                $.ajax({
     
     
                    url:"admin",
                    type:"GET",
                    success:function(data,status){
     
     
                        if(!data.isAdmin){
     
     
                            location.assign("index.html");
                        }
                    },
                    error:function(data,status){
     
     
                        location.assign("login.html");
                    }
                })
            }
            function makeProblemTable(data){
     
     
                let problemTable=document.querySelector("#problemTable");
                for(let problem of data){
     
     
                    let tr=document.createElement("tr");
                    let tdId=document.createElement("td");
                    tdId.innerHTML=problem.id;
                    tr.appendChild(tdId);
                    let tdTitle=document.createElement("td");
                    let a=document.createElement("a");
                    a.innerHTML=problem.title;
                    a.href="problemDetail.html?id="+problem.id;
                    a.target='_blank';
                    tdTitle.appendChild(a);
                    tr.appendChild(tdTitle);
                    let tdlevel=document.createElement("td");
                    tdlevel.innerHTML=problem.level;
                    tr.appendChild(tdlevel);
                    let tdButton=document.createElement("td");
                    let button=document.createElement("button");
                    button.innerHTML="删除";
                    button.value=problem.id;
                    button.id="submit";
                    //给按钮设计一个点击事件
                    button.onclick=function(){
     
     
                    let body={
     
     
                        id: problem.id,
                    };
                    $.ajax({
     
     
                        url: "deleteProblem",
                        type: "Post",
                        data:JSON.stringify(body),
                        success:function(data,status){
     
     
                            if(data){
     
     
                                location.assign("deleteProblem.html");
                            }
                        }
                    })
                }
                    tdButton.appendChild(button);
                    tr.appendChild(tdButton);
                    problemTable.appendChild(tr);
                }
            }
            getUser();
            getProblem();
            
        </script>

addUser.html

<div class="login-agileits-top" >
						<!-- 使用form表单将前端输入的数据返回给后端 -->
						<form action="register" method="post"> 
							<p>UserName </p>
							<input type="text" class="name" name="username" required=""/>
							<p>Password</p>
							<input type="password" class="password" name="password" required=""/>  
							<p>isAdmin(是输入1 否则为0)</p>
							<input type="text" class="name" name="admin" required=""/>
							<input type="submit" value="SignUp">
						</form> 	
					</div> 
						<script src="js/jquery.min.js"></script>

					<script>
        //获取用户登录信息,获取失败则返回登录页面
		function getUser(){
     
     
                $.ajax({
     
     
                    url:"admin",
                    type:"GET",
					success:function(data,status){
     
     
						if(!data.isAdmin){
     
     
							location.assign("index.html");
						}
					},
                    error:function(data,status){
     
     
                        location.assign("login.html");
                    }
                })
            }
            getUser();
	</script> 

addProblem.html

<section class="my-5 pt-5">
            <div class="container">
                <div class="row mt-4">
                    <div class="col-sm-12 pb-4">
                        <div class="form-group">
                            <label for="title">标题</label>
                                <textarea class="form-control" id="title" style="width: 100%; height: 40px;"></textarea>
                        </div>
                    </div>
                </div>
                <div class="row mt-4">
                    <div class="col-sm-12 pb-4">
                        <div class="form-group">
                            <label for="level">难度</label>
                                <textarea class="form-control" id="level" style="width: 100%; height: 40px;"></textarea>
                        </div>
                    </div>
                </div>
                <div class="row mt-4">
                    <div class="col-sm-12 pb-4">
                        <div class="form-group">
                            <label for="description">题目描述</label>
                                <textarea class="form-control" id="description" style="width: 100%; height: 400px;"></textarea>
                        </div>
                    </div>
                </div>
                <div class="row mt-4">
                    <div class="col-sm-12 pb-4">
                        <div class="form-group">
                            <label for="TestCode">测试用例</label>
                                <textarea class="form-control" id="TestCode" style="width: 100%; height: 400px;"></textarea>
                        </div>
                    </div>
                </div>
                <div class="row mt-4">
                    <div class="col-sm-12 pb-4">
                        <div class="form-group">
                            <label for="codeEditor">代码</label>
                                <textarea class="form-control" id="codeEditor" style="width: 100%; height: 400px;"></textarea>
                        </div>
                    </div>
                </div>
                <button type="button" class="btn btn-primary" id="submitButton">提交</button>
            </div>
        </section>

        <!--footer-->
        <section class="py-5 bg-dark">
            <div class="container">
                <div class="row">
                    <div class="col-md-6 offset-md-3 col-sm-8 offset-sm-2 col-xs-12 text-center">
                        
                        <p class="pt-2 text-muted">
                            &copy; by 文墨轩
                        </p>
                    </div>
                </div>
            </div>
        </section>
        <script src="js/jquery.min.js"></script>
        <script>
            function getUser(){
     
     
                $.ajax({
     
     
                    url:"admin",
                    type:"GET",
					success:function(data,status){
     
     
						if(!data.isAdmin){
     
     
							location.assign("index.html");
						}
					},
                    error:function(data,status){
     
     
                        location.assign("login.html");
                    }
                })
            }
            let button=document.querySelector("#submitButton");
            button.onclick=function(){
     
     
                let body={
     
     
                    id: 0,
                    title: title.value,
                    level: level.value,
                    description: description.value,
                    testCode: TestCode.value,
                    templateCode: codeEditor.value,
                };
                $.ajax({
     
     
                    url:"addProblem",
                    type:"POST",
                    data: JSON.stringify(body),
                    success:function(data,status){
     
     
                        if(data.correct){
     
     
                            location.assign("function.html");
                        }
                    }
                })
            }
            getUser();
        </script>

项目展示

管理员

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

普通用户

在这里插入图片描述
在这里插入图片描述

Gitee地址

在线oj代码地址

猜你喜欢

转载自blog.csdn.net/weixin_49830664/article/details/123527905