29基于java的在线考试系统设计与实现

本章节来介绍一个基于java的在线考试系统的实现

系统概要

近年来,随着世界各国需要参加考核的人员与日俱增,单纯依靠传统的人工安排考场和监考人员的纸质化考试逐渐显示出了效率低,易发生冲突的缺陷,这时,在线考试系统便应运而生,此种考试方式以方便快捷高效等优点将越来越适用于如今的各项考试、考核。此外,无纸化在线考试对考试人员和审阅人员均提供了便捷。因此,本文将主要以JAVA为开发基础,实现一个在线考试系统。

它的用户由学生、教师,管理员和超级管理员组成。学生登陆系统可以进行在线测试和成绩查询。当学生登陆时,系统会随机地为学生选取试题组成考卷。当学生提交考卷后,系统会自动批改客观题,并将试卷提供给教师查看和提醒教师对试卷主观题进行修改。待教师修改完试卷后,系统会自动生成考生成绩和分数段统计信息。学生可以查询自己的成绩信息和试卷,以便更好地了解自己的学习情况。教师也可以通过分数段统计信息更好地了解学生的学生情况。后台管理员可以对考题,考试设置信息,用户信息进行维护。学生,教师,管理员和超级管理员都可以对个人信息进行维护。

  • 基础功能
  • 学生角色
  • 教师角色
  • 管理员角色
  • 超级管理角色
    拥有全部角色权限,且在此基础上添加功能:

详细功能在下面会介绍到。

系统使用的架构和内容获取

采用B/S的架构实现,整体遵循MVC的设计思想。

> 后端:java,spring,springmvc,mybatis,springboot等
> 数据库:mysql
> 开发工具:idea或者eclipse
> 前端:html,css,javascript,jquery,layui等
> 文件储存:采用的七牛云储存
> 更多内容可查看:http://projecthelp.top

项目实现

  • 用户 UserController 的实现
