欢迎添加微信互相交流学习哦!

项目源码:https://gitee.com/oklongmm/biye2

摘 要

本系统系采用基于J2EE平台的Struts、Hibernate和Spring框架开发。通过利用面向对象和分层的编程技术,实现现有大多数网站所具备的诸如浏览文章、发布文章和回复文章等功能。同时本系统通过运用开源框架的优势,在很大程度上解决了系统开发中过于繁琐的数据转换、异常处理及事务处理等问题,简化和集成了系统框架,整改和完善了事务和业务逻辑的处理。
本系统主要分为普通用户和管理员两个大的模块,其中普通用户模块包括:用户注册、用户登陆、发帖提问、问题回答、问题检索、回答问题记录、用户问题记录、修改用户个人资料。管理员模块包括:管理员维护、栏目管理、问题管理、用户管理、密码修改。
本文主要介绍在实际研究开发过程中采用的一些技术手段。
关键词:Struts;Hibernate;Spring
ABSTRUCT
The design and development of BBS, which is based on JAVA EE Struts, Hibernate, Spring Framework and the connection pool, via the object-oriented programming and layered technologies, makes us now realize most functions of BBS. Thanks to the use of the connection pool and framework of the open-source, we now dont need care much about the conversion and the processing between different data, only to focus on the judgment of logic.
There are two main modules in the BBS in research, the normal mode and the administrator mode. The normal mode includes: user registration, logging in, posting questions, answering questions, questions index, answers records, questions records, and modification of users personal information. Administrator mode includes: administrator maintenance, management of themes, management of problems, management of users, and modification of passwords.
This paper focuses on some techniques in the research, including some theory foundation and some problems for the further development of BBS.
Key words:Struts;Hibernate;Spring
1.前言
1.1 网站论坛简述
网站论坛是一个以文化交流,学习知识为目的的,借助网络传输媒体和WEB共享实现的应用系统。像日常生活中的黑板报一样,电子公告牌按不同的主题、分主题分成很多个布告栏,布告栏的设立的依据是大多数BBS使用者的要求和喜好,使用者可以阅读他人关于某个主题的最新看法,也可以将自己的想法毫无保留地贴到公告栏中。同样地,别人对你的观点的回应也是很快的(有时候几秒钟后就可以看到别人对你的观点的看法)。在互联网,人们之间的交流打破了空间、时间的限制。在与别人进行交往时,无须考虑自身的年龄、学历、知识、社会地位、财富、外貌,健康状况,而这些条件往往是人们在其他交流形式中无可回避的。同样地,也无从知道交谈的对方的真实社会身份。这样,参与BBS的人可以处于一个平等的位置与其他人进行任何问题的探讨。这对于现有的所有其他交流方式来说是不可能的。
伴随着网络的出现,网页逐渐融入人们的生活。随着Internet的进一步发展,建站的技术日新月异。 就现在开发web技术来说,主要集中分为三大类:基于C/S结构的应用程序开发;结合C/S结构和Web技术的复合应用程序;基于B/S结构的动态网页技术。C/S结构系统:是传统开发模式,一般以数据库和客户端的两层结构实现,也有加入中间件的三层或多层结构,在web早期是标准的系统模式,但随着计算机技术的发展和网络的发展, C/S结构的不足越发明显,B/S结构系统逐渐成为了时尚
本系统在功能上实现了现今大多数网站系统具有的功能。在开发与实现的过程当中运用了JAVA EE中比较流行的框架和设计模式,这是本论坛的一个特点。本系统能够让人们更加方便的在网上进行知识交流,从而促进文化知识的传播以及各类信息技术的传播,同时达到人们网上交流、学习的目的。
1.2 问题提出与现状分析
以往类似于本系统的开发通常基于ASP技术,出于在安全性、系统稳定性和系统可维护性等方面考虑,传统的ASP技术已远远不及如今基于面向对象技术的J2EE框架系统。
首先在安全性方面,ASP系统很容易被黑客攻击,由于ASP的源码并未加密,黑客很容易通过源码来破解系统的漏洞并加以攻击。此外在数据库查询方面,APS的安全性也远远落后于J2EE技术。
其次在系统稳定性方面,由于ASP不支持线程,每次请求和响应均需要建立相应的进程加以调度,一旦系统访问量增大,系统将由于负荷过载而导致系统访问缓慢,更严重的甚至导致系统崩溃
最后在系统可维护性方面。由APS是视图和业务逻辑混合结构,在对于如今主张分层设计的J2EE系统而言,ASP的混乱且无序的框架根本无法存在可维护性。
综上所述,本系统采用基本J2EE技术开发。并运用各开源框架完善系统架构。使系统在安全性、稳定性、可维护性等方面较APS更胜一筹。
2 相关开发环境及技术理论
2.1系统开发环境
•采用B/S架构,使用JDSK1.5.04运行环境
•服务器操作系统:Windows XP
•数据库服务器:MySQL 5.1.39
•Web 服务器:Apache-Tomcat-6.0.1
2.2 技术简介
2.2.1 系统设计的主要技术路线
本管理系统是在Spring框架的基础上开发出来的。典型的J2EE结构分为三次结构:表现层、业务逻辑层和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。表现层是传统的JSP技术,自1999年问世以来,经过多年的发展,其广泛的应用和稳定的表现,为其作为表现层技术打下了坚实的基础。
该系统从逻辑结构上分为四层:表示层、业务逻辑层、服务层和数据持久层。其中使用Spring作为网站的整体基础架构,负责MVC的分离,在Spring框架的模型部分,利用Hibernate框架对持久层提供支持。
2.2.2 J2EE体系结构介绍
J2EE是一种利用Java 2平台来简化企业解决方案的开发、部署和管理相关的复杂问题的体系结构。J2EE核心是一组技术规范与指南,其中所包含的各类组件、服务架构及技术层次,均有共通的标准及规格,让各种依循J2EE架构的不同平台之间,存在良好的兼容性,解决过去企业后端使用的信息产品彼此之间无法兼容,导致企业内部或外部难以互通的窘境。 J2EE技术的基础就是核心Java平台或Java 2平台的标准版,J2EE不仅巩固了标准版中的许多优点,如编写一次、随处运行的特性、方便存储数据库的JDBC API以及能够在Internet应用中保护数据的安全模式等等,同时还提供了对EJB(Enterprise JavaBeans)、Java Servlets API、JSP(Java Server Pages)以及XML技术的全面支持。其最终目的就是成为一个能够使企业开发者大幅缩短投放市场时间的体系结构。
J2EE体系结构大致可以分为以下几层:
(1) Domain Object(领域对象)层:此层由系列的POJO(Plain Old Java Object,普通的、传统的Java对象)组成,这些对象是该系统的Domain Object,往往包含了各自所需要实现的业务逻辑方法。
(2) DAO(Data Access Object,数据访问对象)层:此层由系列的DAO组件组成,这些DAO实现了对数据库的创建、查询、更新和删除(CRUD)等原子操作。
(3) 业务逻辑层:此层由系列的业务逻辑对象组成,这些业务逻辑对象实现了系统所需要的业务逻辑方法。这些业务逻辑方法可能仅仅用于暴露Domain Object对象所实现的业务逻辑方法,也可能是依赖DAO组件实现业务逻辑方法。
(4) 控制器层:此层由系列控制器组成,这些控制器用于拦截用户请求,并调用业务逻辑组件的业务逻辑方法,处理用户请求,并根据处理结果转发到不同的表现层组件。
(5) 表现层:此层由系列的JSP页面、Velocity页面、PDF文档视图组件组成。此层负责收集用户请求,并将显示处理结果[10]。
2.2.3 Spring框架简介
该系统主要运用Spring框架。Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。另外,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
轻量即从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。
控制反转即Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
面向切面即Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的,完成业务逻辑,仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
容器即Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
框架即Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。
3 系统需求分析
3.1 功能需求分析
功能需求定义了开发人员必须实现的软件功能,使得用户能完成他们的任务,从而满足业务需求。参照业务需求分析的结果对每个业务进行细化,从而得到系统的功能模块。
通过分析,本系统主要分为普通用户和管理员两个大的模块,其中普通用户模块包括:用户注册、用户登陆、发帖提问、问题回答、问题检索、回答问题记录、用户问题记录、修改用户个人资料。管理员模块包括:管理员维护、栏目管理、问题管理、用户管理、密码修改。
3.2 系统可行性分析
3.2.1 环境可行性分析
系统主要运用Spring框架技术开发,开发所需要的软件工具都是简单易操作的且开源,安全,可维护性强。如下所示:
Web服务器:Apache-Tomcat-6.0.1版本。
开发技术:JDK5.0相关新特性、Spring框架技术、Hibernate框架技术、Struts框架技术。
系统选用MyEclipse 7.0作为集成开发环境。MyEclipse是在Eclipse的基础上添加了一些插件,也是一款功能强大的JavaEE集成开发环境,支持代码编写、配置、测试以及除错,MyEclipse6.0以前版本需先安装Eclipse。MyEclipse6.0以后版本安装时不需安装Eclipse。
MyEclipse企业级工作平台(MyEclipse Enterprise Workbench ,简称MyEclipse)是对Eclipse IDE的扩展,利用它可以在数据库和JavaEE的开发、发布,以及应用程序服务器的整合方面极大的提高工作效率。它是功能丰富的JavaEE集成开发环境,包括了完备的编码、调试、测试和发布功能,完整支持HTML, Struts, JSF, CSS, Javascript, SQL, Hibernate。
在结构上,MyEclipse的特征可以被分为7类:
(1)JavaEE模型
(2)WEB开发工具
(3)EJB开发工具
(4)应用程序服务器的连接器
(5)JavaEE项目部署服务
(6)数据库服务
(7)MyEclipse整合帮助
对于以上每一种功能上的类别,在Eclipse中都有相应的功能部件,并通过一系列的插件来实现它们。MyEclipse结构上的这种模块化,可以让我们在不影响其他模块的情况下,对任一模块进行单独的扩展和升级。
数据库:MYSQL 5.0
服器操作系统:由于JAVA语言的跨平台性,开发过程采用Windows 2003操作系统,也可以采用Windows XP操作系统。
现有的硬件和软件在功能上是可以满足系统开发的需求,开发所需要的软件工具也都是简单易操作的,开发人员的技术水平完全可以胜任系统的开发。
3.2.2 技术可行性分析
技术上的可行性主要是根据系统分析得到的需要开发的软件,来分析利用现有技术是否能实现待开发的软件。系统主要运用Spring框架技术开发,开发所需要的软件工具都是简单易操作的且开源,安全,可维护性强。如下所示:
Web服务器:Apache-Tomcat-6.0.1版本。
开发技术:JDK5.0相关新特性、Spring框架技术、Struts框架技术、Hibernate框架技术。
开发工具:MyEclipse 7.0、网页开发工具Dreamweaver MX。
数据库:MYSQL 5.0
服务器操作系统:由于JAVA语言的跨平台性,开发过程采用Windows 2003操作系统,也可以采用Windows XP操作系统。
现有的硬件和软件在功能上是可以满足系统开发的需求,开发所需要的软件工具也都是简单易操作的,开发人员的技术水平完全可以胜任系统的开发。所以该系统在技术上是可行的。
3.2.3 操作可行性分析
该系统具有易用性,B/S结构使得客户端不必安装任何软件,客户端只要有浏览器并连接到相应的网络即可使用,免除了非专业人员操作技术上的困难。WEB中间件服务器和数据库服务器均采用Windows 2003操作系统,WEB服务器采用为Tomcat6.0.1版本,数据库管理系统为MYSQL 5.0版本。
该系统具有友好亲切的使用界面,功能丰富并且使用简单,一般用户无需培训即可使用,对运行的平台和机器配置要求不高,便于配置和应用。
3.2.4 分析结果
经以上分析,说明该系统在开发上是可行的,在环境、技术、操作上都有可行性,可以进行开发。
4 系统总体设计
4.1系统功能结构总统框架设计
根据系统功能需求分析,设计出系统总体结构图如图4.1所示:
图4.1 系统总体结构图
4.2 系统各功能模块用例分析
网站论坛主要分成匿名访问用户(也称为未注册用户或未登陆用户)、普通用户和管理员用户三个角色,三个角色的具体实现,基本原理都一样:通过控制层对数据库中数据的操作,由显示层具体体现出各类用户相应具有的功能。
网站论坛的普通客户用例分析参考普通客户用例分析图,如图4.2所示。注册用户和未注册用户均为普通用户,未注册用户可通过注册模块注册账号。已注册用户可通过登陆模块登陆系统。
图4.2 普通用户用例分析图
系统登录后,用户可以发贴、回贴、修改个人信息和查询个人信息。这其中还包括维护用户的个人信息。
管理员通过后台管理可登录成为后台用户,并对系统进行相应的维护。
管理员维护系统包括增加管理员、增加栏目、删除栏目和修改栏目。此外管理员还可维护普通用户信息。并具备普通用户的所有权限。
管理员具有删除用户、修改用户积分、查看用户资料系统权限。查看用户资料包含了查看贴和删除贴的功能。
管理员用例图如图4.3,系统主要分成查看信息、发布信息、回复信息和系统管理四大功能。其中查看信息对所有用户开放,发布信息和回复信息只对注册用户开放,而系统管理功能只限管理员使用。
图4.3 管理员用例分析图
4.3数据库设计
4.3.1 数据库总体设计
系统主要由用户模块、栏目模块、问答模块和后台管理模块组成。
用户模块主要提供用户登录和发贴记录用户信息的功能。
栏目模块将系统分成一级栏目和二极栏目,两极栏目间相互关联。主要为后面的问答模块做铺垫。
问答模块由问题表和回答表构成,是整个网站系统的核心。问题表和回答表之前产生一对多的关联关系,一个问题对应着多个回答。
后台管理模块主要是维护系统的用户、栏目、问题数据和回答数据,同时还担负着管理问题的能力。
表4-1 数据库表清单
表名 说明
users 用户表
admin 管理员表
item 一级栏目表
subitem 二级栏目表
question 问题表
answer 回答表
如表4-1所示,系统由六个表组成。其中问题表和回答表之间有关联关系;一级栏目表和二级栏目表之间有关联关系。其余各表单独存在。
数据库物理模型参考数据库物理模型图,如图4.4所示。
图4.4 数据库物理模型图
图中关系item_su描述的是一级栏目对应一个或多个二级栏目,subitem表中的itemid是外键,与item表中的itemid外键关联,Delete constraint = Cascade。
关系que_ans描述的是一个问题对应一个或多个回答,answer表中的qid是外键,与question表中的qid外键关联,Delete constraint = Cascade。
问题表和回答表都将记录用户表的ID,但出于考虑,它们之间确并不建立关联关系。因为删除用户后就要删除用户之前所发的贴,因为根据数据库关联的参照完整性原则,如果问题表或回答表同用户表存在关联,那么当用户删除后,问题表或回答表就无法关联到用户表的记录。严重时将引起数据丢失。
4.3.2数据字典
(1) 用户表(users)
表4-2 用户表
字段 字段描述 类型 主键 不为空 备注
Id 序号 Integer True True
Userid 用户ID Varchar False True
Userpwd 密码 Varchar False True
Userques 密码问题 Varchar False True
Userans 密码答案 Varchar False True
Usermail 邮箱 Varchar False True
integral 用户积分 Integer False True
Grade 用户等级 Integer False True
Sex 性别 Varchar False True
Realname 真实姓名 Varchar False False
在名称为webdb的数据库中,根据项目的需求建立相应的数据表。
用户信息表user用来保存用户信息。表user共有10个字段。
(2) 管理员表(admin)
表4-3 管理员表
字段 字段描述 类型 主键 不为空 备注
Id 序号 integer True True
Adminid 登录ID Varchar False True
Adminpwd 密码 Varchar False False
管理员表admin用来保存管理员用户信息。在admin中共有3个字段。
(3) 一级栏目表(item)
表4-4 一级栏目表
字段 字段描述 类型 主键 不为空 备注
Itemid 栏目编号 integer True True
Itemname 栏目名称 Varchar False True
Itemcode 排序 integer False False
(4) 二级栏目表(subitem)
表4-5 二级栏目表
字段 字段描述 类型 主键 不为空 备注
Subid 栏目编号 integer True True
Subname 栏目名称 Varchar False True
Itemcode 一级栏目 Integer False False
subcode 排序 integer False False
一级栏目表和二级栏目表分别是:item、subitem,用来保存BBS中栏目的信息。在item中共有3个字段,在subitem中共有4个字段。
(5) 问题表(question)
表4-6 问题表
字段 字段描述 类型 主键 不为空 备注
qid 序号 integer True True
Title 标题 Varchar False True
Content 内容 varchar False False
Itemid 一级栏目 Integer False False
Subid 二级栏目 Integer False False
Userid 提问用户 varchar False False
Grade 用户等级 varchar False False
Offerscore 悬赏分数 integer False False
Status 回答状态 integer False False
Questiontime 提问时间 date False False
Clickcount 点击次数 integer False False
Accpetflag 是否采纳 integer False False 答案是否采纳
commenflag 是否推荐 integer False False
问题表question用来保存用户提的问题。表question共有13个字段。
(6) 回答表(answer)
表4-7 回答表
字段 字段描述 类型 主键 不为空 备注
Id 序号 integer True True
Quesans 回答内容 text False True
Userid 回答用户 varchar False False
Grade 用户等级 varchar False False
Anstime 回答时间 date False False
Status 回答状态 integer False False
Qid 问题编号 integer False False
回答表answer用来保存用户回答问题的答案。表answer共有7个字段。
5 系统详细设计
5.1系统运行环境和部署架构
系统运行的操作系统为Windows xp,数据库采用MySQL 5.1.39 ,应用服务器采用Tomcat 6.0.20应用服务器。
5.2系统体系结构的设计
(1)该系统是以关系数据库为存储,基于Web的应用系统。由一系列组件和功能模块组成。
● 总体结构:浏览器/服务器(B/S)
● 编程模式:Jsp+Hibernate+STRUTS
● 逻辑结构:用户界面开发、业务逻辑处理和数据存储
(2)该系统联合使用业务代理和DAO模式如图5.1所示:
图5.1 系统架构图
5.3系统业务流程
系统的业务流程严格遵守J2EE应用的规范,浏览器从进入系统开始,即发送*.do的请求,该请求被ActionServlet拦截,进入Struts框架的控制。系统的所有超级链接,包括表单的处理都将向*.do请求,即被ActionServlet拦截,由Struts的MVC框架控制。系统的业务流程图如图5.2所示:
图5.2 系统业务流程图
浏览器获得数据后向服务器端发送请求(request),FilterDispatch接收到从浏览器发送来的请求后将相应的数据请求分发到相应的Action的execute()方法进行处理,execute()方法通过BeanFactory创建service实现类的对象,实现类对象调用其响应的业务逻辑方法,业务逻辑层的方法又调用Dao层的方法进行数据库的操作,对数据进行持久化。
5.4 系统代码实现
5.4.1系统控制层
(1)定义接口
BBS采用的是dao设计模式,所以先定义了许多接口(在项目的srcrgwttmyzhsdao包下),这些接口都是为实现BBS具体功能设计的。接口名分别如下:
IAdminDAO:此接口定义了所有对管理员用户表操作的方法;
IAnswerDAO:此接口定义了所有对回答表操作的方法;
IItemDAO:此接口定义了所有对一级栏目表操作的方法;
ISubitemDAO:此接口定义了所有对二级栏目表操作的方法;
IQuestionDAO:此接口定义了所有对问题表操作的方法;
IUserDAO:此接口定义了所有对用户表操作的方法。
(2)实现接口
所有接口中定义的方法和详细代码见附录和光盘中源文件。
由于数据库连接交给了Spring托管,所以实现接口里的方法时,对数据库的操作只需要继承HibernateDaoSupport类,当要对数据库操作时,只需要调用父类的getSession()方法就能得到Session,对数据库实现操作。
执行对数据库中纪录的删除操作,所以要得到Session。由于继承了HibernateDaoSupport类,所以只需要直接调用父类的getSession()方法就能得到Session。
各实现类名称分别为:
IAdminDAOImpl:实现了IAdminDAO接口中的所有方法;
IAnswerDAOImpl:实现了IAnswerDAO接口中的所有方法;
IItemDAOImpl:实现了IItemDAO接口中的所有方法;
ISubitemDAOImpl:实现了ISubitemDAO接口中的所有方法;
IQuestionDAOImpl:实现了IQuestionDAO接口中的所有方法;
IUserDAOImpl:实现了IUserDAO接口中的所有方法。
(3)数据库连接
BBS采用的是数据库连接池技术,交由Spring框架托管,并继承了LocalSessionFactoryBean实现与数据库的连接。Spring配制文件applicationContext.xml。
JNDIjava:comp/env/不能变,jdbc/duck与前面建立站点时配制的jndiName相对应。
hibernate.connection.autocommit表示允许自动提交。
hibernate.show_sql显示sql语句。
(4)定义VO类和Hibernate映射文件
所有的VO类和Hibernate映射文件都放在项目的srcrgwttmyzhso包下。Hibernate映射文件是用来描述数据库中表和VO类关系的xml文件。
question表和answer表是一对多关系,所以在创建这两个表的VO类时,除包括对应表中字段外应相互将对方包含其中。
一个问题可能有多个答案,所以类用一个类型为Set的属性。
一个答案只可能对应一个问题,所以类中应包含一个类型为Question的属性。
Set接口是可重复,但无序的,为了能让回答在问题下按照时间先后的顺序排列,所以Answer类实现了Comparable接口复写compareTo方法,并且因为Date类复写过compareTo方法,所以可以这样复写compareTo方法。
在Question VO类映射文件Question.hbm.xml中,要反映出一对多,并且按照自然排序的特点,所以要在结点中加入一个属性sort=”natural” 从而达到了使答案按照时间先后顺序排列的效果。
Answer VO类的映射文件Answer.hbm.sml中也要反映出一对一的特点,所以应该在映射文件中加入结点。
(5)加入Struts功能
所有与Struts有关的文件都在项目的srcrgwttmyzhsstruts包下,其中包括资源文件ApplicationResources.properties,和action类、form类。为了使Struts和Spring整合在一起,须在网站描述文件web.xml中加入相应配置。
完成该步骤后,已经实现了Spring+Hibernate+Struts。当Struts的某个类要用到其他类的对象时,只需要在这个类中把要用到的类作为自己的属性,并生成get、set方法就能得到。如QuestionAction.java中,此类是Struts用来响应前台所有对Question表操作请求的类。其中要用到IQuestionDAO类来对数据库中Question表的增、删、查、改等操作。
之所以这里用到了IQuestionDAO类,却没有一句是创建该类的一个实例的语句,是因为利用了Spring的控制反转。
(6)乱码过滤器
为了防止论坛在运行中可能出现的乱码问题,本论坛加入了过滤器。过滤器只能防止在往数据库里存,或者从数据库中读时,可能产生的编码不一致而导致的乱码。首先应该确定的是,数据库中是按照gb2312(或者gbk)编码存放数据。在项目srcrgwttmyzhsilter包中建立EncondingFilter.java类,该类实现了Filter接口,并复写了接口中的所有方法。
(7)防止匿名访问过滤器
为了防止有人在浏览器的地址栏中直接输入后台或者某些需要登陆后才能访问的网页,加入了过滤功能。首先需要把某一种类需要保护的网页文件放入项目下WebRoot/jsp目录下的同一目录中,如提问和修改个人信息功能的网页是需要注册用户登陆以后才能访问的,则把相关网页全都放入WebRoot/jsp目录下名为user的目录。
(8)积分转换和加密
数据库中只存放了用户拥有的积分,要在网页上显示出相应拥有的头衔,必须经过转换,转换规则参考积分规则图,如图5.3所示。
图5.3 积分规则图
在项目中建立IntegralGrade.java类并实现其功能。其关键代码如下所示:
public IntegralGrade() {
this.pro = new Properties();
this.pro.setProperty(1, 开发爱好者);
this.pro.setProperty(2, 初级程序员);
this.pro.setProperty(3, 软件工程师);
this.pro.setProperty(4, 高级软件工程师);
this.pro.setProperty(5, 项目主管);
this.pro.setProperty(6, 项目经理);
this.pro.setProperty(7, 项目总监);
this.pro.setProperty(8, 首席技术执行官);
}
//确认等级
public int getGrade(int integral){
int grade = 0;
if(integral>=0&&integral<=300){
grade = 1;
}
if(integral>=301&&integral<=1000){
grade = 2;
}
if(integral>=1001&&integral<=5000){
grade = 3;
}
if(integral>=5001&&integral<=10000){
grade = 4;
}
if(integral>=10001&&integral<=20000){
grade = 5;
}
if(integral>=20001&&integral<=50000){
grade = 6;
}
if(integral>=50001&&integral<=100000){
grade = 7;
}
if(integral>=100001&&integral<=500000){
grade = 8;
}
return grade;
}
为了保护用户的密码信息,这里设计了一个加密类。该类对外提供了一个getMD5ofStr方法,是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串,返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的。当用户在注册页面输入密码传入Struts相应的类处理时,调用了该方法,进而把用户的密码进行了MD5后再存入到数据库中。这样即使数据库中数据泄露,也不至于会把用户的口令直接泄露出去。MD5Code.java类在项目中的srcrgwttmyzhstil包下。此类为网上下载,具体实现的算法在此不阐述。
(9)防止用户重复提交表单
Struts的Token(令牌)服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户绘画中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
BBS中所有需要提交的表单中都使用了Struts中带的防止重复提交表单机制。如用户注册,在进入注册页面时,已经在request中加入了Token。
5.4.2系统显示层
(1)前台文件架构
根据前期的分析,BBS的前台主要包括用户注册、用户登陆、用户提问回复、用户个人信息中心、后台管理等模块。前台页面都位于项目的WebRootjsp目录下,该目录下还有三级子目录,分别是admin:用来存放管理员访问页面;ques:用来存放问题相关页面;user:用来存放用户访问相关页面。
(2)前台前面运行结果
BBS的首页以简单明快为主,让访客最快地找到BBS中最近流行的讨论话题和自己提的问题有没有回答等。首页示例参考首页示例图,如图5.4所示。
图5.4首页示例图
(3)用户注册及登录
操作用户如有系统账号,可通过用户登录模块登录系统,登录成功后将进入系统主界面。登录失败将返回错误信息。
操作用户如没有系统账号,可通过用户注册模块注册新账号,注册成功后即可进入系统界面。如因账号已存在等错误信息导致注册失败,将返回错误信息。
系统登录成功后将在用户表号记录登记日志;用户如注册成功后同样将在用户表写入注册信息。
图5.4 用户注册及系统登录数据流
BBS访问者如果要发帖提问必须经过注册、登陆以后才能发帖。注册页面参考用户注册示例图,如图5.5所示。
图5.5 用户注册示例图
用户注册信息保存在用户表user中。当用户填写完表单以后,点击注册后,根据页面 中action的值在Struts配制文件中查询后送到相应的Struts的Action类中,根据表单中的隐藏域status的值来判断送给类中的哪个方法来执行。
通过页面提交,先进入UserForm.java进行form表单检查。这里主要检查的是表单各项是否填写,填写是否合规则,如验证码必须是数字等;如果有未填写的,则返回到提交页面上,并提示哪项没有填写,要求用户填写完整;如果都填写完整,则进入相应的action中的方法进行下一步处理。这里是传给UserAction.java中的register方法。用户注册的关键代码如下所示:
public ActionForward register(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
// Token验证
if (isTokenValid(request, true)) {
UserForm userForm = (UserForm) form;
// 先判断验证码是否正确
String ccode = (String) request.getSession().getAttribute(ccode);
String checkcode = userForm.getCheckcode();
if (!(checkcode.equals(ccode))) {
ActionMessages errors = new ActionMessages();
errors.add(checkcode, new ActionMessage(checkcode.error));
super.saveErrors(request, errors);
return mapping.getInputForward();
}
User user = null;
try {
// 如果正确,则要向数据库中插入
user = this.iuserdao.queryByUserid(userForm.getUserid());
if (user == null) {
MD5Code md5 = new MD5Code();
user = new User();
user.setUserid(userForm.getUserid());
user.setUserpwd(md5.getMD5ofStr(userForm.getUserpwd()));
user.setUserques(userForm.getUserques());
user.setUserans(userForm.getUserans());
user.setSex(男);
user.setGrade(1);
// 查询此用户是否存在
this.iuserdao.register(user);
// 成功之后要将用户名和用户等级保存在session之中
request.getSession().setAttribute(userid,
user.getUserid());
request.getSession().setAttribute(grade, user.getGrade());
return mapping.findForward(registersuccess);
} else {
ActionMessages errors = new ActionMessages();
errors.add(exist, new ActionMessage(user.userid.exist));
super.saveErrors(request, errors);
//换一个Token
resetToken(request);
return mapping.getInputForward();
}
} catch (Exception e) {
e.printStackTrace();
return mapping.findForward(registerfailure);
}
} else {
// 认为是重复提交
ActionMessages errors = new ActionMessages();
errors.add(formsubmit, new ActionMessage(formsubmit.error));
super.saveErrors(request, errors);
return mapping.getInputForward();
}
}
用户注册后需要登陆才能发帖。登陆页面参考用户登陆示例图,如图5.6所示。
图5.6用户登陆示例图
用户登陆信息保存在用户表user中。当用户填写完表单以后,点击注册后,根据页面中action的值在Struts配制文件中查询后送到相应的Struts的Action类中,根据表单中的隐藏域status的值来判断送给类中的哪个方法来执行。
通过页面提交,先进入UserForm.java进行form表单验证,如果验证通过,则进入相应的action中的方法进行下一步处理。这里是传给UserAction.java中的login方法。部分代码见源程序,有很详细的注释。
(4)问题发布功能的实现
只有当用户登录后,才能发布问题和对已有问题进行回复。问题发布界面如图5.7所示:
图5.7用户发布问题示例图
用户发布的问题信息保存在问题表question中。当用户填写完问题发布表单以后,点击提问后,根据页面中action的值在Struts配制文件中查询后送到相应的Struts的Action类中,根据表单中的隐藏域status的值来判断送给类中的哪个方法来执行。
通过页面提交,先进入QuestionForm.java进行form表单验证,如果验证通过,则进入相应的action中的方法进行下一步处理。这里是传给QuestionAction.java中的insert方法。
(5)后台用户管理的实现
管理员可以对系统后台进行管理,后台管理包括用户管理、栏目管理、问题管理等功能模块,后台管理页面如图5.8所示:
图5.8后台管理页面示例图
后台登录的关键代码如下:
public ActionForward login(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
AdminForm adminForm = (AdminForm) form;// TODO Auto-generated method stub
String ccode = (String) request.getSession().getAttribute(ccode);
String checkcode = adminForm.getCheckcode();
if (!(checkcode.equals(ccode))) {
ActionMessages errors = new ActionMessages();
errors.add(checkcode, new ActionMessage(checkcode.error));
super.saveErrors(request, errors);
return mapping.getInputForward();
}
Admin admin = new Admin();
MD5Code md5 = new MD5Code();
admin.setAdminid(adminForm.getAdminid());
admin.setAdminpwd(md5.getMD5ofStr(adminForm.getAdminpwd()));
boolean flag = false;
try {
flag = this.iadmindao.login(admin);
} catch (Exception e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
if(flag){
request.getSession().setAttribute(adminid, admin.getAdminid());
return mapping.findForward(loginsuccess);
}else{
request.getSession().setAttribute(flag, error);
return mapping.findForward(loginfailure);
}
}
(6)其他功能页面的实现过程
其他普通用户功能页面和管理员用户功能页面的实现过程和以上两个功能页面很类似,基本上都是重复以上步骤。不同的是分给了Struts框架不同的form和action去处理。这样做的好处是使得整个BBS系统结构非常清晰,各个模块划分得很清楚,各自只处理各自功能页面的请求,从而降低了耦合性。
Struts框架本身就是基于MVC[注4]的。各个jsp页面就是MVC的View层,Struts也提供了很多方便页面现实的Struts标签。本BBS中的所有jsp页面都是用Struts1.2的标签。Struts的form和action当于controller层,它们把从View层得来的数据,通过Struts配制文件传给相应的form或者action,程序员可以在其中定义各种方法来实现对事务的处理,而不用过多关注数据在各层
间是如何传递,以及数据类型间的相互转换,这些,Struts框架已经帮我们做好了。这是使用框架的一些好处。
在Struts的action中有的方法要与数据库打交道,这个时候就只需要调用已经定义好的接口,这相当于Model层。Action中不需要关心数据从哪来,怎么来的,也不需要关心数据传过去如何插入到数据库的。只要申明一个实现接口的类的对象,调用其中已经定义好的一些方法,就能从数据库中得到相关数据,这里设计的是得到一个已经实例化的VO对象。这样action就能很方便地把从数据库中得到的数据往View层传;往数据库中插数据也是一样,只要把从View层得到的数据作为一个VO对象做为参数调用已经定义好的方法,就能实现对数据库中的数据增、删、查、改。所有代码请参考项目中的源程序,其中也有很多很详细的注释。
6 BBS的完善与改进意见
整个BBS虽然已经开发完成,而且各功能模块运行流畅自然且经使用具有一定的实用价值,但是由于时间的关系以及是一个人开发的原因,有许多地方需要改进。如数据库连接池的配置,由于没太多的经验,网站论坛可能会因为访问的次数频繁,和访问量的增大,服务器可能会有死机的现象。而且页面的设计,因为缺少美术功底和Flash、图片的修饰,不太好看,对发贴人设定的分数也没有控制,用户可以随便设置多少分。虽然用户在注册时网数据库中加入的密码是经过MD5加密的,但是其他用户的基本信息并没有加密。数据库数据被盗取出去后用户的很多相关信息可能会泄露。还有些页面图片的路径也有可能因为后期的改动,使得不能正常显示。这些都是要在今后需要完善和改进的地方。
注 释
[注1]. BBS(Bulletin Board Service,公告牌服务)是Internet上的一种电于信息服务系统。它提供一块公共电子白板,每个用户都可以在上面书写,可发布信息或提出看法。
[注2].VO是处于Transient和Detached状态的对象统称为值对象(Value Object)
[注3]. MD5的全称是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest开发出来,经MD2、MD3和MD4发展而来。它的作用是让大容量信息在用数字签名软件签署私人密匙前被压缩成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数)。不管是MD2、MD4还是MD5,它们都需要获得一个随机长度的信息并产生一个128位的信息摘要。虽然这些算法的结构或多或少有些相似,但MD2的设计与MD4和MD5完全不同,那是因为MD2是为8位机器做过设计优化的,而MD4和MD5却是面向32位的电脑。
[注4]. MVC(Model/View/Controller)模式是国外用得比较多的一种设计模式,好象最早是在Smaltalk中出现。MVC包括三类对象。Model是应用对象,View是它在屏幕上的表示,Controller定义用户界面对用户输入的响应方式。
模型-视图-控制器(MVC)是80年代Smalltalk-80出现的一种软件设计模式,现在已经被广泛的使用。
1、模型(Model)
模型是应用程序的主体部分。模型表示业务数据,或者业务逻辑.
2、视图(View)
视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面。
3、控制器(controller)
控制器工作就是根据用户的输入,控制用户界面数据显示和更新model对象状态。
参考文献
[1](美)Douglas E.Comer.Computer Networks and Internets–with Internet Applications[M].北京:电子工业出版社,2004:P529-543.
[2]CNNIC.2006年中国博客调查报告[J].中国互联网络信息中心,2006年7月.
[3]李佳,季秀兰.JSP+Mysql数据库的安全隐患与解决方案[J].电脑学习,2007年08期:P43.
[4]李兴华.JAVA框架核心技术.http://www.mldn.cn/Pub/wml.txt/980810-2.html.
[5]王国辉,李文立,杨亮.JSP数据库系统开发完全手册[M].北京:人民邮电出版社,2006.
[6]李刚.JAVA EE应用开发详解[M].北京:清华大学出版社.
[7]李刚.整合Struts+Hibernage+Spring应用开发详解[M].北京:清华大学出版社.
[8]孙卫琴.精通Struts:基于MVC的JAVA Web设计与开发[M].北京:电子工业出版社.
[9]杨磊,陈凌云.精通Eclipse Web开发-Java体系结构、工具、框架及整合应用[M].北京:人民邮电出版社.
[10]李刚. 轻量级Java EE企业应用实战--Struts 2 + Spring + Hibernate整合开发 [M] 北京:电子工业出版社,2009.
[11]李刚. Struts2权威指南--基于WebWork核心的MVC开发[M] 北京:电子工业出版社,2007.
[12]刘斌. 精通JavaWeb整合开发(JSP + AJAX + Struts + Hibernate[M] 北京:电子工业出版社,2007.
[13]耿祥义,张跃平. Java2实用教程(第三版)[M] 北京:清华大学出版社,2006.
[14]孙卫琴. 精通Hibernate:Java对象持久化技术详解[M] 北京:电子工业出版社,2007.
附 录
IQuestionDAOImpl.java部分代码如下:
……
public class IQuestionDAOImpl extends HibernateDaoSupport implements IQuestionDAO {
public void delete(int qid) throws Exception {
这里要执行对数据库中纪录的删除操作,所以要得到Session。由于继承了HibernateDaoSupport类,所以只需要直接调用父类的getSession()方法就能得到Session。
String hql = DELETE FROM Question WHERE qid=?;//SQL语句
Query q = super.getSession().createQuery(hql);//建立查询对象
q.setInteger(0, qid);//设置查询参数
q.executeUpdate();//返回查询结果
}
……
Spring配制文件applicationContext.xml部分代码如下:
class=org.springframework.jndi.JndiObjectFactoryBean
destroy-method=close>

java:comp/env/jdbc/duck

class=org.springframework.orm.hibernate3.HibernateInterceptor>

class=org.springframework.orm.hibernate3.LocalSessionFactoryBean>

org.hibernate.dialect.MySQLDialect

true

true

…… ……

映射文件Admin.hbm.xml部分代码如下:
……

……
Question VO类部分代码如下:
……
public class Question {
private int qid;
private String title;
private String content;
……
//因为一个问题可能有多个答案,所以类用一个类型为Set的属性。
private Set answers;
……
Answer VO类部分代码如下:
……
public class Answer implements Comparable {

private int aid;
private String quesans;
private String userid;
/*因为一个答案只可能对应一个问题,所以类中应包含一个类型为Question的属性*/
private Question question;
……
复写compareTo方法如下:
public int compareTo(Object o) {
Answer a = (Answer)o;
return getAnstime().compareTo(a.getAnstime());
}
Question VO类映射文件排序效果如下:
……

……
Struts配置代码如下:
……

contextConfigLocation

/WEB-INF/classes/applicationContext.xml

context

org.springframework.web.context.ContextLoaderServlet

1

……
在Struts配制文件struts-config.xml中建立一个插件,代码如下:

value=/WEB-INF/classes/applicationContext.xml />

并在标签之前,标签之后加入标签,具体内容如下:

Question表的增、删、查、改等操作。部分代码如下:
package org.wtt.myzhs.struts.action;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
……
public class QuestionAction extends DispatchAction {
//设置类型IQuestionDAO的属性iquestiondao
private IQuestionDAO iquestiondao;
public ActionForward insert(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
……
public IQuestionDAO getIquestiondao() {
return iquestiondao;
}
public void setIquestiondao(IQuestionDAO iquestiondao) {
this.iquestiondao = iquestiondao;
}
}
之所以这里用到了IQuestionDAO类,却没有一句是创建该类的一个实例的语句,是因为利用了Spring的控制反转,在Spring配制文件applicationContext.xml中有如下配制:
……

abstract=true>

……

class=org.wtt.myzhs.impl.IQuestionDAOImpl
parent=iquestiondao>

……

class=org.wtt.myzhs.struts.action.QuestionAction>

解决乱码问题部分代码如下:
package org.wtt.myzhs.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
……
//该类实现过滤器接口
public class EncondingFilter implements Filter {
//要转换成的编码
private String charset = null;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
//把ServletRequest中的编码设置为指定的编码。
req.setCharacterEncoding(this.charset);
//继续把request、response往后传。
chain.doFilter(req, resp);
}
//初始化要设置的编码类型,该类型能由网站配制文件web.xml文件中指定
public void init(FilterConfig arg0) throws ServletException {
this.charset = arg0.getInitParameter(charset);
}
}
建立好编码过滤类后,还需要在网站配制文件web.xml中加入如下描述代码:
……

encoding

org.wtt.myzhs.filter.EncondingFilter

charset
GB18030

encoding
/*

……
防止匿名访问部分代码如下:
package org.wtt.myzhs.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
……
public class UserLoginFilter implements Filter {
……
/*把ServletRequest向下强制转型为HttpServletRequest类型
如果request中属性userid不为空,则把request、response继续往后传,使其访问。*/
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)arg0;
if(req.getSession().getAttribute(userid)!=null){
arg2.doFilter(arg0, arg1);
}
else{
//如果request中属性userid为空则跳转到forward.htm页面
req.getRequestDispatcher(forward.htm).forward(arg0, arg1);
}
}
……
}
建立好编码过滤类有,还需要在网站配制文件web.xml中加入如下描述代码:
……

userlogin

org.wtt.myzhs.filter.UserLoginFilter

userlogin
/jsp/user/*

userlogin
/jsp/ques/*

……
实现积分部分代码如下:
package org.wtt.myzhs.util;
import java.util.Properties;
public class IntegralGrade {
private Properties pro = null;
private static final IntegralGrade ig = new IntegralGrade();
//key --> value
public IntegralGrade() {
this.pro = new Properties();
this.pro.setProperty(1, 开发爱好者);
this.pro.setProperty(2, 初级程序员);
……
public static IntegralGrade getInstance(){
return ig;
}
//确认等级
public int getGrade(int integral){
int grade = 0;
if(integral>=0&&integral<=300){
grade = 1;
}
if(integral>=301&&integral<=1000){
grade = 2;
}
……
}
//取得等级信息
/*
*
* @param grade
* 表示用户登陆之后的等级
* @return 返回一个等级的具体信息
*/
public String getGradeInfo(int grade){
String str = null;
str = this.pro.getProperty(grade+);
return str == null?:str;
}

public static void main(String args[]) {
IntegralGrade ig = new IntegralGrade();
System.out.println(ig.getGradeInfo(ig.getGrade(5002)));
}
}
解决表单重复提交部分代码如下:
……
public ActionForward forward(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
saveToken(request);
return mapping.findForward(register);
……
提交表单后Struts交由UserAction类中的register方法处理时,进行Token验证。UserAction.java部分代码如下:
……
public ActionForward register(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
//Token验证, 如果Token没有过期,则继续进行注册代码
if (isTokenValid(request, true)) {
......
//如果Token过期了,则跳转到特定页面

基于java的校园网站论坛设计与实现(含源文件)相关推荐

  1. 基于Java的校园商铺的设计与实现

    基于java的校园商铺的设计与实现 摘要:本系统是一个基于Java的校内商铺在线系统,该系统主要针对本校内的师生所设计的一款在线电子商务系统,使得学校的师生能够在校内任意位置即可购买到所需要的生活用品 ...

  2. java毕业设计校园招聘论坛设计mybatis+源码+调试部署+系统+数据库+lw

    java毕业设计校园招聘论坛设计mybatis+源码+调试部署+系统+数据库+lw java毕业设计校园招聘论坛设计mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: 项目架构:B/S ...

  3. 基于JAVA学校校园网站系统(Springboot框架) 开题报告

      本科生毕业论文 基于Java(springboot框架)学校校园网站系统 开题报告 学    院: 专    业: 计算机科学与技术 年    级: 学生姓名: 指导教师:   XXXX大学本科生 ...

  4. 基于JAVA宠物救助网站的设计与实现计算机毕业设计源码+系统+数据库+lw文档+部署

    基于JAVA宠物救助网站的设计与实现计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA宠物救助网站的设计与实现计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B ...

  5. java拼图游戏设计文档_基于JAVA的拼图游戏的设计与实现(含录像)

    基于JAVA的拼图游戏的设计与实现(含录像)(任务书,开题报告,中期检查表,外文翻译,毕业论文15500字,程序代码,答辩PPT,答辩视频录像) 摘  要 在我们日常生活中,有很多的益智类游戏,如七巧 ...

  6. 基于java的心理健康网站的设计与实现_基于JavaEE心理健康教育网站的设计与开发.doc...

    基于JavaEE心理健康教育网站的设计与开发 基于 内容摘要: 近年来,信息化和网络化不断深入现代社会各个领域,人们的生活行为方式也发生了深刻变化,网络成瘾等新的认知和心理障碍等问题不断出现.随着我国 ...

  7. 基于Java的校园商铺的设计与实现源码

    欢迎添加微信互相交流学习哦! 项目源码:https://gitee.com/oklongmm/biye 摘要:本系统是一个基于Java的校内商铺在线系统,该系统主要针对本校内的师生所设计的一款在线电子 ...

  8. 基于PHP+MySQL校园网站的设计与实现

    校园生活是很多大学生没好的回忆,为了能过让更多的校园风采展示给人们,我们通过PHP和MYSQL开发了本校园网站的设计与实现,通过本网站可以更好的展示校园内风采和美好生活 本系统分为前台和后台2部分,前 ...

  9. 企业门户网站的设计与实现(含源文件)

    欢迎添加微信互相交流学习哦! 项目源码:https://gitee.com/oklongmm/biye 内容摘要:本文介绍了基于JSP的企业门户网站的设计,通过MySql数据库存储.读取数据,运用To ...

最新文章

  1. Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )
  2. cx oracle6 oracle10,python安装cx_Oracle
  3. java 判断是否是list_给Java程序员的20个链表面试题
  4. 我的 Vue.js 学习日记 (七) - 事件与修饰符
  5. 关于jquery.AutoComplete插件的一些使用心得(编码问题,效率问题)
  6. Android 插件技术实战总结
  7. 系统级性能分析工具 — Perf
  8. c#事务的使用、示例及注意事项(转)
  9. 【资料下载区】【iCore、 iCore2相关资料】更新日期2017/1/11
  10. css初始化_利用CSS变量实现炫酷的悬浮效果
  11. html5教学文档笔记,4.HTML 教程- (HTML5 基础)
  12. oracle数据库表excel文件位置,Excel数据导入到oracle数据库表方法
  13. Android学习路线(适合学生)
  14. jmeter脚本录制http/https
  15. js不同地图坐标系经纬度转换(同一经纬度,硬件/谷歌转高德地图;经纬度查询)
  16. 无人机航摄地面站航线设计主要参数
  17. 栅栏布局合并html,制作简约CSS栅栏布局
  18. 计算机辅助设计中图元单位,CAD图形单位快捷键
  19. 【Matlab学习手记】良好的编程习惯
  20. java优化编程 第2版_Java优化编程(第2版)林胜利、王坤茹 pdf

热门文章

  1. 2014第2周四部署环境买火车票
  2. linux下pthread_mutex_t使用时的问题
  3. python中unexpected indent是什么意思_python3:unexpected indent?indent expected?autopep8!
  4. python—简单数据抓取七(采取蘑菇API代理设置scrapy的代理IP池并利用redis形成队列依次使用,利用ip池访问网页并将scrapy爬取转移到items的数据存入到数据库)
  5. git保存用户名密码的方式
  6. 1938年叶企孙给熊大缜的诗
  7. 编写程序,创建类MyMath,计算圆的周长和面积以及球的表面积和体积,并编写测试代码,结果保留两位小数。
  8. 【调剂】2021年华中农业大学硕士研究生招生调剂信息
  9. docker文件挂载
  10. ABAP 去除字符串某个字段(去掉的金额逗号例子)