基于javaweb+mysql的jsp+servlet考试系统(java+jsp+bootstrap+servlet+mysql)

基于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项目

技术栈

  1. 后端:servlet 2. 前端:JSP+bootstrap+jQuery

使用说明

  1. 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件; 2. 使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven; 若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行; 3. 将项目中db.properties配置文件中的数据库配置改为自己的配置; 4. 运行项目,在浏览器中输入http://localhost:8080/ 登录

	
	
}
package com.mrkj.ygl.servlet3.business;

/**
 * The beauty of the code
 * 
 *
 */
public class BusinessMainServlet 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("main");
		//返回试卷编辑
		if("getMain".equals(action)){
														//easyui datagrid组件传递过来的参数page代表当前页,默认1
			String pageStr = req.getParameter("page");
														//easyui datagrid组件传递过来的参数row代表每页显示多少行,我们设置为10
			String rowStr = req.getParameter("rows");
														//转换String为Integer,之所以这里不适用int是因为在某些特定情况下参数获取为null,
														//使用Integer避免了空指针异常,这是一个有趣的小技巧
			}
		}
	}

	/**
	 * Initialization of the servlet. <br>
	 * 
	 * @throws ServletException
	 *             if an error occurs
	 */
	@Override
	public void init() throws ServletException {
		// Put your code here
	}

}
package com.mrkj.ygl.servlet3.system;

public class RegisterServlet extends HttpServlet {

	/**
	 * Constructor of the object.
	 */
	public RegisterServlet() {
		super();
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	@Override
				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);
        
    }
}
package com.mrkj.ygl.servlet3.business;

/**
 * The beauty of the code
				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);
        
    }
 
}
package com.mrkj.ygl.servlet3.business;

				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 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(
						"admin2", tempPage, row);
				Long count = BusinessService.getInfoCount("admin2");
				// 分页
			
			if (答案2正确!=null){
				check.add(UUID2);
			}
			
			if (答案3正确!=null){
				check.add(UUID3);
			}
			
			if (答案4正确!=null){
				check.add(UUID4);
			}
			//List转换为String[],这里我们使用的是答案编码,答案编码的实现是通过UUID生成字符串,
			//转换为char[],把char[]里的每一个元素转换为对应的ascⅡ码,把ascⅡ码相加得出答案编码
			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);
	}

}
package com.mrkj.ygl.socket;


/**
 * The beauty of the code
 * 
 *
 */