@Controller
@Slf4j
@Api("用户controller")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private UserClazzService userClazzService;
    @Autowired
    private Kaptcha kaptcha;

    @PostMapping("/login")
    @ResponseBody
    @ApiOperation("登录")
    @OperationLog("登录")
    public ResponseParam login(String username, String password, String code) {
        String msg = "";
        try {
            if (kaptcha.validate(code)){
                //获取主体对象
                Subject subject = SecurityUtils.getSubject();
                subject.login(new UsernamePasswordToken(username, password));
                log.info("{}登录成功",subject.getPrincipal());
                return new ResponseParam("登录成功");
            }
        } catch (KaptchaNotFoundException e) {
            msg="验证码已失效!";
        } catch (KaptchaIncorrectException e) {
            msg="验证码错误!";
        } catch (UnknownAccountException e) {
            msg="用户名错误!";
        } catch (IncorrectCredentialsException e) {
            msg="密码错误!";
        } catch (Exception e){
           throw e;
        }
        log.info("{}登录失败,{}",username,msg);
        return ResponseUtil.getErrorResponseParam(msg);
    }

    @GetMapping("logout")
    @ApiOperation("注销")
    @OperationLog("注销")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "login";
    }

    @PostMapping("/register")
    @ResponseBody
    @ApiOperation("注册")
    @OperationLog("注册")
    public ResponseParam registerTeacher(@Validated @RequestBody RequestDataParam<RegisterUserParam> req) throws Exception {
        RegisterUserParam data = req.getData();
        if(ObjectUtil.notEqual(data.getRole(), RoleEnum.STUDENT.getCode()) && ObjectUtil.notEqual(data.getRole(), RoleEnum.TEACHER.getCode())){
            throw new ServiceException("注册失败");
        }
        UserRequestParam user = new UserRequestParam();
        BeanUtil.copyProperties(data, user);
        RequestDataParam<UserRequestParam> param = new RequestDataParam<>();
        param.setData(user);
        return save(param);
    }

    @RequiresUser
    @ResponseBody
    @PostMapping({"/user/information"})
    @ApiOperation("个人信息修改")
    @OperationLog("个人信息修改")
    public ResponseParam information(@Validated @RequestBody RequestDataParam<UserRequestParam> req){
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        UserRequestParam data = req.getData();
        data.setUsername(null);
        data.setRole(null);
        data.setId(user.getId());
        return update(data);
    }

    /*----------------------------------管理员------------------------------*/

    @PostMapping("/user/updateUser/{id}")
    @ResponseBody
    @ApiOperation("用户管理:修改用户")
    @OperationLog("用户管理:修改用户")
    @RequiresRoles(value = {"admin","superadmin"}, logical = Logical.OR)
    public ResponseParam updateUser(@PathVariable("id")Long id, @Validated @RequestBody RequestDataParam<UserRequestParam> req) throws Exception {
        Integer role = req.getData().getRole();
        if(!(RoleEnum.STUDENT.getCode().equals(role) || RoleEnum.TEACHER.getCode().equals(role))){
            return ResponseUtil.getErrorResponseParam("您没有权限!");
        }
        req.getData().setId(id);
        return update(req.getData());
    }

    @PostMapping("/user/saveUser")
    @ResponseBody
    @ApiOperation("用户管理:新增用户")
    @OperationLog("用户管理:新增用户")
    @RequiresRoles(value = {"admin","superadmin"}, logical = Logical.OR)
    public ResponseParam saveUser(@Validated @RequestBody RequestDataParam<UserRequestParam> req) throws Exception {
        Integer role = req.getData().getRole();
        if(!(RoleEnum.STUDENT.getCode().equals(role) || RoleEnum.TEACHER.getCode().equals(role))){
            return ResponseUtil.getErrorResponseParam("您没有权限!");
        }
        return save(req);
    }

    @RequiresRoles(value = {"admin","superadmin"}, logical = Logical.OR)
    @PostMapping("/user/listUserForPage")
    @ResponseBody
    @ApiOperation("用户管理:查询用户")
    @OperationLog("用户管理:查询用户")
    public ResponseParam listUserForPage(@Validated @RequestBody PageRequestParam<UserPageRequestParam> req) throws Exception {
        UserPageRequestParam data = req.getData();

        Page<User> page = new Page<>(req.getPage(),req.getLimit());
        page = userService.listForPage(page,data,false);

        return new ResponseParam(page);
    }

    @RequiresRoles(value = {"admin","superadmin"}, logical = Logical.OR)
    @PostMapping("/user/deleteUser/{id}")
    @ResponseBody
    @ApiOperation("用户管理:删除用户")
    @OperationLog("用户管理:删除用户")
    public ResponseParam deleteUser(@PathVariable("id")Long id) {
        User user = userService.getById(id);
        if(ObjectUtil.isNull(user) || !(RoleEnum.STUDENT.getCode().equals(user.getRole()) || RoleEnum.TEACHER.getCode().equals(user.getRole()))){
            return ResponseUtil.getErrorResponseParam("您没有权限!");
        }
        return deleteById(id);
    }

    @RequiresRoles(value = {"admin","superadmin"}, logical = Logical.OR)
    @PostMapping("/user/lockUser/{id}")
    @ResponseBody
    @ApiOperation("用户管理:封禁/解封用户")
    @OperationLog("用户管理:封禁/解封用户")
    public ResponseParam lockUser(@PathVariable("id")Long id) {
        User user = userService.getById(id);
        if(ObjectUtil.isNull(user) || !(RoleEnum.STUDENT.getCode().equals(user.getRole()) || RoleEnum.TEACHER.getCode().equals(user.getRole()))){
            return ResponseUtil.getErrorResponseParam("您没有权限!");
        }
        return lockById(id);
    }

    @RequiresRoles(value = {"admin","superadmin"}, logical = Logical.OR)
    @GetMapping("/user/listStudent")
    @ResponseBody
    @ApiOperation("用户管理:学生列表")
    @OperationLog("用户管理:学生列表")
    public ResponseParam listStudent() {
        List<User> userList = userService.listUser(RoleEnum.STUDENT.getCode());
        return new ResponseParam(userList);
    }

    @RequiresRoles(value = {"admin","superadmin"}, logical = Logical.OR)
    @GetMapping("/user/listTeacher")
    @ResponseBody
    @ApiOperation("用户管理:教师列表")
    @OperationLog("用户管理:教师列表")
    public ResponseParam listTeacher() {
        List<User> userList = userService.listUser(RoleEnum.TEACHER.getCode());
        return new ResponseParam(userList);
    }

    @RequiresRoles(value = "superadmin")
    @PostMapping("/user/deleteAdmin/{id}")
    @ResponseBody
    @ApiOperation("用户管理:删除管理员")
    @OperationLog("用户管理:删除管理员")
    public ResponseParam deleteAdmin(@PathVariable("id")Long id) {
        return deleteById(id);
    }

    @RequiresRoles(value = "superadmin")
    @PostMapping("/user/lockAdmin/{id}")
    @ResponseBody
    @ApiOperation("用户管理:封禁/解封管理员")
    @OperationLog("用户管理:封禁/解封管理员")
    public ResponseParam lockAdmin(@PathVariable("id")Long id) {
        return lockById(id);
    }

    @RequiresRoles(value = "superadmin")
    @PostMapping("/user/listAdminForPage")
    @ResponseBody
    @ApiOperation("用户管理:查询管理员")
    @OperationLog("用户管理:查询管理员")
    public ResponseParam listAdminForPage(@Validated @RequestBody PageRequestParam<UserPageRequestParam> req) {
        UserPageRequestParam data = req.getData();

        Page<User> page = new Page<>(req.getPage(),req.getLimit());
        page = userService.listForPage(page,data,true);

        return new ResponseParam(page);
    }

    @PostMapping("/user/saveAdmin")
    @ResponseBody
    @ApiOperation("用户管理:新增管理员")
    @OperationLog("用户管理:新增管理员")
    @RequiresRoles(value = "superadmin")
    public ResponseParam saveAdmin(@Validated @RequestBody RequestDataParam<UserRequestParam> req) throws Exception {
        return save(req);
    }

    @PostMapping("/user/updateAdmin/{id}")
    @ResponseBody
    @ApiOperation("用户管理:修改管理员")
    @OperationLog("用户管理:修改管理员")
    @RequiresRoles(value = "superadmin")
    public ResponseParam updateAdmin(@PathVariable("id")Long id, @Validated @RequestBody RequestDataParam<UserRequestParam> req) {
        req.getData().setId(id);
        return update(req.getData());
    }

    @RequiresRoles(value = {"teacher","superadmin"}, logical = Logical.OR)
    @PostMapping("/user/listStudentForPage")
    @ResponseBody
    @ApiOperation("用户管理:查询学生")
    @OperationLog("用户管理:查询学生")
    public ResponseParam listStudentForPage(@Validated @RequestBody PageRequestParam<StudentPageRequestParam> req) throws Exception {
        StudentPageRequestParam data = req.getData();

        User user = (User) SecurityUtils.getSubject().getPrincipal();
        UserClazz userClazz = UserClazz.builder().userId(user.getId()).build();
        List<Long> clazzIds = userClazzService.list(userClazz).stream().map(UserClazz::getClazzId).collect(Collectors.toList());
        List<Long> studentIds = userClazzService.listByClazzIds(clazzIds).stream().map(UserClazz::getUserId).collect(Collectors.toList());

        data.setStudentIds(studentIds);
        Page<User> page = new Page<>(req.getPage(),req.getLimit());
        page = userService.listStudentForPage(page,data);

        return new ResponseParam(page);
    }
}
  • QiniuUtil七牛云工具类
