这套基于Java在线考试系统是我的优秀毕业设计作品,当初是团队开发出来的,花了两个月时间。从系统设计到开发成功都花了团队很多的心血。
在线考试系统实现了包含题库编辑、抽题组卷、试题分析、在线考试等模块的Web考试系统。在线考试系统一直以来就毕业设计的热门选题,难度也算是比较高的毕设项目了。对学生的技术水平要求高,工作量也比较大。
在线考试系统已经实现的主要功能有:
1、在线考试(包含限定时间设置),支持选择题、填空题、判断题三种题型,自动判分
2、选择题、填空题、判断题及用户信息的文本文件数据的Web导入
3、用户注册、登录、修改密码、基本信息管理
4、按照一定给分策略进行抽题和组卷,支持“固定组卷” 和“随机组卷”两种方式
5、按照内容、知识点、答案等搜索题库,题目及分数的统计
6、章节知识点的分层和树状展示
7、管理广播消息的推送、系统设置的修改
项目是基于Java+Tomca+Mysql开发的,部署简单,代码注释详细易懂。
下面看下在线考试系统数据库表设计
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
登录代码
package cn.lynu.lyq.java_exam.actions;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import cn.lynu.lyq.java_exam.dao.StudentDao;
import cn.lynu.lyq.java_exam.entity.Student;
@Component("userLogin")
@Scope("prototype")
public class UserLoginAction extends ActionSupport {
private static final long serialVersionUID = 5090548832375142158L;
private final static Logger logger = LoggerFactory.getLogger(UserLoginAction.class);
private String registerNo;
private String password;
private String username;
@Resource
private StudentDao studentDao;
public String getRegisterNo() {
return registerNo;
}
public void setRegisterNo(String registerNo) {
this.registerNo = registerNo;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String execute() throws Exception {
logger.info("用户登陆");
Student stu = studentDao.findByRegNoAndPassword(registerNo, password);
if(stu!=null){
username=stu.getName();
ActionContext ctx=ActionContext.getContext();
ctx.getSession().put("USER_INFO", stu);
}else{
this.addActionError("学号或密码错误,请重新输入!");
}
return SUCCESS;
}
public String logout() throws Exception{
logger.info("用户退出登陆");
ActionContext ctx=ActionContext.getContext();
ctx.getSession().remove("USER_INFO");
this.addActionMessage("退出登陆成功!");
return SUCCESS;
}
}
成绩功能代码
package cn.lynu.lyq.java_exam.actions;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.lang.ArrayUtils;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.ui.TextAnchor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import cn.lynu.lyq.java_exam.common.ExamPhase;
import cn.lynu.lyq.java_exam.dao.ExamDao;
import cn.lynu.lyq.java_exam.dao.StudentDao;
import cn.lynu.lyq.java_exam.dao.StudentExamScoreDao;
import cn.lynu.lyq.java_exam.entity.Student;
import cn.lynu.lyq.java_exam.entity.StudentExamScore;
import cn.lynu.lyq.java_exam.misc.CustomColorBarRenderer;
@Component("scoresBarChart")
@Scope("prototype")
public class ScoresBarChartAction extends ActionSupport {
private static final long serialVersionUID = 2217462899746164125L;
private final static Logger logger = LoggerFactory.getLogger(ScoresBarChartAction.class);
private JFreeChart chart;
@Resource
private StudentDao studentDao;
@Resource
private ExamDao examDao;
@Resource
private StudentExamScoreDao studentExamScoreDao;
public JFreeChart getChart() {
return chart;
}
public void setChart(JFreeChart chart) {
this.chart = chart;
}
@Override
public String execute() throws Exception {
// double[][] data = new double[][] { { 90 , 80 , 77 , 85 } };
// String[] rowKeys = {""};
// String[] columnKeys = { "张三", "李四", "王二", "马六" };
ActionContext ctx =ActionContext.getContext();
String classSearch=ctx.getParameters().get("classSearch").getValue();
String examNameSearch=ctx.getParameters().get("examNameSearch").getValue();
logger.debug("classSearch=["+classSearch+"]");
logger.debug("examNameSearch=["+examNameSearch+"]");
// Student theStudent =(Student)ctx.getSession().get("USER_INFO");
// List<Student> stuList = studentDao.findByGrade(theStudent.getGrade());
List<String> examNameList = examDao.findAllDistinctExamName();
if(!examNameSearch.equals("")){
examNameSearch=examNameList.get(Integer.parseInt(examNameSearch)-1);
}else{
examNameSearch=examNameList.get(0);
}
List<StudentExamScore> list1 = studentExamScoreDao.findByClassIdAndExamNameAndExamPhase(classSearch,examNameSearch,
ExamPhase.FINAL_SCORED.getChineseName());
List<String> stuNameList = new ArrayList<>();
List<Double> scoreList = new ArrayList<>();
for(StudentExamScore examScore:list1){
scoreList.add((double)examScore.getScore());
Student stu = studentDao.findById(examScore.getStudent().getId());
stuNameList.add(stu.getName());
}
String[] stuNameArray = (String[])stuNameList.toArray(new String[stuNameList.size()]);
Double[] integerScoreArray = (Double[])scoreList.toArray(new Double[scoreList.size()]);
double[] scoreArray = ArrayUtils.toPrimitive(integerScoreArray);
//排序
int[] index = new int[scoreArray.length];//原始下标数组
for(int i=0; i<scoreArray.length; i++){
index[i] = i;
}
sortWithIndex(scoreArray,index);
//根据分数排序,重新排列姓名数组
String[] stuNameArraySorted = new String[stuNameArray.length];
for(int i=0; i<stuNameArray.length; i++){
stuNameArraySorted[i] = stuNameArray[index[i]];
}
double[][] data = new double[][] { scoreArray };
String[] rowKeys = {""};
String[] columnKeys = stuNameArraySorted;
// logger.debug(">>>>>>>>>>学生名列表:"+Arrays.toString(stuNameArraySorted));
// logger.debug(">>>>>>>>>>学生名length:"+stuNameArraySorted.length);
// logger.debug(">>>>>>>>>>分数列表:"+Arrays.toString(scoreArray));
// logger.debug(">>>>>>>>>>分数length"+scoreArray.length);
CategoryDataset dataset = DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);
// 创建主题样式
StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
// 设置标题字体
standardChartTheme.setExtraLargeFont(new Font("SimHei", Font.BOLD, 20));
// 设置图例的字体
standardChartTheme.setRegularFont(new Font("Microsoft YaHei", Font.PLAIN, 15));
// 设置轴向的字体
standardChartTheme.setLargeFont(new Font("Microsoft YaHei", Font.PLAIN, 15));
standardChartTheme.setSmallFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
// 应用主题样式
ChartFactory.setChartTheme(standardChartTheme);
chart = ChartFactory.createBarChart3D("成绩分布图", "姓名", "成绩", dataset, PlotOrientation.HORIZONTAL, false,
false, false);
CategoryPlot plot = chart.getCategoryPlot();// 获得图表区域对象
CustomColorBarRenderer renderer = new CustomColorBarRenderer();
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE4, TextAnchor.BASELINE_RIGHT));
renderer.setItemLabelAnchorOffset(25D);
renderer.setBaseItemLabelsVisible(true);
plot.setRenderer(renderer);
return SUCCESS;
}
/*
* 冒泡排序 并返回 排序对应的原始下标
*/
public void sortWithIndex(double[] array, int[] index){
// index = new int[array.length];//原始下标数组
// for(int i=0; i<array.length; i++){
// index[i] = i;
// }
for(int i=0; i<array.length; i++){//冒泡轮次i
for(int j=0; j<array.length-i-1; j++){//参与比较的数组下标j
if(array[j]<array[j+1]){
double tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
int tmp2 = index[j];
index[j] = index[j+1];
index[j+1] = tmp2;
}
}
}
}
}
需要可以加微信(LGY178888)了解下!