Java实训模拟学生考试系统

Java实训模拟学生考试系统

第一部分 系统简介

  • 此实训使用java语言实现,能够实现学生的注册和登录,以及能够对学生进行考试和对试卷的批改,注册的用户名、密码(密码会通过MD5加密方式加密)和考试成绩等数据会通过redies数据库存储到本地文本文档中。

第二部分 软件准备

  • 我使用的是IntelliJ IDEA编译器,这篇文章的范例也都将使用IntelliJ IDEA展示,除此之外还需要redies数据库,我会将涉及到的所有软件打包放到最后。

  • IntelliJ IDEA编译器,可以去浏览器中搜索,下载社区版即可。安装过程可以借鉴其他UP主的文章,这里不再赘述。

  • redies数据库也可以去浏览器中搜索下载最新版本,我使用的不是最新版本,如有需要可以去我打包的文件中寻找。

  • redies数据库详细的使用方法:
    1.将redies数据库文件夹放到新建好的文件夹中(推荐全英文路径)
    在这里插入图片描述
    2.将redies数据库启动,WIN+R启动一个运行窗口输入cmd,使用CD命令切换到redies数据库文件所在的位置运行
    在这里插入图片描述
    在这里插入图片描述
    这里以F盘为例,C盘情况如下:
    在这里插入图片描述
    完成上步之后在最后一行输入如下代码:

    redis-server redis.windows.conf
    

    在这里插入图片描述
    选择允许访问即可,看到上图的图形说明redies数据库启动成功,此时不要关闭命令提示框,否则redies数据库将不能使用。运行程序的时候也不能关闭。

第三部分 系统代码

  • 主程序 ExamController
package controller;

import java.util.List;
import java.util.Scanner;
import dao.ExamDao;
import model.Paper;
import service.impl.*;
import service.*;

public class ExamController {
    
    