public class BusinessMainServlet 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("main");
		//返回试卷编辑
		if("getMain".equals(action)){
														//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.getMainCount();
														//计算出page的计算出当前页数从多少航开始,理解这句话,需要了解MySql分页查询语句
			if (page > 0){
				page = (page-1)*row;
			}
														//把page与row作为参数传递,最终实现分页查询
			List<Map<String, String>> model = BusinessService.getMain(page, row);
			
			String result = null;
public class BusinessMainServlet 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("main");
		//返回试卷编辑
		if("getMain".equals(action)){
														//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.getMainCount();
														//计算出page的计算出当前页数从多少航开始,理解这句话,需要了解MySql分页查询语句
			if (page > 0){
				page = (page-1)*row;
			}
														//把page与row作为参数传递,最终实现分页查询
			List<Map<String, String>> model = BusinessService.getMain(page, row);
			
			String result = null;
			try {
														//这里写了一个方法,向前台返回Easyui datagrid组件需要的Json模型
				result = MrksUtils.getEasyUIDataGridModel(model, count);
			} catch (Exception e) {
				e.printStackTrace();
			}
														//这里写了一个方法,使用response把Json返回给客户端
			MrksUtils.responseWriteJson(resp, result);
		}else{
			req.getRequestDispatcher("WEB-INF/view/main.jsp").forward(req, resp);
		}
	}

	/* (non-Javadoc)
			String result = null;
			try {
														//这里写了一个方法,向前台返回Easyui datagrid组件需要的Json模型
			result = MrksUtils.getEasyUIDataGridModel(model, count);
			} catch (Exception e) {
			
			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
		
		resp.setContentType("text/html");
		
		resp.setCharacterEncoding("UTF-8");
		String action = req.getParameter("action");
		
		
		PrintWriter   wr=resp.getWriter();
		if ("add".equals(action)){		//增加问题
			
			String 问题标题 = req.getParameter(BusinessQuestion.问题标题.toString());  //问题元素
			String 问题类型 = req.getParameter(BusinessQuestion.问题类型.toString());	//问题元素
			String 分数 = req.getParameter(BusinessQuestion.分数.toString());	//问题元素
			String 外键 = req.getParameter(BusinessQuestion.外键.toString());	//问题元素
			
			String 答案1 = req.getParameter("DAAN1");		//答案元素
			String 答案2 = req.getParameter("DAAN2");		//答案元素
			String 答案3 = req.getParameter("DAAN3");		//答案元素
			String 答案4 = req.getParameter("DAAN4");		//答案元素
			String 答案1正确 = req.getParameter("DAAN1CHECK");		//计算答案编码
			String 答案2正确 = req.getParameter("DAAN2CHECK");		//计算答案编码
			String 答案3正确 = req.getParameter("DAAN3CHECK");		//计算答案编码
			String 答案4正确 = req.getParameter("DAAN4CHECK");		//计算答案编码
			List<String> check = new ArrayList<>();
			Map<String,String> daanMap= new HashMap<>();
			
			String UUID1 = UUID.randomUUID().toString();
			daanMap.put(UUID1, 答案1);
			String UUID2 = UUID.randomUUID().toString();
			daanMap.put(UUID2, 答案2);
			String UUID3 = UUID.randomUUID().toString();
			daanMap.put(UUID3, 答案3);
			String UUID4 = UUID.randomUUID().toString();

/**
 * The beault of the code
 * 
 *
 *	设计思想
 *
 *1、WebSocket 是在HTML 5支持的通信协议,实现客户端与服务端的长连接。
 *
 *2、考试时间计算方式是,本地倒计时与服务器端同时计时,这样做考虑到网络延迟因素,不单方面的依赖任何一端的计时。计时终止时试卷提交。
 *
 *3、客户端每次答题都会与服务器通信,服务器会记录这个答题者的答题记录,记录存在内存当中,并没有持久化,触发持久化条件有以下几种。
 *
 *	A:用户手动提交试卷
 *	B:用户断开连接
 *	C:用户关闭网页
 *	
 *4、
 *
 *
 */
@ServerEndpoint(value = "/mysocket",configurator=BaseContext.class)
public class MySocket {
    
	private static final long serialVersionUID = 79990006013872453L;
	
	//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    
    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    private static CopyOnWriteArraySet<MySocket> webSocketSet = new CopyOnWriteArraySet<MySocket>();
    public static java.util.concurrent.ConcurrentHashMap<String , String> useronline = new java.util.concurrent.ConcurrentHashMap<String , String>();
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    private ServletContext context = null;
 * 
 * 
 *
 */

public class SystemLogin extends HttpServlet{

	private static final SystemService 系统服务= new SystemService();
	
	/* (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 {

		Map<String, String[]> parmMap = req.getParameterMap();
		for (Entry<String, String[]> entry:parmMap.entrySet()){
			System.out.println(entry.getKey()+":"+entry.getValue()[0]);
		}
	}

	/* 
	 *	
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		HttpSession session = req.getSession();
		if (session.getAttribute(UserInfo.用户名.toString())!=null){
			req.getRequestDispatcher("WEB-INF/view/main.jsp").forward(req, resp);
		}else{
			resp.sendRedirect("login.jsp?msg=1");
		}
	}

	/* The beauty of the code
	 * 
	 * 
	 * 
	 */
	@SuppressWarnings("unused")
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		String 用户名 = req.getParameter(UserInfo.用户名.toString());
		String 密码 = req.getParameter(UserInfo.密码.toString());
		
