基于javaweb+mysql的jsp+servlet考试系统(java+jsp+bootstrap+servlet+mysql)
运行环境
Java≥8、MySQL≥5.7、Tomcat≥8
开发工具
eclipse/idea/myeclipse/sts等均可配置运行
适用
课程设计,大作业,毕业设计,项目练习,学习演示等
功能说明
基于javaweb+mysql的JSP+Servlet考试系统(java+jsp+bootstrap+servlet+mysql)
项目介绍
本系统分为两个角色,一个是考生,一个是管理员, 考生功能如下: 登录、选择考试科目、选择考卷、在线考试、提交试卷、并且查询自己的考试成绩
管理员功能如下: 登录、添加试卷、并且添加试卷里的题目、编辑科目、还可以查询所有考生的成绩
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS; 5.数据库:MySql 5.7版本; 6.是否Maven项目: 否;查看源码目录中是否包含pom.xml;若包含,则为maven项目,否则为非maven项目
技术栈
- 后端:servlet 2. 前端:JSP+bootstrap+jQuery
使用说明
- 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件; 2. 使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven; 若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行; 3. 将项目中db.properties配置文件中的数据库配置改为自己的配置; 4. 运行项目,在浏览器中输入http://localhost:8080/ 登录
//根据ID删除数据
int result = BusinessService.deleteById(sub_id);
if (result == 1){
MrksUtils.responseWriteJson(resp, "{\"success\":\"YES\"}");
}else{
MrksUtils.responseWriteJson(resp, "{\"success\":\"NO\"}");
}
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String action = req.getParameter("sub");
if (action!=null){
if (action.equals("kmbj")){ //获取科目编辑首页
req.getRequestDispatcher("/editSubject.jsp").forward(req, resp);
}else if (action.equals("getSubject") ){ //获取科目分页列表
//easyui datagrid组件传递过来的参数page代表当前页,默认1
String pageStr = req.getParameter("page");
//easyui datagrid组件传递过来的参数row代表每页显示多少行,我们设置为10
String rowStr = req.getParameter("rows");
//转换String为Integer,之所以这里不适用int是因为在某些特定情况下参数获取为null,
//使用Integer避免了空指针异常,这是一个有趣的小技巧
Integer page = Integer.parseInt(pageStr);
Integer row = Integer.parseInt(rowStr);
//获取总共有多少行数据
Long count = BusinessService.getSubCount();
//计算出page的计算出当前页数从多少航开始,理解这句话,需要了解MySql分页查询语句
if (page > 0){
page = (page-1)*row;
}
//把page与row作为参数传递,最终实现分页查询
List<Map<String, String>> model = BusinessService.getSubPage(page, row);
String result = null;
try {
//这里写了一个方法,向前台返回Easyui datagrid组件需要的Json模型
result = MrksUtils.getEasyUIDataGridModel(model, count);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//这里写了一个方法,使用response把Json返回给客户端
MrksUtils.responseWriteJson(resp, result);
}
}
}
/* (non-Javadoc)
@OnOpen
public void onOpen(Session session,EndpointConfig config) throws IOException{
//WebSocket Session
this.session = session;
webSocketSet.add(this);
//Servlet Application context
context = (ServletContext)config.getUserProperties().get(ServletContext.class.getName());
//Servlet Session
httpSession = (HttpSession)config.getUserProperties().get(HttpSession.class.getName());
//获取Session里的用户信息
Map<String,Object> userInfoMap = (Map<String,Object>)httpSession.getAttribute("userInof");
//把当前用户的的的连接对象存入Context
String 用户名 = (String)userInfoMap.get(UserInfo.用户名.toString());
context.setAttribute(用户名, this);
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(){
//断开连接,如果断开连接我们需要把用户答题数据持久化
//1、清除context里的属性对象
//2、理想状态下计算分数
//3、
try {
context.removeAttribute((String)httpSession.getAttribute(UserInfo.用户名.toString()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
//用户答题时,每次回答一道题都会发送一条信息与服务器通信,这里接收用户发过来的信息。
if (message != null){
switch (message) {
//case 1 从这步开始考试正式开始。
case "start":
Map<String, String[]> parmMap = req.getParameterMap();
for (Entry<String, String[]> entry:parmMap.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue()[0]);
}
}
}
public class SystemLogin extends HttpServlet {
private static final SystemService 系统服务= new SystemService();
/**
* Constructor of the object.
*/
public SystemLogin() {
super();
}
/**
* Destruction of the servlet. <br>
*/
@Override
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
@ServerEndpoint(value = "/mysocketTest",configurator=BaseContext.class)
public class MySocket2 {
private static final long serialVersionUID = 79990006013872453L;
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static CopyOnWriteArraySet<MySocket2> webSocketSet = new CopyOnWriteArraySet<MySocket2>();
public static java.util.concurrent.ConcurrentHashMap<String , String> useronline = new java.util.concurrent.ConcurrentHashMap<String , String>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private ServletContext context = null;
private HttpSession httpSession = null;
/**
* 连接建立成功调用的方法
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
* @throws IOException
*/
@OnOpen
public void onOpen(Session session,EndpointConfig config) throws IOException{
//WebSocket Session
this.session = session;
webSocketSet.add(this);
//Servlet Application context
context = (ServletContext)config.getUserProperties().get(ServletContext.class.getName());
//Servlet Session
pageStr = "1";
}
if (rowStr == null) {
rowStr = "100";
}
Integer page = Integer.parseInt(pageStr);
Integer row = Integer.parseInt(rowStr);
Integer tempPage = 0;
if (page > 0) {
tempPage = (page - 1) * row;
}
List<Map<String, String>> ksfs = BusinessService.getKsfs(
username, tempPage, row);
Long count = BusinessService.getInfoCount(username);
// 分页
Integer lastPage = 0;
if (count % row > 0) {
lastPage = Integer.parseInt((count / row + 1) + "");
} else {
lastPage = Integer.parseInt((count / row) + "");
}
String HtmlPage = Util.page(page, lastPage);
req.setAttribute("HtmlPage", HtmlPage);
req.setAttribute("ksfs", ksfs);
req.getRequestDispatcher("WEB-INF/view/chaxun.jsp").forward(
req, resp);
} else if ("gocx".equals(action)) {
req.getRequestDispatcher("/actionKfcx.jsp").forward(req, resp);
}else if("aaa".equals(action)){
//拿到考试成绩数据
String pageStr = req.getParameter("page");
String rowStr = req.getParameter("rows");
if (pageStr == null) {
pageStr = "1";
}
if (rowStr == null) {
rowStr = "100";
}
Integer 答案编码 = MrksUtils.statistics(check.toArray(new String[check.size()]));
BusinessService.InsertQuestionAndAnswers(问题标题, 问题类型, 分数, 答案编码, 外键, daanMap);
//parent.location.href='question?que=sjbj'
}
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPut(req, resp);
}
}
/**
* The beault of the code
*
*
* 设计思想
Map<String, String[]> parmMap = req.getParameterMap();
for (Entry<String, String[]> entry:parmMap.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue()[0]);
}
}
}
public class SystemLogin extends HttpServlet {
private static final SystemService 系统服务= new SystemService();
/**
* Constructor of the object.
*/
public SystemLogin() {
super();
}
/**
* Destruction of the servlet. <br>
*/
@Override
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
/**
* The beauty of the code
*
*
*/
public class ActionQuestionServlet extends HttpServlet {
/*
* (non-Javadoc)
*
* @see
* javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest
* , javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doDelete(req, resp);
}
/*
* (non-Javadoc)
*
* @see
* javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
* , javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String action = req.getParameter("act");
HttpSession session = req.getSession();
if (null != session.getAttribute("userInof")) {
if ("action".equals(action)) {
// 获取完整试卷
String main_id = req.getParameter("main_id");
Map<String, Object> questions = BusinessService
Timekeeping timekeeping = new Timekeeping(target,session);
Thread thread = new Thread(timekeeping);
//启动线程
thread.start();
break;
//case 2 这里预期效果是用户每次选择答案都保存在内存当中
case "question":
//case 3 用户关闭了浏览器,会向服务器发送一条数据,这里可做持久化算分处理
case "close":
System.out.println("关闭连接");
onClose();
default:
break;
}
}
}
/**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
//发生连接异常时
}
/**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
//向客户机发送消息,如果计时完毕会向客户机发送一个状态,告诉客户机时间到了,需要提交试卷。
this.session.getBasicRemote().sendText(message);
}
}
Timekeeping timekeeping = new Timekeeping(target,session);
Thread thread = new Thread(timekeeping);
//启动线程
thread.start();
break;
//case 2 这里预期效果是用户每次选择答案都保存在内存当中
case "question":
//case 3 用户关闭了浏览器,会向服务器发送一条数据,这里可做持久化算分处理
case "close":
System.out.println("关闭连接");
onClose();
default:
break;
}
}
}
/**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
//发生连接异常时
}
/**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
//向客户机发送消息,如果计时完毕会向客户机发送一个状态,告诉客户机时间到了,需要提交试卷。
this.session.getBasicRemote().sendText(message);
}
}
* Constructor of the object.
*/
public RegisterServlet() {
super();
}
/**
* Destruction of the servlet. <br>
*/
@Override
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter wr=response.getWriter();
//获取用户名
public class RegisterServlet extends HttpServlet {
/**
* Constructor of the object.
*/
public RegisterServlet() {
super();
}
/**
* Destruction of the servlet. <br>
*/
@Override
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
/**
* The beauty of the code
*
*
*/
public class ActionQuestionServlet extends HttpServlet {
/*
* (non-Javadoc)
*
* @see
* javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest
* , javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doDelete(req, resp);
}
/*
* (non-Javadoc)
*
* @see
* javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
* , javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String rowStr = req.getParameter("rows");
//转换String为Integer,之所以这里不适用int是因为在某些特定情况下参数获取为null,
//使用Integer避免了空指针异常,这是一个有趣的小技巧
Integer page = Integer.parseInt(pageStr);
Integer row = Integer.parseInt(rowStr);
//获取总共有多少行数据
Long count = BusinessService.getSubCount();
//计算出page的计算出当前页数从多少航开始,理解这句话,需要了解MySql分页查询语句
if (page > 0){
page = (page-1)*row;
}
//把page与row作为参数传递,最终实现分页查询
List<Map<String, String>> model = BusinessService.getSubPage(page, row);
String result = null;
try {
//这里写了一个方法,向前台返回Easyui datagrid组件需要的Json模型
result = MrksUtils.getEasyUIDataGridModel(model, count);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//这里写了一个方法,使用response把Json返回给客户端
MrksUtils.responseWriteJson(resp, result);
}
}
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
String 科目 = req.getParameter(BusinessSubject.科目.toString());
String action = req.getParameter("action");
if ("add".equals(action)){
int isResult = BusinessService.insert(科目);
if (isResult == 1){
MrksUtils.responseWriteJson(resp, "{\"success\":\"YES\"}");
}else{
*设计思想
*
* 这个类处理考试科目,主要功能有分页,增加,修改,删除
*
*1、分页采用easyui的datagrid组件,默认传递参数page,row
*
*/
public class BusinessSubjectServlet extends HttpServlet{
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取ID
String sub_id = req.getParameter(BusinessSubject.ID.toString());
//根据ID删除数据
int result = BusinessService.deleteById(sub_id);
if (result == 1){
MrksUtils.responseWriteJson(resp, "{\"success\":\"YES\"}");
}else{
MrksUtils.responseWriteJson(resp, "{\"success\":\"NO\"}");
}
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String action = req.getParameter("sub");
if (action!=null){
if (action.equals("kmbj")){ //获取科目编辑首页
req.getRequestDispatcher("/editSubject.jsp").forward(req, resp);
}else if (action.equals("getSubject") ){ //获取科目分页列表
//easyui datagrid组件传递过来的参数page代表当前页,默认1
String pageStr = req.getParameter("page");
//easyui datagrid组件传递过来的参数row代表每页显示多少行,我们设置为10
String rowStr = req.getParameter("rows");
//转换String为Integer,之所以这里不适用int是因为在某些特定情况下参数获取为null,
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to
* post.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
@Override
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
res.setCharacterEncoding("utf-8");
PrintWriter out = res.getWriter();
String 用户名 = req.getParameter("USERNAME");
System.out.println(用户名);
String 密码 = req.getParameter(UserInfo.密码.toString());
System.out.println(密码);
Map<String, Object> userInfoMap = 系统服务.selectUserInfoBy用户名(用户名);
if (userInfoMap != null){
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to
* post.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
@Override