	public static void main(String[] args) {
    
    

		String name;
		String Key = "secret";
		String key;
		Integer score ;
		boolean flag = false;
		boolean flag1 = false;
		String[] myAnswers = new String[5];
		ExamService examServiceImpl = new ExamServiceImpl();
		MultiValueMapImpl mode = new MultiValueMapImpl();
		ExamDao account = new ExamDao();
		Scanner reader = new Scanner(System.in);
		System.out.println("***欢迎进入考试系统***");
		//模拟考生登录系统
		while(!flag) {
    
    
			flag1 = false;
			System.out.println("*************");
			System.out.println("请输入r进行注册");
			System.out.println("请输入l进行登录");
			System.out.println("请输入q退出系统");
			System.out.println("*************");
			String k = reader.next();
			Scanner readerType;

			switch(k.charAt(0)) {
    
    
				case 'r':
					System.out.println("*************");
					System.out.println("请注册用户名");
					Scanner readerName0 = new Scanner(System.in);
					name = readerName0.next();
					if ( ExamDao.jedis.get(name+Key) == null){
    
    
						System.out.println("*************");
						System.out.println("请输入密码");
						Scanner readerKey0 = new Scanner(System.in);
						key = readerKey0.next();
						account.saveAccount(name,key);
						System.out.println("已完成注册!!!");
						while(!flag1) {
    
    
							System.out.println("*************");
							System.out.println("请输入s开始考试");
							System.out.println("请输入c查询成绩");
							System.out.println("请输入h查询历史成绩");
							System.out.println("请输入e返回上级");
							System.out.println("*************");
							readerType = new Scanner(System.in);
							switch (readerType.next().charAt(0)) {
    
    
								case 's':
									System.out.println("考试开始");
									List<Paper> paperLists = examServiceImpl.getPaper();
									int i = 0;
									for (Paper p : paperLists) {
    
    
										if (i <= 4) {
    
    
											System.out.println(p.getTitle(i));
											System.out.println("*************");
											System.out.println("请输入你的选项");
    										Scanner myAns = new Scanner(System.in);
											myAnswers[i] = myAns.next().toUpperCase();
											boolean flag3 = false;
											if ((myAnswers[i].equalsIgnoreCase("A")) ||(myAnswers[i].equalsIgnoreCase("B")) || (myAnswers[i].toUpperCase().equals("C"))){
    
    
												//equalsIgnoreCase(String anotherString)将此 String 与另一个 String 进行比较,不考虑大小写。如果两个字符串的长度相等,并且两个字符串中的相应字符都相等(忽略大小写),则认为这两个字符串是相等的。
												i++;
											}
											else{
    
    
												while (!flag3) {
    
    
													System.out.println("*************");
													System.out.println("请输入A、B、C(或a、b、c)!!!");
													System.out.println("*************");
													Scanner myAns0 = new Scanner(System.in);
													myAnswers[i] = myAns.next().toUpperCase();
													if ((myAnswers[i].equalsIgnoreCase("A")) || (myAnswers[i].equalsIgnoreCase("B")) || (myAnswers[i].toUpperCase().equals("C"))) {
    
    
														i++;
														flag3 = true;

													}
												}
											}



										}

									}
									examServiceImpl.check(name, myAnswers, key);
									System.out.println("考试结束");
									break;
								case 'c':
									score = examServiceImpl.getScore(name);
									if (score < 0) {
    
    
										System.out.println(name + "未参加考试~");
									} else if (score >= 60)
										System.out.println(name + "的成绩为:" + score + " 恭喜通过考试~");
									else
										System.out.println(name + "的成绩为:" + score + " 很遗憾,需要继续努力~");
									break;
								case 'h':
									System.out.println(examServiceImpl.getHistroyScore(name));
									break;
								case 'e':
									flag1 = true;
									break;
							}
						}
					}
					else{
    
    
						System.out.println("此用户名已注册请重新注册!!!");
					}
					break;
				case 'l':
					System.out.println("请输入用户名");
					Scanner readerName1 = new Scanner(System.in);
					name = readerName1.next();
					if ( ExamDao.jedis.get(name+Key) != null){
    
    
						System.out.println("*************");
						System.out.println("请输入密码");
						Scanner readerKey1 = new Scanner(System.in);
						key = readerKey1.next();
						if (key.equals(ExamDao.jedis.get(name+Key))){
    
    
							while(!flag1) {
    
    
								System.out.println("*************");
								System.out.println("请输入s开始考试");
								System.out.println("请输入c查询成绩");
								System.out.println("请输入h查询历史成绩");
								System.out.println("请输入e返回上级");
								System.out.println("*************");
								readerType = new Scanner(System.in);
								switch(readerType.next().charAt(0)) {
    
    
									case 's':
										System.out.println("考试开始");
										List<Paper> paperLists =examServiceImpl.getPaper();
										int i = 0;
										for (Paper p : paperLists) {
    
    
											if (i<=4){
    
    
												System.out.println(p.getTitle(i));
												System.out.println("*************");
												System.out.println("请输入你的选项");
												Scanner myAns = new Scanner(System.in);
												myAnswers[i] = myAns.next().toUpperCase();
												boolean flag4 = false;
												if ((myAnswers[i].equalsIgnoreCase("A")) ||(myAnswers[i].equalsIgnoreCase("B")) || (myAnswers[i].equalsIgnoreCase("C"))){
    
    
													//equalsIgnoreCase(String anotherString)将此 String 与另一个 String 进行比较,不考虑大小写。如果两个字符串的长度相等,并且两个字符串中的相应字符都相等(忽略大小写),则认为这两个字符串是相等的。
													i++;
												}
												else{
    
    
													while (!flag4) {
    
    
														System.out.println("*************");
														System.out.println("请输入A、B、C(或a、b、c)!!!");
														System.out.println("*************");
														Scanner myAns1 = new Scanner(System.in);
														myAnswers[i] = myAns.next().toUpperCase();
														if ((myAnswers[i].equalsIgnoreCase("A")) || (myAnswers[i].equalsIgnoreCase("B")) || (myAnswers[i].equalsIgnoreCase("C"))) {
    
    
															i++;
															flag4 = true;

														}
													}
												}


											}
										}
										examServiceImpl.check(name, myAnswers, key);
										System.out.println("考试结束");
										break;
									case 'c':
										score = examServiceImpl.getScore(name);
										if(score < 0) {
    
    
											System.out.println(name + "未参加考试~");
										}else if(score>=60)
											System.out.println(name + "的成绩为:"+ score+" 恭喜通过考试~");
										else
											System.out.println(name + "的成绩为:"+ score+" 很遗憾,需要继续努力~");
										break;
									case 'h':
										System.out.println(examServiceImpl.getHistroyScore(name));
										break;
									case 'e':
										flag1 = true;
										break;
								}

							}
						}
						else{
    
    
							System.out.println("密码不正确!!!");
						}
					}
					else{
    
    
						System.out.println("该用户名不存在请进行注册!!!");
						break;
					}
					break;
				case 'q':
					flag = true;
				default:
					break;
			}
		}
		System.out.println("系统退出");
	}
}
  • 数据库连接和数据存储 ExamDao
package dao;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import redis.clients.jedis.Jedis;
import service.impl.MultiValueMapImpl;
import service.impl.MakeSecret;