		Map<String, Object> userInfoMap = 系统服务.selectUserInfoBy用户名(用户名);
		if (userInfoMap != null){
			String 取出的密码 = (String)userInfoMap.get(UserInfo.密码.toString());
			if (密码!=null&&密码.equals(取出的密码)){
				req.getSession().setAttribute("userInof", userInfoMap);
			}
        }
    }
    /**
     * 发生错误时调用
     * @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);
        
    }
}
package com.mrkj.ygl.servlet3.business;

/**
 * The beauty of the code
 * 
 *
 *设计思想
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		String action = req.getParameter("que");
		//返回试卷编辑
		if ("sjbj".equals(action)){
			req.setAttribute("AllSubject", BusinessService.getAllSubPage());
			req.getRequestDispatcher("/editQuestion.jsp").forward(req, resp);
		}else if("getQuestion".equals(action)){
														//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.getQueCount();
														//计算出page的计算出当前页数从多少航开始,理解这句话,需要了解MySql分页查询语句
			if (page > 0){
				page = (page-1)*row;
			}
														//把page与row作为参数传递,最终实现分页查询
			List<Map<String, String>> model = BusinessService.getQuestion(page, row);
			
			String result = null;
			try {
														//这里写了一个方法,向前台返回Easyui datagrid组件需要的Json模型
			result = MrksUtils.getEasyUIDataGridModel(model, count);
			} catch (Exception e) {
			
			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
		
		resp.setContentType("text/html");
 *
 */
@ServerEndpoint(value = "/mysocket",configurator=BaseContext.class)
public class MySocket {
    
	private static final long serialVersionUID = 79990006013872453L;
	
	//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    
    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    private static CopyOnWriteArraySet<MySocket> webSocketSet = new CopyOnWriteArraySet<MySocket>();
    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
        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(){
					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);
        
    }
}
package com.mrkj.ygl.servlet3.business;

/**
 * The beauty of the code
 * 
     * 连接建立成功调用的方法
     * @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
        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) {
	public static String md5(String str) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(str.getBytes());
			byte b[] = md.digest();

			int i;

			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			str = buf.toString();
		} catch (Exception e) {
			e.printStackTrace();

		}
		return str;
	}
	
	
	public static String TrasformDateToString (Date date){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		
		if (date != null){
			return sdf.format(date);
		}else{
			return null;
		}
	}
	
	public static String TrasformGetimeToString (Long date){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		
		if (date != null){
			return sdf.format(new Date(date));
		}else{
			return null;
		}
	}
}
		Map<String, Object> resultMap = new HashMap<String, Object>();
		ObjectMapper om = new ObjectMapper();
		resultMap.put("rows", model);
		resultMap.put("total", count);
		return om.writeValueAsString(resultMap);
	}
	
	public static void responseWriteJson(HttpServletResponse resp,String result){
		resp.setCharacterEncoding("UTF-8");
		resp.setContentType("application/json; charset=utf-8");
		try {
			resp.getWriter().print(result);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 根据 ans_id 获取答案吗
	 * @param ans_id
	 * @return
	 */
	public static int statistics (String ...ans_id){
		
		StringBuffer sb = new StringBuffer("");
		
		for (String id : ans_id){
			sb.append(id);
		}
		
		char[] cArr = sb.toString().toCharArray();
		
		int result = 0;
		
		for (char c : cArr){
			result += c+0;
		}
		
		return result;
	}

	public static String md5(String str) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(str.getBytes());
			byte b[] = md.digest();

			int i;

			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
 */
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
						.getAllQuestion(main_id);
				req.setAttribute("questions", questions);

				session.setAttribute(BusinessMain.答题时间.toString(),
						questions.get(BusinessMain.答题时间.toString()));
				req.getRequestDispatcher("/WEB-INF/view/kaoshi.jsp").forward(
						req, resp);
			} else if ("kskm".equals(action)) {
				// 获取所有科目
				List<Map<String, String>> subjects = BusinessService
						.getAllSubPage();
				req.setAttribute("subjects", subjects);
        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":
				//httpSession中存放了当前试卷的时间
				String time = (String)httpSession.getAttribute(BusinessMain.答题时间.toString());
				//分钟计算 这里是一个小时,考虑到网络延迟,这里多加了3秒,JS计时正常计算
				Long targetMinute = 1000L*60L*Long.parseLong(time);//1000L*60L*60L+3000L;
				//获取当前时间,用当前时间+上预期分钟,得到考试结束时间
				Date curretn = new Date();
				
				Long target = curretn.getTime()+targetMinute;
				
				//开始考试 ,倒计时开始时,会向客户端发送一个start状态标记,客户端使用js计时也同步开始。
				//结束考试,计时结束,会向客户端发送一个end状态吧iaoji,客户端使用js提交表单,完成一次考试。
	@Override
	public void init() throws ServletException {
		// Put your code here
	}

}
package com.mrkj.ygl.util;