@Component
@Slf4j
public class QiniuUtil {

    @Value("${oss.qiniu.accessKey}")
    private String accessKey;

    @Value("${oss.qiniu.secretKey}")
    private String secretKey;

    @Value("${oss.qiniu.bucketname}")
    private String bucketname;

    public String upload(MultipartFile file) throws IOException, UploadException {
        if(ObjectUtil.isNull(file)) {
            return "";
        }
        // region2是华南区域
        Configuration cfg = new Configuration(Region.autoRegion());
        UploadManager uploadManager = new UploadManager(cfg);
        // 生成上传凭证,然后准备上传
        Auth auth = Auth.create(accessKey, secretKey);
        // 上传
        Response response;
        String fileName;
        String filType;
        DefaultPutRet putRet = null;
        try {
            String originalFileName = file.getOriginalFilename();
            filType = originalFileName.substring(originalFileName.lastIndexOf("."));
            fileName = StrUtil.concat(true, String.valueOf(DateUtil.currentSeconds()), RandomUtil.randomString(6),filType);
            response = uploadManager.put(file.getBytes(), fileName, auth.uploadToken(bucketname));
            // 解析上传成功的结果
            putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
        } catch (QiniuException e) {
            // 请求失败时打印的异常的信息
            log.warn(StrUtil.concat(true,StrUtil.toString(e.code()),e.response.toString()));
            throw new UploadException("上传七牛云失败");
        }
        return fileName;
    }

