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日

相关文章

  • springboot 使用mybatis查询的示例代码

    以下是关于”springboot 使用mybatis查询的示例代码”的完整攻略: 1. 准备工作 在开始之前,我们需要做一些准备工作: Java JDK 1.8 及以上版本 Gradle 或者 Maven 等构建工具 MyBatis 3 + SpringBoot 数据库(本示例使用 MySQL) 这些工具和技术是开发这个示例所需的基本要素。如果你已经安装好了…

    Java 2023年5月19日
    00
  • 什么是字节码?

    以下是关于字节码的完整使用攻略: 什么是字节码? 字节码是Java程序编译后的中间代码,它是一种与平台无关的二进制格式。字节码可以在Java虚拟(JVM)上运行,VM将字节码解释成机器码并执行。 字节码的优点 字节码具有以下优点: 跨平台性由于字节码是与平台关的,因此程序可以在不同的操作系统上运行,而不需要修改代码。 安全性由于字节码是中代码,因此它可以被反…

    Java 2023年5月12日
    00
  • Java将json对象转换为map键值对案例详解

    当需要在Java程序中处理JSON对象时,常见的方式是将其解析为Java中的HashMap数据结构。以下是将JSON对象转换为Map键值对的完整攻略。 步骤一:导入依赖包 在Java代码中解析JSON对象通常需要使用第三方库,如FastJson、Jackson等。我们可以在项目的pom.xml文件中添加如下依赖: <dependency> &lt…

    Java 2023年5月26日
    00
  • Spring中配置数据源的几种方式

    下面是 Spring 中配置数据源的几种方式的完整攻略。 1. 在 XML 文件中配置数据源 在 Spring 的 XML 配置文件中,我们可以使用以下 XML 元素来配置数据源: <bean id="dataSource" class="org.springframework.jdbc.datasource.Driver…

    Java 2023年5月20日
    00
  • 使用Spring Boot 2.x构建Web服务的详细代码

    使用Spring Boot 2.x构建Web服务的详细代码攻略 Spring Boot是一个流行的Java框架,可以帮助开发人员快速构建Web应用程序。本文将详细介绍使用Spring Boot 2.x构建Web服务的详细代码攻略,包括如何创建Spring Boot项目、如何定义Controller、如何处理请求、如何返回响应等。 创建Spring Boot项…

    Java 2023年5月15日
    00
  • spring mvc中直接注入的HttpServletRequst安全吗

    Spring MVC中直接注入的HttpServletRequest安全吗? 在Spring MVC中,我们可以直接在控制器方法中注入HttpServletRequest对象,以便在方法中访问请求信息。但是,这种做法是否安全呢?本文将对此进行详细讲解,并提供两个示例说明。 直接注入HttpServletRequest的安全问题 直接注入HttpServlet…

    Java 2023年5月17日
    00
  • Tomcat报错:HTTP Status 500 (Wrapper cannot find servlet class)解决办法

    当Tomcat在运行Servlet时出现错误信息 “HTTP Status 500 – Wrapper cannot find servlet class”,这通常表示Tomcat无法找到指定的servlet class。出现这种情况通常有以下几种解决办法。 一、检查web.xml文件的元素是否存在或正确 在web.xml文件中声明了Servlet的元素指定…

    Java 2023年5月19日
    00
  • 使用nginx+tomcat实现静态和动态页面的分离

    使用Nginx和Tomcat实现静态和动态页面的分离,具体步骤如下: 步骤一:安装Nginx和Tomcat 首先需要安装Nginx和Tomcat,建议使用最新版本。可以在Ubuntu系统上通过以下命令进行安装: sudo apt-get update sudo apt-get install nginx tomcat9 步骤二:配置Nginx 接下来需要配置…

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