public class MrksUtils {

	public static String getEasyUIDataGridModel(List<Map<String, String>> model,Long count) throws Exception{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		ObjectMapper om = new ObjectMapper();
		resultMap.put("rows", model);
		resultMap.put("total", count);
		return om.writeValueAsString(resultMap);
	}
	
	public static void responseWriteJson(HttpServletResponse resp,String result){
		resp.setCharacterEncoding("UTF-8");
		resp.setContentType("application/json; charset=utf-8");
		try {
			resp.getWriter().print(result);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 根据 ans_id 获取答案吗
	 * @param ans_id
	 * @return
	 */

		String action = req.getParameter("main");
		//返回试卷编辑
		if("getMain".equals(action)){
														//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.getMainCount();
														//计算出page的计算出当前页数从多少航开始,理解这句话,需要了解MySql分页查询语句
			if (page > 0){
				page = (page-1)*row;
			}
														//把page与row作为参数传递,最终实现分页查询
			List<Map<String, String>> model = BusinessService.getMain(page, row);
			
			String result = null;
			try {
														//这里写了一个方法,向前台返回Easyui datagrid组件需要的Json模型
				result = MrksUtils.getEasyUIDataGridModel(model, count);
			} catch (Exception e) {
				e.printStackTrace();
			}
														//这里写了一个方法,使用response把Json返回给客户端
			MrksUtils.responseWriteJson(resp, result);
		}else{
			req.getRequestDispatcher("WEB-INF/view/main.jsp").forward(req, resp);
		}
	}

	/* (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 action = req.getParameter("action");
		
		if ("add".equals(action)){
			String ID = UUID.randomUUID().toString();
			String 标题 = req.getParameter(BusinessMain.标题.toString());
			String 外键 = req.getParameter(BusinessMain.外键.toString());
    @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":
				//httpSession中存放了当前试卷的时间
				String time = (String)httpSession.getAttribute(BusinessMain.答题时间.toString());
				//分钟计算 这里是一个小时,考虑到网络延迟,这里多加了3秒,JS计时正常计算
				Long targetMinute = 1000L*60L*Long.parseLong(time);//1000L*60L*60L+3000L;
				//获取当前时间,用当前时间+上预期分钟,得到考试结束时间
		resp.setCharacterEncoding("UTF-8");
		String action = req.getParameter("action");
		
		
		PrintWriter   wr=resp.getWriter();
		if ("add".equals(action)){		//增加问题
			
			String 问题标题 = req.getParameter(BusinessQuestion.问题标题.toString());  //问题元素
			String 问题类型 = req.getParameter(BusinessQuestion.问题类型.toString());	//问题元素
			String 分数 = req.getParameter(BusinessQuestion.分数.toString());	//问题元素
			String 外键 = req.getParameter(BusinessQuestion.外键.toString());	//问题元素
			
			String 答案1 = req.getParameter("DAAN1");		//答案元素
			String 答案2 = req.getParameter("DAAN2");		//答案元素
			String 答案3 = req.getParameter("DAAN3");		//答案元素
			String 答案4 = req.getParameter("DAAN4");		//答案元素
			String 答案1正确 = req.getParameter("DAAN1CHECK");		//计算答案编码
			String 答案2正确 = req.getParameter("DAAN2CHECK");		//计算答案编码
			String 答案3正确 = req.getParameter("DAAN3CHECK");		//计算答案编码
			String 答案4正确 = req.getParameter("DAAN4CHECK");		//计算答案编码
			List<String> check = new ArrayList<>();
			Map<String,String> daanMap= new HashMap<>();
			
			String UUID1 = UUID.randomUUID().toString();
			daanMap.put(UUID1, 答案1);
			String UUID2 = UUID.randomUUID().toString();
			daanMap.put(UUID2, 答案2);
			String UUID3 = UUID.randomUUID().toString();
			daanMap.put(UUID3, 答案3);
			String UUID4 = UUID.randomUUID().toString();
			daanMap.put(UUID4, 答案4);
			if (答案1正确!=null){
				check.add(UUID1);
			}
			
			if (答案2正确!=null){
				check.add(UUID2);
			}
			
			if (答案3正确!=null){
				check.add(UUID3);
			}
			
			if (答案4正确!=null){
				check.add(UUID4);
			}
     * 发生错误时调用
     * @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);
        
    }
}
package com.mrkj.ygl.servlet3.business;

/**
 * The beauty of the code
 * 
 *
 *设计思想
 *
 *	这个类处理考试科目,主要功能有分页,增加,修改,删除
		resp.setContentType("application/json; charset=utf-8");
		try {
			resp.getWriter().print(result);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 根据 ans_id 获取答案吗
	 * @param ans_id
	 * @return
	 */
	public static int statistics (String ...ans_id){
		
		StringBuffer sb = new StringBuffer("");
		
		for (String id : ans_id){
			sb.append(id);
		}
		
		char[] cArr = sb.toString().toCharArray();
		
		int result = 0;
		
		for (char c : cArr){
			result += c+0;
		}
		
		return result;
	}

	public static String md5(String str) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(str.getBytes());
			byte b[] = md.digest();

			int i;

			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)

请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

基于JavaWeb Servlet+JSP的量表系统可以通过以下步骤实现: 1.创建数据库表格,包括量表信息、题目信息、选项信息和用户答题记录信息等。 2.使用Servlet实现用户登录、注册、修改密码等功能。 3.使用JSP实现量表列表展示、量表详情展示、答题页面展示等功能。 4.使用ServletJSP实现用户答题记录的增加、查询、修改和删除等功能。 5.使用Bootstrap等前端框架美化页面,提高用户体验。 以下是一个简单的基于JavaWeb Servlet+JSP的量表系统的代码示例: 引用:基于JavaWeb Servlet+JSP+MYSQL+Bootstrap 文章管理系统 基于JavaWeb Servlet+JSP+MYSQL+Bootstrap 文章管理系统 基于JavaWeb Servlet+JSP+MYSQL+Bootstrap 文章管理系统 基于JavaWeb Servlet+JSP+MYSQL+Bootstrap ... 引用: ```java <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>量表详情</title> </head> <body> <h1>量表详情</h1> <table> <tr> <td>量表名称:</td> <td>${scale.name}</td> </tr> <tr> <td>量表描述:</td> <td>${scale.description}</td> </tr> <tr> <td>题目列表:</td> <td> <table> <c:forEach items="${scale.questions}" var="question"> <tr> <td>${question.content}</td> <td> <c:forEach items="${question.options}" var="option"> <input type="radio" name="${question.id}" value="${option.id}">${option.content} </c:forEach> </td> </tr> </c:forEach> </table> </td> </tr> </table> <form action="submit" method="post"> <input type="hidden" name="scaleId" value="${scale.id}"> <input type="submit" value="提交"> </form> </body> </html> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值