java毕业设计——基于java+J2EE+sqlserver的SMART在线考试系统设计与实现(毕业论文+程序源码)——在线考试系统

基于java+J2EE+sqlserver的SMART在线考试系统设计与实现(毕业论文+程序源码)

大家好,今天给大家介绍基于java+J2EE+sqlserver的SMART在线考试系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦。需要下载开题报告PPT模板及论文答辩PPT模板等的小伙伴,可以进入我的博客主页查看左侧最下面栏目中的自助下载方法哦

文章目录:

1、项目简介

  1. 拥有一套适合校情的在线考试评估系统、将信息技术用于校务管理评估中便是迫切的要求。SMART系统是一个在线考试信息管理系统,该系统主要实现了学生在线考试与评估以及教师对学生在线考试信息的管理和维护。
  2. 本文涉及到的公共资源模块,它作为SMART项目的一个组成部分,占有十分重要的作用,它是后面所有模块的基础,这个模块的设计质量关系到整个系统的开发质量。为保持系统的先进性、灵活性、安全性和扩展性,模块采用MVC架构以及Struts、Spring、Jsp、Hibernate等等一些目前流行的技术和组件。整个模块包括地区资源、教务资源、试题资源、试卷资源等功能模块。通过这些模块的应用,可以满足SMART系统的公共需求,对SMART系统的应用和发展起到一定的促进作用。


2、资源详情

项目难度:中等难度
适用场景:相关题目的毕业设计
配套论文字数:13419个字33页
包含内容:整套源码+完整毕业论文


3、关键词

个统计评估;Struts;Jsp;Hibernate;Spring

4、毕设简介

提示:以下为毕业论文的简略介绍,项目源码及完整毕业论文下载地址见文末。

引言
1.1课题起源
随着社会的发展,计算机的普及,将教育产业信息化成为可能而且这种呼声也越来越高,传统的考试、统计、评估、管理工作也越来越显的繁重和笨拙,传统的这些操作,即费时又费力,而且容易出错,工作效率较低,并且不管统计、评估还是管理工作合理性都不好。因此,拥有一套实用、高效、完善的评估管理软件就显得尤为重要了,它可以提升学校的教育质量和教学管理质量,提高工作效率,降低行政成本。
SMART在线考试系统目的是为中小学生提供在线考试、在线评估的智能化平台,并为学校、主管部门教学评估、教学质量控制提供决策依据。该软件系统内含在线考试评估子系统。本软件产品是一项独立的软件,而且全部内容自含。

1.2课题目的
设计一套符合中小学生实际情况、完整统一、技术先进、高效稳定、安全可靠的基于C/S架构的智能化的在线考试、在线评估的系统,并为学校、主管部门教学评估、教学质量控制提供决策依据的一个平台。

1.3课题意义
作为在中小学生,在线考试系统更趋于公证、客观、针对性,更能激发学生的学习兴趣和热情;作为老师,大大减轻了出卷,阅卷,评卷,以及统计,评估、管理等等工作负担,从而大大提高了工作效率。

2 系统实现架构环境与技术说明
2.1系统架构
系统在选用结构的时候,有B/S、C/S、Smart Client(智能客户端)三种可能的方案。它们各有各的优缺点。
 B/S架构
B/S架构的优点在于客户端和服务器通过Intranet进行数据交换,客户端基于统一的WEB浏览器,减少了投资,解决了系统维护升级的问题,另外只有极少部分事务逻辑在前端(Browser)实现,但是主要事务逻辑在服务器端(Server)实现,这也就充分保护了数据的安全。虽然如此,B/S结构还是有很多的不足,其中最大的缺点是在界面操作上具有很大局限性,用起来很难,开发起来也很费钱。
 C/S架构
采用C/S结构可以减轻服务器运行数据负荷,数据的储存管理也较为透明,最重要的是开发较为迅速。而它的缺点也是不少,它会造成高昂的维护成本,且投资大,维护不方便。在实际开发中,部署不如B/S方便。但由于它能快速开发出较为使用的用户界面,而且可以将部分运算转移到客户端来,所以是一个值得考虑的方案。
 Smart Client
Smart Client是下一代客户端软件的代表,它可以充分利用终端设备的优势(Full PC、PDA、Phone)、能够调用Web Service、支持在线和离线两种状态、能够如同Web应用程序一般简单方便的部署。由于这套系统的目标客户是教务处负责排课的老师,因此它不会涉及到对终端设备的支持,但是方便部署这一点确实需要的,因为这正是C/S的缺点。