    //删除文件 参数:存储的图片文件名
    public void deleteFileFromQiniu(String fileName){
        Configuration cfg = new Configuration(Region.region2());
        String key = fileName;
        Auth auth = Auth.create(accessKey, secretKey);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        try {
            bucketManager.delete(bucketname, key);
        } catch (QiniuException e) {
            //如果遇到异常,说明删除失败
            log.warn(StrUtil.concat(true,StrUtil.toString(e.code()),e.response.toString()));
        }
    }
}
  • 成绩导出工具类
@Slf4j
public class ExcelUtil {

    public static void download(HttpServletResponse response,String fileName, Class pojoClass, Collection collection) throws IOException, UploadException {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20") + ".xlsx");
            EasyExcel.write(response.getOutputStream(), pojoClass)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet("sheet1")
                    .doWrite(collection);
        } catch (Exception e) {
            log.error("成绩导出失败,文件下载时发生异常",e);
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSONUtil.toJsonStr(map));
        }
    }
}

部分功能展示

登录页面

在这里插入图片描述
管理员,教师和学生角色统一一个登陆页面,通过登录进去后台判断不同的角色权限,跳转到不同的页面系统。

注册

在这里插入图片描述
系统目前可以是学生和老师进行一个注册,然后进入系统,当然如果你的业务是不需要用户进行注册的话,可以把这个注册给删除掉,因为管理员也是可以在后台进行添加用户的。

管理员身份

首页

在这里插入图片描述
首页有一个轮播图和系统公告,系统公告管理员可以加入后台进行管理,点击后台入口即可进入管理页面。

管理页面首页

在这里插入图片描述

学生和教师用户管理

在这里插入图片描述
管理员可以增加和修改用户,包括学生和教师,也可以禁用用户操作。

班级管理

在这里插入图片描述

学生申请加入班级

在这里插入图片描述

因为开放了学生自己注册的功能,所以学生和教师的关联,可以学生自己通过系统进行申请,当然如果实际情况不是注册的方式的话,管理员可以自己进行关联的,该功能可以灵活去掉。

在线考试管理

考试的一个过程需要在这申明一下:

1.首先先要有一个题库 ;
2.然后管理员或者老师往这个题库里面添加题目
3.创建一份试卷,试卷的产生是通过自己定义题目的个数,然后选择上面创建的题库,进行自动组卷。
4.创建一次考试,需要选择一份试卷,然后选中考试的班级,然后还有开始的时间。
5.到达开始时间后,学生登录系统中进行考试。
6.考试结束后,提交试卷,为防止考试学生提前交卷,然后告诉答案给考场上面正在考试的同学,所以考试结束后才开始系统自动触发批改系统job.
7.学生查看开始分数情况。

题库管理

在这里插入图片描述

题目管理

在这里插入图片描述
新增加题目:
在这里插入图片描述

试卷管理

在这里插入图片描述
新增加一份试卷,进行自动组卷:
在这里插入图片描述

考试管理

在这里插入图片描述
新增加一次考试:
在这里插入图片描述

学生成绩管理

在这里插入图片描述
还可以导出考试考的成绩列表:
在这里插入图片描述

超级管理员角色

具有所有的上面管理员选线,额外再增加以下的功能:

管理所有管理员

在这里插入图片描述

系统公告管理

在这里插入图片描述

系统操作日志管理

在这里插入图片描述

教师身份角色

首页

在这里插入图片描述

教师管理端首页

在这里插入图片描述
显示最近考试的情况统计。

学生列表

在这里插入图片描述
相对于管理员来讲,就只能看到学生用户,而看不到管理员用户角色的,并且不可以增加学生用户。

班级管理

在这里插入图片描述
下面具体的教师的权限信息,可以参照右边的导航栏和上面管理员的角色看到教师角色所具有的权限,这里就没必要一一列举了:
在这里插入图片描述

学生角色

学生首页

在这里插入图片描述

关联教师

因为学生有可能是自己注册进来的,所以需要自己提交申请加入老师的班级:
在这里插入图片描述

考试列表

在这里插入图片描述
这里展示的是自己关联的老师下的班级下已经创建的考试列表。

参加考试

在这里插入图片描述

考试页面

在这里插入图片描述

我的成绩

在这里插入图片描述

我的错题

在这里插入图片描述

成绩分析

在这里插入图片描述

个人信息

在这里插入图片描述

我的班级

在这里插入图片描述

修改登录密码

在这里插入图片描述
以上是大部分功能展示,所有的功能都是正常运行,没有bug,导入到idea或者eclipse即可运行,没有套路,具体细节大家下载后自己慢慢研究,欢迎大家一起交流学习