/**
 * 数据层
 * @author double
 *
 */
public class ExamDao {
    
    
    public static Jedis jedis;
    String Score = "score";
    private static final String[] ansvers = {
    
    "A", "B", "A", "C", "B"};
    MultiValueMapImpl<String, String> stringMultiValueMap = new MultiValueMapImpl<>();

    private static String path = "C:\Users\86761\Desktop\JavaText\LocalMemory.txt";

    static {
    
    
        //连接本地的Redis 服务
        jedis = new Jedis("localhost");
        //如果Redis服务设置了密码;需要下面这行,没有就不需要
        //jedis.auth("123456");
        System.out.println("连接Redis成功");
        //查看服务是否运行
        System.out.println("服务正在运行:" + jedis.ping());
    }

    public String[] getAnswers() {
    
    
        return ansvers;
    }

    public List<String> paperPut() {
    
    
        try {
    
    
            String encoding = "GBK";
            File file = new File("C:\Users\86761\Desktop\JavaText\Text.txt");
            String text;
            if (file.isFile() && file.exists()) {
    
     // 判断文件是否存在
                InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到文件编码问题
                BufferedReader bufferedReader = new BufferedReader(read);
                List<String> listString = new LinkedList<>();
                while (((text = bufferedReader.readLine()) != null)) {
    
    
                    // System.out.println(lineTxt);
                    listString.add(text);
                }
                read.close();
                return listString;
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return null;
    }

    public void saveAccount(String name, String key) {
    
    
        String Key = "secret";
        String account = name + Key;
        ExamDao.jedis.set(account, key);
    }

    public boolean saveScore(String name, String score, String key) {
    
    
        stringMultiValueMap.add(name, key);
        stringMultiValueMap.add(name, score);
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now = sdf.format(date);
        String total = "";
        if (jedis.get(name) != null) {
    
    
            total = jedis.get(name);
        }
        jedis.set(name, total + score + " " + now + "\r\n");
        jedis.set(name+Score,score);

        return writer(name, Integer.parseInt(score), path, now, key);
    }

    public boolean writer(String name, Integer score, String path, String now, String key) {
    
    
        MakeSecret secretKey = new MakeSecret();
        boolean flag = true;
        FileWriter fw = null;
        try {
    
    
            fw = new FileWriter(path, true);
            fw.write("\r\n" + String.format("%-3s", name) + "   " + score + "   " + now + " " + secretKey.getResult(key));
            //刷新
            fw.flush();
        } catch (Exception e) {
    
    
            e.printStackTrace();
            flag = false;
        } finally {
    
    
            if (fw != null) {
    
    
                try {
    
    
                    fw.close();
                } catch (Exception e) {
    
    
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

        public int getName(String name) {
    
    
            return jedis.get(name+Score)!= null ? Integer.parseInt(jedis.get(name+Score)) : -1;
        }

        public String getHistoryName(String name) {
    
    
            return jedis.get(name) != null ? jedis.get(name) : "暂无历史成绩!";
        }

}
  • 试卷获取 Paper
package model;

import service.impl.ExamServiceImpl;

public class Paper {
    
    
	private String title;
	public Paper(String title) {
    
    
		this.setTitle(title);
	}
	public String getTitle(int x) {
    
    
		int i = 0;
		int k;
		ExamServiceImpl examService = new ExamServiceImpl();
		String[] paperlist = new String[1000];
		for (Paper p : examService.getPaper()){
    
    
			paperlist[i] = p.title;
			i++;
		}
		if (x>=4 & x<5){
    
    
			for (k = 16; k < 19 ; k++) {
    
    
				System.out.println(paperlist[k]);
			}
			return paperlist[k];
		}
		else if (x == 3) {
    
    
			for (k = 12; k < 15; k++) {
    
    
				System.out.println(paperlist[k]);
			}
			return paperlist[k];
		}
		else if (x == 2){
    
    
			for ( k = 8; k < 11 ; k++) {
    
    
				System.out.println(paperlist[k]);
			}
			return paperlist[k];
		}
		else if (x == 1){
    
    
			for ( k = 4; k <7  ; k++) {
    
    
				System.out.println(paperlist[k]);
			}
			return paperlist[k];
		}
		else if (x == 0) {
    
    
			for (k = 0; k < 3; k++) {
    
    
				System.out.println(paperlist[k]);
			}
			return paperlist[k];
		}
		else {
    
    
			return null ;
		}
	}
	public void setTitle(String title) {
    
    
		this.title = title;
	}

}
  • 考试服务实现 ExamServiceImpl
package service.impl;

import java.util.LinkedList;
import java.util.List;
import dao.ExamDao;
import model.Paper;
import service.ExamService;


public class ExamServiceImpl implements ExamService{
    
    

    ExamDao examDao = new ExamDao();
    @Override
    public List<Paper> getPaper(){
    
    
        ExamDao examDao = new ExamDao();
        List<Paper> listPaper = new LinkedList<>();
        for (String textString : examDao.paperPut()){
    
    
            Paper m = new Paper(textString);
            listPaper.add(m);
        }
        return listPaper;
    }

    @Override
    public boolean check(String name, String[] ans,String key) {
    
    
        int score=this.answer(ans);
        examDao.saveScore(name,""+score,key);
        return true;
    }

    @Override
    public int getScore(String name) {
    
    
        // TODO Auto-generated method stub
        return examDao.getName(name);
    }

    @Override
    public String getHistroyScore(String name) {
    
    
        // TODO 返回及格的历史分数
        return examDao.getHistoryName(name) ;
    }

    @Override
    public int answer(String[] ans) {
    
    
        String[] correctAns=examDao.getAnswers();
        int score=0;
        for(int i=0;i<correctAns.length;i++){
    
    
            if(correctAns[i].equals(ans[i])){
    
    
                score+=20;
            }
        }

        return score;
    }
}
  • 将密码加密 MakeSecret
package service.impl;

import java.math.BigInteger;
import java.security.MessageDigest;

public class MakeSecret {
    
    
    public static final String KEY_MD5 = "MD5";

    public  String  getResult(String inputStr)
    {
    
    
//        System.out.println("=======加密前的数据:"+inputStr);
        BigInteger bigInteger=null;

        try {
    
    
            MessageDigest md = MessageDigest.getInstance(KEY_MD5);
            byte[] inputData = inputStr.getBytes();
            md.update(inputData);
            bigInteger = new BigInteger(md.digest());
        } catch (Exception e) {
    
    e.printStackTrace();}
//        System.out.println("MD5加密后:" + bigInteger.toString(16));
        return bigInteger.toString(16);
    }
}
  • 构造一键多值Map的实现 MultiValueMapImpl
package service.impl;

import service.MultiValueMap;

import java.util.*;

/**
 * Created in Jan 10, 2016 5:03:17 PM.
 *
 * @author Yan Zhenjie;
 */
public class MultiValueMapImpl<K, V> implements MultiValueMap<K, V> {
    
    

    protected Map<K, List<V>> mSource = new LinkedHashMap<K, List<V>>();

    public MultiValueMapImpl() {
    
    
    }

    @Override
    public void add(K key, V value) {
    
    
        if (key != null) {
    
    
            // 如果有这个Key就继续添加Value,没有就创建一个List并添加Value
            if (!mSource.containsKey(key))
                mSource.put(key, new ArrayList<V>(2));
            mSource.get(key).add(value);
        }
    }

    @Override
    public void add(K key, List<V> values) {
    
    
        // 遍历添加进来的List的Value,调用上面的add(K, V)方法添加
        for (V value : values) {
    
    
            add(key, value);
        }
    }

    @Override
    public void set(K key, V value) {
    
    
        // 移除这个Key,添加新的Key-Value
        mSource.remove(key);
        add(key, value);
    }

    @Override
    public void set(K key, List<V> values) {
    
    
        // 移除Key,添加List<V>
        mSource.remove(key);
        add(key, values);
    }

    @Override
    public void set(Map<K, List<V>> map) {
    
    
        // 移除所有值,便利Map里的所有值添加进来
        mSource.clear();
        mSource.putAll(map);
    }

    @Override
    public List<V> remove(K key) {
    
    
        return mSource.remove(key);
    }

    @Override
    public void clear() {
    
    
        mSource.clear();
    }

    @Override
    public Set<K> keySet() {
    
    
        return mSource.keySet();
    }

    @Override
    public List<V> values() {
    
    
        // 创建一个临时List保存所有的Value
        List<V> allValues = new ArrayList<V>();

        // 便利所有的Key的Value添加到临时List
        Set<K> keySet = mSource.keySet();
        for (K key : keySet) {
    
    
            allValues.addAll(mSource.get(key));
        }
        return allValues;
    }

    @Override
    public List<V> getValues(K key) {
    
    
        return mSource.get(key);
    }

    @Override
    public V getValue(K key, int index) {
    
    
        List<V> values = mSource.get(key);
        if (values != null && index < values.size())
            return values.get(index);
        return null;
    }

    @Override
    public int size() {
    
    
        return mSource.size();
    }

    @Override
    public boolean isEmpty() {
    
    
        return mSource.isEmpty();
    }

    @Override
    public boolean containsKey(K key) {
    
    
        return mSource.containsKey(key);
    }

}
  • 考试服务接口 ExamService
package service;

import java.util.List;


import model.Paper;

public interface ExamService {
    
    

	List<Paper> getPaper();

	boolean check(String name, String[] ans,String key);

	int getScore(String name);

	String getHistroyScore(String name);

	int answer(String[] ans);
}
  • 一键多值Map的接口 MultiValueMap
package service;

import java.util.List;
import java.util.Map;
import java.util.Set;

public interface MultiValueMap<K, V> {
    
    

    /**
     * 添加Key-Value。
     *
     * @param key   key.
     * @param value value.
     */
    void add(K key, V value);

    /**
     * 添加Key-List<Value>。
     *
     * @param key    key.
     * @param values values.
     */
    void add(K key, List<V> values);

    /**
     * 设置一个Key-Value,如果这个Key存在就被替换,不存在则被添加。
     *
     * @param key   key.
     * @param value values.
     */
    void set(K key, V value);

    /**
     * 设置Key-List<Value>,如果这个Key存在就被替换,不存在则被添加。
     * @param key    key.
     * @param values values.
     * @see #set(Object, Object)
     */
    void set(K key, List<V> values);

    /**
     * 替换所有的Key-List<Value>。
     *
     * @param values values.
     */
    void set(Map<K, List<V>> values);

    /**
     * 移除某一个Key,对应的所有值也将被移除。
     *
     * @param key key.
     * @return value.
     */
    List<V> remove(K key);

    /**
     * 移除所有的值。
     * Remove all key-value.
     */
    void clear();

    /**
     * 拿到Key的集合。
     * @return Set.
     */
    Set<K> keySet();

    /**
     * 拿到所有的值的集合。
     *
     * @return List.
     */
    List<V> values();

    /**
     * 拿到某一个Key下的某一个值。
     *
     * @param key   key.
     * @param index index value.
     * @return The value.
     */
    V getValue(K key, int index);

    /**
     * 拿到某一个Key的所有值。
     *
     * @param key key.
     * @return values.
     */
    List<V> getValues(K key);

    /**
     * 拿到MultiValueMap的大小.
     *
     * @return size.
     */
    int size();

    /**
     * 判断MultiValueMap是否为null.
     *
     * @return True: empty, false: not empty.
     */
    boolean isEmpty();

    /**
     * 判断MultiValueMap是否包含某个Key.
     *
     * @param key key.
     * @return True: contain, false: none.
     */
    boolean containsKey(K key);

}
  • 以上代码的结构如图:
    在这里插入图片描述

第四部分 具体使用

  • 首先在文件夹中创建两个如下图所示的文本文档,内容复制我打包好的里面的即可
    在这里插入图片描述
  • 同时注意这两处文件的地址要相对应
    在这里插入图片描述
  • 都准备好后运行程序,出现这种画面便是进入了系统
    在这里插入图片描述
    进行注册
    在这里插入图片描述
    如果直接开始考试会显示,没有参加考试
    在这里插入图片描述
    共五道题,全部答完后便会显示考试结束,题目和答案可以自己设置
    在这里插入图片描述
    考完可以直接查询成绩
    在这里插入图片描述
    考试成绩等信息会自己保存在本地
    在这里插入图片描述
    查询历史成绩会显示成绩以及作答的具体时间
    在这里插入图片描述
    选择返回上级会直接到最开始的登录界面
    在这里插入图片描述
    如果输入的密码不正确会弹出提示
    在这里插入图片描述
    退出系统程序结束,要想再进入系统需要重新运行程序
    在这里插入图片描述
  • 此程序的不足之处在于考试题目的获取不是很完美,没有完成题目随机获取,以及题目的长度是固定的没有做到可变,希望对此有兴趣的人可以对他进行改良,欢迎大家交流。
  • 拓展之处使用了MultiValueMap(一键多值)将用户名作为键,密码和分数作为值,使用了MD5加密方式把用户保存在本地的密码进行了加密。
  • 如果遇到jedis报红可以使用IntelliJ IDEA的自动修复修复。

第五部分 网址链接

  • 如果想继续了解redies数据库相关知识,可访问下面的网址:
  • https://www.runoob.com/redis/redis-install.html
  • 链接:https://pan.baidu.com/s/1cqjst0w3Y0IAHyJX1d5h-w
    提取码:8096

猜你喜欢

转载自blog.csdn.net/qq_56866000/article/details/125933900