2.2系统实现环境和技术
2.2.1开发环境
 集成开发环境: JDK5.0+Eclipse3.1+MyEclipse4.0+Tomcat5.5.15 + SQLServer
 开发语言: Java、SQL

2.2.2 运行环境
 服务器操作系统:Windows server
 应用服务器系统:tomcat5.0+jre5.0
 数据库管理系统:SQL Server
 客户端操作系统:Windows任意版本
 客户端浏览器:Microsoft IE5.0以上

2.3系统框架说明
Smart 在线考试项目(以下简称“Smart”),将在struts+sprintg 管理的hibernate作为平台框架搭建具体的Smart在线考试业务系统。

采用struts MVC框架主要用于将Smart的数据流和业务流分开,采用hibernate,主要用于更高效率对数据库存取效率及提高项目开发效率。采用spring管理的hibernate主要主要是获得Spring对Hibernate的支持,获得更高的开发效率和更高的Hibernate操作性能。并能获得Spring相关的事务支持。之所以不完全用Spring框架是考虑项目组的技术水平可能不足以完全驾驭这样的框架规范。所以本系统不属于标准的Struts + Spring + Hibernate的标准J2EE应用。具体框架版本:Struts 1.2 + hibernate 2.1。

对于Hibernate的数据库IO操作,将采用DAO模式将操作封装至DAO对象中。而将建立专门的业务层,对WEB层及其他子模块或类进行接口。

2.3.1 struts 介绍
省略

2.3.2 理解MVC设计模式
省略

2.3.3 spring 介绍
省略

2.3.4 hibernate组件介绍
省略

2.3.5 jsp组件介绍
省略

2.3.6 SQL Server 介绍
省略

2.3.7 Tomcat介绍
省略

3 功能需求分析
3.1功能需求
3.1.1 公共资源管理
公共资源管理模块涉及到省、市、县/区、乡/镇、村、学校、年级、班级等基本信息的设置(其中乡/镇、村是动态的,用户可以根据具体情况设置或者不设置)。用户可通过它实现添加、删除、修改省、市、县/区、乡/镇、村、学校、年级、班级的基本信息。

3.1.2 教务资源管理
教务资源管理具体包括课程设置,教科书设置,章节设置,知识点设置。用户可以对课程,教科书,章节,知识点等进行添加,删除,修改等操作。还可以对知识点进行搜索,针对哪一个年级,哪一个课程,哪一个章节进行搜索。

3.1.3 试题资源管理
试题资源管理主要是对题目类型,答案类型,难度系数进行设置,用户可以对题目类型,答案类型,难度系数进行添加,删除,修改等操作。由于三个类型的数据相似,所以这三个类型的数据放在“code代码”一张表中。

3.1.4 试卷资源管理
试卷资源管理负责管理考试类型和试卷类型的基本信息。用户可通过它实现考试类型以及试卷类型的添加,删除,修改等操作。

3.2非功能需求
省略

4数据库设计

Smart系统—公共资源管理所使用到的所有表,一共有14张。分别是:

[1] CODE表 -存储题目类型,答案类型,试卷类型等等的信息。
表4-1 “CODE”表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5 系统模块的设计与实现
5.1系统模块的设计
5.1.1 公共资源管理模块设计
在系统的公共资源管理模块中,我们设定了八级的关系(包括:省级设置、市级设置、县/区设置、乡/镇设置、村级设置、学校设置、年级设置、班级设置)其中他们的关系是一级一级向下的。也就是只有设置了上一级别,下一个级别才能设置(其中乡/镇设置、村级设置可以根据具体情况可以设置或者不设置)。

我们画出各个级别设置详细流程图,图4-1是各个级别的设置选择。
在这里插入图片描述

图5-1 级别设置流程图解
5.1.2 教务资源管理模块设计

在这里插入图片描述

图5-2教务资源管理模块
图4-2所示的是教务资源管理具体的操作过程,用户进入分别可以对课程,教科书,章节,知识点进行添加,删除,修改操作。
5.1.3 试题资源管理模块设计

在这里插入图片描述