原文链接:https://www.cnblogs.com/projecthelp/p/17380907.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:29基于java的在线考试系统设计与实现 - Python技术站

(0)
上一篇 2023年5月8日
下一篇 2023年5月8日

相关文章

  • 一篇文章带你入门java泛型

    一篇文章带你入门Java泛型 什么是Java泛型? Java泛型是Java语言的一种特性,它是为了让程序员能够编写更加通用的代码而设计的。 通过使用泛型,程序员可以定义一种或多种类型作为参数或返回值,而不需要指定具体的类型。 对于泛型的用途,最常见的就是集合类型,可以使用泛型来定义集合的类型。 如何使用Java泛型? Java泛型使用一对尖括号“<&g…

    Java 2023年5月23日
    00
  • Java开发实现的Socket双向通信功能示例

    下面就是讲解“Java开发实现的Socket双向通信功能示例”的完整攻略。 1. Socket双向通信概述 Socket是一种网络通信协议,可以在网络上实现进程间的通信,它是一种双向的通信机制,也称为套接字。在Java中,Socket通常指的是Java socket API,也就是Java中的网络编程模块。 Java中的Socket通常用于网络编程,可以在两…

    Java 2023年5月26日
    00
  • 详解Java中字符流与字节流的区别

    下面是“详解Java中字符流与字节流的区别”的完整攻略。 一、Java中的字符流和字节流 在Java中,文件的读取和写入可以通过字符流和字节流实现,两者的区别在于处理文件时所看待的最基本的单元:字节流以字节为单位进行操作,而字符流以字符为单位进行操作。 在Java中,字符是Unicode的,占用两个字节;而字节是指计算机存储数据的最小单位,占用一个字节。因此…

    Java 2023年5月20日
    00
  • Spring data jpa的使用与详解(复杂动态查询及分页,排序)

    下面是关于“Spring data jpa的使用与详解(复杂动态查询及分页,排序)”的完整攻略。 什么是Spring data jpa? Spring data jpa是Spring Framework的一部分,它在JPA(Java Persistence API)的基础上提供了更简单的方式来访问数据库。它可以轻松地访问各种数据库,并支持分页、排序和动态查询…

    Java 2023年5月20日
    00
  • Java安全性的作用是什么?

    Java安全性的作用是确保Java应用程序在运行时不受到恶意攻击或未经授权的访问,从而保护计算机和数据安全。Java安全性涵盖了以下几个方面: 防止未授权访问:通过Java安全管理器,可以控制Java代码对系统资源(如文件、网络等)的访问权,从而防止未经授权的访问和操作。例如,可以通过设置Java安全管理器来限制Java应用程序的读取和写入文件的能力,从而防…

    Java 2023年5月11日
    00
  • Java运行期注解的作用是什么?

    Java运行期注解是在运行期间动态地修改代码行为或元数据的方式。在Java语言中,使用注解可以为类、方法、字段等元素添加额外的元数据信息,特别是在框架应用中,注解是必要的成分之一。 Java运行期注解的作用包括但不限于以下几个方面: 1. 解耦 运行期注解是通过将元数据信息附加在程序元素上而实现的,整个注解体系实现了代码与元数据之间的解耦。开发人员在不破坏原…

    Java 2023年5月11日
    00
  • java.lang.Runtime.exec() Payload知识点详解

    下面我将详细讲解一下“java.lang.Runtime.exec() Payload知识点详解”的完整攻略。 什么是java.lang.Runtime.exec() Payload? java.lang.Runtime.exec()是Java语言中一个可以执行外部命令的方法。正常使用该方法可以很方便地执行各种系统命令,功能非常强大。但是,当我们在执行该方法…

    Java 2023年5月20日
    00
  • 深入理解Java泛型、协变逆变、泛型通配符、自限定

    禁止转载 重写了之前博客写的泛型相关内容,全部整合到这一篇文章里了,把坑都填了,后续不再纠结这些问题了。本文深度总结了函数式思想、泛型对在Java中的应用,解答了许多比较难的问题。 纯函数 协变 逆变 泛型通配符 PECS法则 自限定 Part 1: 协变与逆变 Java8 引入了函数式接口,从此方法传参可以传递函数了,有人说这是语法糖。 实际上,这是编程范…

    Java 2023年4月22日
    00
合作推广
合作推广
分享本页
返回顶部