图5-3试题资源管理模块
图4-3所示的是试题资源管理具体的操作过程,用户进入可以分别对题目类型,难度系数,答案类型进行添加,删除,修改操作
5.1.4 试卷资源管理模块设计
图4-4所示的是试卷资源管理具体的操作过程,用户进入可以分别对考试类型,试卷类型进行添加,删除,修改操作。

在这里插入图片描述

图5-4试卷资源管理模块

5.2 系统模块的实现
各子模块的重要功能如下(只提供部分界面截图):
表5-1 系统模块
在这里插入图片描述
在这里插入图片描述

5.2.1 公共资源管理模块实现
在这里插入图片描述

图5-5 公共资源管理模块界面

(1)这是返回用户定义的编号的方法:

public String getId(String nowId,Integer maxLength){//根据数据库的编号(NO)返回用户输入的定义的NO
		 String id="";
		 Integer length=(Integer)(nowId.length())-maxLength; //从什么位置开始
		 Integer size=nowId.length();//什么地方结束
		 id=nowId.substring(length,size);//这个id就是上个级别的编号(NO)
		 return id;//返回上个级别的编号(NO)
	 }

(2)这是执行下个级别的具体操作:

/*************当执行下一步操作
,以及初始化时候执行这里*****************/
		String forward = "";
		String step = toChi ((String) request.getParameter ("step"));
		List result = typeBaseInfo(step);//得到下级别信息的list
		String str [] = step.split ("'");
		String rulename = "";
		String fathername = "";// 上一级别的名字
		String grandfather = "";// 上一级别的名字
		String maxLength = "";
		String id2 = "";
		if (str.length == 5) {
			Rulename = str[0];
			id2 = str[1];
			fathername = str[2];
			maxLength = str[3];
			grandfather = str[4];
		} else {
			return null;}
		request.getSession ().setAttribute ("rulename", rulename);
		request.getSession ().setAttribute ("fathername", fathername);
		request.getSession ().setAttribute ("grandfather", grandfather);
		request.getSession ().setAttribute ("maxLength", maxLength);
		request.getSession ().setAttribute ("id2", id2);

Action中前台得到step参数,其中,step有编号(NO),编号(NO)长度,上级别的名字(如:省级设置),这个级别的设置(如:市级设置),通过方法typeBaseInfo把下个级别的list返回到页面。具体的代码逻辑如下:

/** 根据step返回 step中rulename 级别对应的list....step中包括下一级别的名字,和这一级别的NO上级别的名字 **/
	Public List typeBaseInfo (String step) {
		List list = (List) new java.util.ArrayList ();
		Map params = new HashMap ();
		String str [] = step.split ("'");
		String rulename = "";//下个级别的名字
		String fathername = "";// 这个级别的名字
		String grandfather = "";// 上一级别的名字
		String maxLength = "";//编号(NO)的长度
		String id = "";
		if (str.length == 5) {
			Rulename = str[0];
			id = str[1];
			fathername = str[2];
			maxLength = str[3];
			grandfather = str[4];
		} else {
			return null;
		}
		Map map = new HashMap();
		map.put("id", id);
		……
		if (rulename.equals("市级设置"))
 {
			List rule = (List) this.call(new Carrier(map,
					BusinessConstants.UNITS_PUBLIC_BUSINESS, "ShowCity"));
			Iterator itClass1 = rule.iterator();
			SmartCity city = null;
			while (itClass1.hasNext())
 {
				UnitsPublicForm unitsPublicForm = new UnitsPublicForm();
				city = (SmartCity) itClass1.next();
				unitsPublicForm.setMaxlength(city.getLength());
				unitsPublicForm.setRuleclass("第2级别");
				unitsPublicForm.setRulename(rulename);
				unitsPublicForm.setRemark(city.getRemark());
				unitsPublicForm.setName (city.getCityName ());
				unitsPublicForm.setID (city.getCityNo ());
				unitsPublicForm.setNextName (city.getNextName ());
				unitsPublicForm.setLastID (city.getLastclassNo ());
				unitsPublicForm.setLastName (city.getLastName ());
				list.add (unitsPublicForm);
			}
			return list;
		}

这段代码是把城市的信息查处来后,放在UnitsPublicForm,并通过list放回。
(3)这是执行上一级别的具体操作:
通过前台得到上个级别的编号(id2),并通过编号长度(length),用ID = id2.substring(0, length2 - length1)方法得到上个级别再上个级别的编号(ID),最后通过typeBaseInfo方法得到上个级别的信息。
具体的逻辑代码参照以下:

/***************执行上一步操作的时候********************************/
String rulename = (String) request.getSession ().getAttribute ("rulename");
String fathername = (String) request.getSession().getAttribute("fathername");
String maxLength = (String) request.getSession().getAttribute("maxLength");
String id2 = (String) request.getSession ().getAttribute ("id2");
Integer maxLength1 = Integer.parseInt (maxLength);
String ID = "";	function deleteBaseInfo(str)
	{
	        var a = document.getElementsByName(str);
	  	var n = a.length;
	  	var temp="";
	  	var flag=true;
	  	for (var i=0; i<n; i++){
	  	if(a[i].checked){
	  	   flag=false;
	  	   if (temp==""){				
		   temp=a[i].value+"'";
		   }else{
	  	       temp = temp + a[i].value+"'";
	  	     }} }
	  	if(flag)
	  	{alert("对不起,你还没有选择!")}
	  	else{
	  	if (confirm("确实要删除?")){
	  	window.location.href="<%=request.getContextPath()%>/unitsTopicDifficultyAction.do?action=delete&step=two&id="+temp;
		}}
		return !flag;
	}
/*********当id2就是上级的NO,它为0时候是表示执行省级设置操作***********/
if (id2.equals("0") || fathername.equals("0") || id2.equals("")) {
	ID = "0";
	fathername = "省级设置";
	request.getSession ().setAttribute ("id2", "0");
	request.getSession().setAttribute("rulename", "省级设置");
	}else 
{
	Integer length1 = Integer.parseInt(maxLength);
	Integer length2 = id2.length();
	ID = id2.substring(0, length2 - length1);//得到上级别再上个级别的编号(ID)
	request.getSession().setAttribute("id2", ID);
	request.getSession().setAttribute("rulename", fathername);}
	List list = (List) typeBaseInfo(ID, fathername);// 查出信息表
request.getSession().setAttribute("resultList", list);// 返回到页面的list

这里的typeBaseInfo方法实现的功能是通过上个级别的编号(ID),和这个级别的设置名字(如:市级设置)返回这个级别的所有的信息。并通过list返回。具体的代码如下:

/*****根据rulename(比如“省级设置“) ,以及上个级别的id 返回这个级别的List*****/
	public List typeBaseInfo(String id, String rulename) {
		Map map = new HashMap();
		List rule = (List) new java.util.ArrayList ();
		List list = (List) new java.util.ArrayList ();
		map.put ("id", id);
       if (rulename.equals("市级设置")) {
			rule = (List) this.call(new Carrier(map,
					BusinessConstants.UNITS_PUBLIC_BUSINESS, "ShowCity"));
			Iterator itClass1 = rule.iterator();
			list = (List) new java.util.ArrayList ();
			SmartCity city = null;
			while (itClass1.hasNext ()) {
			UnitsPublicForm unitsPublicForm = new UnitsPublicForm();
			city = (SmartCity) itClass1.next ();
			unitsPublicForm.setMaxlength (city.getLength ());
			unitsPublicForm.setRuleclass("第2级别");
			unitsPublicForm.setRulename (rulename);
			unitsPublicForm.setRemark (city.getRemark ());
			unitsPublicForm.setName (city.getCityName ());
			unitsPublicForm.setID (city.getCityNo ());
			unitsPublicForm.setNextName (city.getNextName ());
			unitsPublicForm.setLastID (city.getLastclassNo ());
			unitsPublicForm.setLastName (city.getLastName ());
			list.add (unitsPublicForm);
			}
		}……

5.2.2 教务资源管理模块实现
在这里插入图片描述

图5-6教务资源管理模块界面
下面是用户添加一条具体信息的代码:
(1)Action类:

public ActionForward save(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		UnitsKnowledgeForm knowledgeForm = (UnitsKnowledgeForm) form;
		SmartKnowledgePoint entity = new SmartKnowledgePoint();
		entity.setKnowledgeNo("00"+System.currentTimeMillis());
		entity.setKnowledgeName(knowledgeForm.getPoint());
		SmartSection se = new SmartSection();
		se.setSectionNo(knowledgeForm.getSectionNo());
		entity.setSectionNo(se);
		Map map = new HashMap();
		map.put("entity", entity);
		   this.call(newCarrier(map,BusinessConstants.UNITS_KNOWLEDGE_BUSINESS,
				"SaveUnitsKnowledge"));//执行business里面的方法。
		return mapping.findForward("save");}

(2)Business类:

public void processSaveUnitsKnowledge(Carrier vo) {
		Map params = (Map) vo.getData();
		SmartKnowledgePoint entity = (SmartKnowledgePoint) params.get("entity");
		if (params != null) {
			((UnitsKnowledgeDAO) getDao()).save(entity);
		}
	}  

这一段代码是把Action中的SmartKnowledgePoint实体取出来后进一步到UnitsKnowledgeDAO类中的save的方法中执行。
(3)DAO类:

public void saveTopicEntity(Code code);
这一行的代码是通过配置文件可以执行到Impl的类的saveTopicEntity方法,并把参数code传过去。

(4)Impl类:

public void saveTopicEntity(Code code) {	
		save(code);
	}

这一行的代码是得到DAO中传过来的实体code,然后调用继承的类中的方法save保存实体code。

5.2.3 试题资源管理模块实现
在这里插入图片描述

图5-7 试题资源管理模块界面
下面是用户删除一条具体信息的代码:
(1)Action类:

public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		String step = (String) request.getParameter("step");
		String forward="";
		if("one".equals(step)){
		Map params = new HashMap();
		String id = request.getParameter("id");
		request.getSession().setAttribute("ID",id);
		params.put("ID", id);
		UnitsTopicSetBusiness topicSetBusiness = new UnitsTopicSetBusiness();  
		 this
			.call(new Carrier(params,
					BusinessConstants.UNITS_TOPIC_BUSINESS,
					"DeleteTopicById"));}	
		else if("two".equals(step)){
			Map params = new HashMap();
			String ID = request.getParameter("id");
			String str = "delete code where code_id in(" + ID + ")";
			System.out.println(ID);
			params.put("ID", ID);		
			 this
				.call(new Carrier(params,
						BusinessConstants.UNITS_TOPIC_BUSINESS,
						"deleteTopicByIdCount"));
			}
		Map params = null;
		List result = (List) this.call(new Carrier(params,
				BusinessConstants.UNITS_TOPIC_BUSINESS, "ShowTopicAnswer"));
		request.getSession().setAttribute("resultList", result);	
		return mapping.findForward("unitsTopicAnswer");
	}

这里通过request.getParameter(“id”)方法得到要删除的实体的ID,然后把这个ID返回到Business的方法中进行删除。
(2)Business类:

public void processdeleteTopicByIdCount(Carrier vo) {
		Map params = (Map) vo.getData();
		String ID = (String) params.get("ID");
		String recId[]=ID.split("'");   
		List recIdList=null;
		for(int i=0;i<recId.length;i++){     
			  String id=recId[i];
			  String str="from Code where recId='"+id+"'";
List  list=(List)((UnitsTopicSetDAO)this.getDao()).showTopicAnswer(str);
			   Iterator itClass = list.iterator();
				while(itClass.hasNext()){				
			 Code code = (Code)itClass.next();
				 ( (UnitsTopicSetDAO)this.getDao()).DeleteTopicById(code);
				 }			          }
		}

这一段代码是把封装的ID串解析后得到每个ID的值,然后根据每个ID的值删除每个实体。
这个封装的ID是在前台页面的js方法中实现的,具体代码如下:

var a = function deleteBaseInfo(str)
	{
	   var a = document.getElementsByName(str);
	  	var n = a.length;
	  	var temp="";
	  	var flag=true;
	  	for (var i=0; i<n; i++){
	  	if(a[i].checked){
	  	   flag=false;
	  	   if (temp=="") {				
		  temp=a[i].value+"'";
		   }else
	  	   {
	  	   temp = temp + a[i].value+"'";
	  	    }
	  	   }
    	 }
	  	if(flag)
	  	{alert("对不起,你还没有选择!")}
	  	else{
	  	if (confirm("确实要删除?")){
	window.location.href="<%=request.getContextPath()%>/unitsTopicDifficultyAction.do?action=delete&step=two&id="+temp;
		}}return !flag;
	}	

5.2.4 试卷资源管理模块实现
在这里插入图片描述

图5-8 试卷资源管理模块界面

下面是用户更新一条具体信息的代码:
(1)Action类:

public ActionForward update(ActionMapping mapping, ActionForm form,
	    HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		UnitsExamTypeAddForm examTypeAddForm = (UnitsExamTypeAddForm) form;
		SmartExamType examtype = (SmartExamType) request.getSession()
				.getAttribute(Constants.CACHED_ENTITY);
		examtype.setExamtypeName(examTypeAddForm.getExamtypeName());
		examtype.setExamtypeYear(examTypeAddForm.getExamtypeYear());
		examtype.setExamtypeTerm(examTypeAddForm.getExamtypeTerm());
		Map map = new HashMap();
		map.put("entity", examtype);
		this.call(new Carrier(map, BusinessConstants.UNITS_EXAMTYPE_BUSINESS,
				"UpdateExamType"));
		return mapping.findForward("update");}

这里通过得到form的属性值
(2)Business类:

public String processUpdateExamType(Carrier vop){
		Map data = vop.getData();
		SmartExamType examtype = (SmartExamType) data.get("entity");
		if(examtype != null) {
			this.getDao().update(examtype);
		}
		return examtype.getExamtypeNo();
	}

这一段代码是得到Action传过来的实体,并通过调用方法update更新这个实体。

6 测试
设计和开发占据了我大部分的精力和时间,经过反复测试,已完成系统所需的功能。系统的测试界面截图参考上面系统功能设计部分的图片。

单元测试:在开发系统的过程中,对所有代码的正确性和逻辑行得到一定的检验,暂时没有出现错误。单元测试就是指为了确保我们的软件在运行过程中的正确无误。
单元测试任务包括: 模块接口测试、数据库连接测试等。
本系统的单元测试中,使用了Eclipse作为测试工具。在测试过程中,我们要对每一个类实现的方法编写一个相应的测试方法。例如下面一个简单方法的用例。

Public void updateUnitsTopic (Code user) {
	try {
			this.update (user);
		} catch (SynchronizeException ex) {
		Code tmp = this.loadUnitsTopic (user.getRecId ());
		if (tmp != null) {
		try {
			BeanUtils.copyProperties (tmp, user);
			} catch (Exception e) {
				}
				this.update (tmp);
			}
		}
	} 
/*******下面是测试方法正确性**********/
public static void main(String[] args) {
		Map params = new HashMap();
		Code code=new Code();
        code.setRemark(“描述”);
        code.setcodeType(“考试类型”);
        code.setcodeMudule(“模块名称”);
		UnitsPublicImpl impl = new UnitsPublicImpl();
		impl.updateUnitsTopic (code);//测试方法是否正确
	}

功能测试:它是在已知系统所应具有的功能,通过测试来检测每个功能的情况。通过测试,本系统功能全部实现,并能正常使用。
性能测试:测试软件的运行性能。这种测试常常与强度测试结合进行,需要事先对被测软件提出性能指标。从测试的结果看,多个用户同时访问时,性能存在有一个饱和点,一旦超过这个负荷,就使性能表现出下降趋势。而且系统的性能还跟计算机硬件性能也有很大的关系。硬件也好,该软件的性能也越好。

结 论
省略。

参考文献
[1] 陈刚.Eclipse从入门到精通[M].北京:清华大学出版社,2005。
[2] Ted Husted[美].Struts In Action[M].北京:机械工业出版社,2003。
[3] 方睿,刁仁宏,吴四九.网络数据库原理及应用[M].成都:四川大学出版社,2005。
[4] 夏昕. Spring 开发指南[M].北京:电子工业出版社,2003。
[5] 夏昕,曹晓钢,唐勇.深入前出Hibernate[M].北京:电子工业出版社,2005。
[6] 耿祥义,张跃平.Java 2实用教程(第二版)[M].北京:清华大学出版社,2004。
[7] 万峰.Jsp网站开发四“酷”全书[M].北京:电子工业出版社,2005

致 谢
省略


5、资源下载

本项目源码及完整论文如下,有需要的朋友可以点击进行下载。如果链接失效可点击下方卡片扫码自助下载。

序号毕业设计全套资源(点击下载)
本项目源码基于java+J2EE+sqlserver的SMART在线考试系统设计与实现(源码+文档)_java_MVC_CS架构_SMART在线考试系统.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

毕业设计方案专家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值