还剩84页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
本科生毕业设计`题目工资管理系统的设计与实现全日制本科生毕业设计成绩评定总表姓名学号专业信息与计算科学题目工资管理系统的设计与实现题目来源是否来源于教师科研课题是;否(√)完成期限2014年9月~2015年3月指导教师杨讯职称讲师设计基本情况设计说明10440字;图纸25张;附件需求分析、概要设计、数据库设计、详细设计、功能模块测试学生总成绩设计成绩百分制指导教师评分;评阅教师评分;答辩评分折合比例指导教师评分40%;评阅教师评分30%;答辩评分30%实得成绩折合分指导教师评分;评阅教师评分;答辩评分;总分;总分人总评等级毕业设计总评等级学院分管领导签字学院签章年月日全日制本科生毕业设计成绩评定表姓名学号专业题目指导教师职称指导教师意见(从学生的态度、设计作品情况及毕业设计说明写作情况等方面表述,是否达到本科毕业设计要求,是否同意答辩内容统一楷体小4号,
1.5倍行距打印,由教师本人手写签名)指导教师评分百分制 指导教师签字 全日制本科生毕业设计成绩评定表姓名刘建涛学号20110513197专业信息与计算科学题目工资管理系统的设计与实现评阅教师职称评阅教师意见(从设计选题、设计思路、作品质量,设计说明等方面表述,是否达到本科毕业设计要求,是否同意提交答辩内容统一楷体小4号,
1.5倍行距打印,由教师本人手写签名)评阅教师评分百分制 评阅教师签字 全日制本科生毕业设计成绩评定表姓名刘建涛学号20110513197专业信息与计算科学题目工资管理系统的设计与实现答辩时间2015年2月2日答辩地点大溪沟答辩人数4答辩小组组长职称刘建涛(主程序员)答辩记录人邓杨(美工)答辩小组成员职称黄涛(测试员)、蒋文明(文档整理员)、邓杨(美工)答辩小组意见(主要从学生答辩制作的PPT、语言表达、逻辑性,对提问的理解及回答,是否通过答辩等方面表述)答辩成绩百分制 答辩小组组长签字 答辩记录(主要记录提问及回答问题,提问不少于3个)姓名刘建涛学号20110513197专业信息与计算科学题目工资管理系统设计与实现设计背景与目标本次开发是由安博教育和学校发起,学生自主选题的一次毕业设计考虑到市面上的人事管理系统与工资管理系统都是针对个别公司开发的我们有意利用ssh技术开发一种通用的,管理权限、部门、以及工资发放形式可以根据不同的公司自行分配和修改、易于维护、易于适应变更、可重用性良好的一个工资管理系统的设计与实现设计思路、技术路线在和指导老师多次交流后,确定实现方案的要点和工作计划本系统的实现的主要功能有1对系统进行管理用户的添加修改以及权限授予都是管理员操作的2对单位人员的变动进行处理一个单位的职工不会是一成不变的,总是在不断的变化有调出、有调入、也有职工在本单位内部调动因此,设计系统是应考虑到这些情况3)对工资账户的创建,修改,删除4对职工的工资进行计算、修改能对各职工的工资进行计算,即计算应发金额、应扣金额及实发金额等5查询统计功能要求即可以单项查询,比如查看某个职工的工资情况等;也可以查询全部6)员工个人信息的查询,修改与管理7报表打印功能每月发放工资时,要求能够打印本月的工资表、随工资发给每个职工的工资条以及工资统计表设计进度计划正如研究任何其它软件项目一样,我做的毕业设计也经历了从选题,调研,熟悉开发环境,实验关键技术,查找类似的相关系统的资料;系统概要设计,数据库结构设计,功能模块开发,功能模块测试,系统调试和系统试运行和修改如下
1.2-1开发计划流程图图
1.2-1开发计划流程图指导教师意见指导教师(签名)年月日全日制本科生毕业设计开题报告全日制本科生毕业设计教师指导记录姓名刘建涛学号20110513197专业信息与计算科学暂定题目工资管理系统的设计与实现最终题目工资管理系统的设计与实现
1、选题指导指导时间2014年9月25日
2、Strusts2配置指导指导时间2014年10月10日
3、权限分配指导指导时间2014年10月20日
4、中文乱码指导指导时间2014年11月31日指导教师(签名)工资管理系统──框架搭建、用户登录、系统管理、报表管理数学学院信息与计算科学专业2011级刘建涛指导教师杨讯摘要在本工资管理系统中,涉及到最多的就是对数据的增删改查,当然在真是的系统中,对于这些操作要控制在严格的权限中,使用struts2+hibernate+spring实现了简单的CRUD操作在mvc与三层架构之间我们选择了三层架构,当然他们本质相同这里采用三层架构,也就是数据访问层、业务逻辑层、表示层这样有利于分工和标准化增加代码的复用性但由于业务无法直接访问数据库必须通过中间层完成反映时间间隔用操作是否成功界面代替我在这里主要介绍登录模块、系统管理模块、报表管理模块、退出登录、中文乱码的解决、如何在Strusts2中实现CRUD的权限分配关键词数据库;工资;工资管理;登录模块;系统管理模块;报表管理模块;退出登录;中文乱码的解决;如何在Strusts2中实现CRUD的权限分配Abstract InthesalarymanagementsysteminvolvingthemostisthedataadditionsanddeletionsofcourseinthesystemreallyisfortheseoperationstobecontrolledinstrictaccesstheuseofStruts2+hibernate+springtoachieveasimpleCRUDoperation.BetweentheMVCandthethreelayerarchitecturewechoosethreelayersarchitectureandofcoursetheywereessentiallythesame.Hereusesthreelayerstructuresnamelythedataaccesslayerbusinesslogiclayerpresentationlayer.Thisisconducivetospecializationandstandardization.Toincreasethereusabilityofthecode.Butbecauseofthebusinesscannotdirectlyaccessthedatabasemustbecompletedthroughthemiddlelayer.Reflectthetimeintervalisreplacedbythesuccessofanoperationinterface.Imainlyintroducedhere:theloginmodulesystemmanagementmodulestatementsmanagementmodulelogoutsolveChinesegarbledhowtorealizetheauthoritydistributionofCRUDinStrusts
2.Keywords Database;salary;salarymanagement;loginmodule;systemmanagementmodule;reportmanagementmodule;exit;solveChinesegarbled;howtorealizetheauthoritydistributionofCRUDinStrusts
2.目录TOC\o1-3\h\u1绪论
151.1背景
151.2开发思路和计划152系统需求
162.1范围
162.2定义
162.3功能需求173数据库设计
173.1数据流程图
173.2数据字典分析184设计说明
214.1系统概述
214.2数据源的配置
214.3Spring配置
264.4Struts2配置265模块一登录模块
275.1登录模块以及响应基础类BaseAction类的配置
275.2对应类之间的调用
295.3部分算法设计
305.4接口
315.5子功能模块的测试326模块二系统模块
356.1功能模块一部门管理模块实现
356.
1.1Strusts的配置
356.
1.2配置DepartmentAction继承BaseAction
366.
1.2对应类之间的调用
376.
1.3部分算法设计
376.
1.4接口
396.
1.5子功能模块的测试
406.2功能模块二角色管理模块实现
426.
2.1Strusts的配置
426.
2.2配置RoleAction和AclAction继承BaseAction
446.
2.2对应类之间的调用
446.
2.3部分算法设计
476.
2.4接口
496.
2.5子功能模块的测试
506.3功能模块三用户管理模块实现
536.
3.1Strusts的配置
536.
3.2配置UserAction继承BaseAction
546.
3.2对应类之间的调用
556.
3.3部分算法设计
566.
3.4接口
596.
3.5子功能模块的测试597模块七报表管理模块
627.1功能模块一员工报表管理模块实现
627.
1.1Strusts的配置
627.
1.2PersonReportAction继承BaseAction
637.
1.2对应类之间的调用
647.
1.3部分算法设计
647.
1.4接口
687.
1.5子功能模块的测试
687.2功能模块一工资报表管理模块实现
707.
2.1Strusts的配置
707.
2.2PersonReportAction继承BaseAction
717.
2.2对应类之间的调用
727.
2.3部分算法设计
727.
2.4接口
737.
2.5子功能模块的测试748权限控制技术:769技术控制(参考网址http://fangang.iteye.com/blog/47670)7910参考文献:821绪论
1.1背景本次开发是由安博教育和学校发起,学生自主选题的一次毕业设计考虑到市面上的人事管理系统与工资管理系统都是针对个别公司开发的我们有意开发一种通用的,管理权限、部门、以及工资发放形式可以根据不同的公司自行分配和修改的工资管理系统随着现代信息技术和管理理论,建立企业管理信息系统是当今社会的重要趋势“用信息化带动工业化”的指导思想的提出更是中国走向互联网时代的口号对企业而言,全面开发和应用计算机管理信息系统就是近期不能回避的问题在企业管理中,人力资源是企业最宝贵的资源,也是企业的“生命线”,因此人事管理是企业的计算机管理信息系统重要组成部分而工资管理又是人力资源管理的重中之重实行电子化的工资管理,可以让人力资源管理人员从繁重琐碎的案头工作解脱出来,去完成更重要的工作工资管理信息系统的实现可以减轻比较繁琐的手工工资管理
1.2开发思路和计划在和指导老师多次交流后,确定实现方案的要点和工作计划本系统的实现的主要功能有1对系统进行管理用户的添加修改以及权限授予都是管理员操作的2对单位人员的变动进行处理一个单位的职工不会是一成不变的,总是在不断的变化有调出、有调入、也有职工在本单位内部调动因此,设计系统是应考虑到这些情况
(3)对工资账户的创建,修改,删除4对职工的工资进行计算、修改能对各职工的工资进行计算,即计算应发金额、应扣金额及实发金额等5查询统计功能要求即可以单项查询,比如查看某个职工的工资情况等;也可以查询全部
(6)员工个人信息的查询,修改与管理7报表打印功能每月发放工资时,要求能够打印本月的工资表、随工资发给每个职工的工资条以及工资统计表和研究任何其它软件项目一样,我做的毕业设计也经历了从选题,调研,熟悉开发环境,实验关键技术,查找类似的相关系统的资料;系统概要设计,数据库结构设计,功能模块开发,功能模块测试,系统调试和系统试运行和修改如下
1.2-1开发计划流程图图
1.2-1开发计划流程图2系统需求
2.1范围本次开发的系统为工资管理系统用于对小型企业的职工基本信息和工资信息的管理包括系统管理(部门管理、角色管理、用户管理)、报表管理(员工报表管理、工资报表管理)
2.2定义GZGLXTGongZiGuanLiXiTong工资管理系统)的缩写FSFinanceStaff(财务人员)的缩写NFSNorFinanceStaff(非财务人员)的缩写JSPJavaServerPage(Java服务器页面)的缩写,一个脚本化的语言UMLJavaServerPage(Java服务器页面)的缩写,一个脚本化的语言
2.3功能需求1)财务管理端系统管理、人事管理、工资账户管理、工资管理、请假管理、个人信息管理、报表管理2)系统管理
1、部门管理,超级管理员具有系统操作的全部权限,可对部门进行添加(需输入部门名称、部门描述),可对已存在部门进行修改和删除
2、角色管理,可以添加角色(需输入角色名称),可对已存在的角色进行授权,修改其角色名称和删除
3、用户管理,可根据员工编号对员工(姓名、员工编号、职务、所属部门、账号)进行查询,也可以对存在的员工进行分配账号,删除账号和分配角色分配账号时,需输入账号和密码分配角色时,有以下角色可供选择(
1、超级管理员、
2、普通用户、
3、普通员工、
4、部门经理、
5、人力资源经理、
6、财务人员、
7、财务经理、
8、审计员、
9、总经理、
10、项目经理),需根据分配的角色选择相应的优先级3)报表管理
1、员工报表管理,可以选择部门,再将所选部门的员工信息报表生成Excel报表(需选择报表文件存放路径)打印出来
2、工资报表管理,可根据日期查询出某个时间段的工资单报表,生成Excel报表(需选择报表文件存放路径)打印出来3数据库设计
3.1数据流程图1系统管理图3-1系统管理流程图2报表管理图3-2报表流程图
3.2数据字典分析1)模块管理表module-主要用来管理模块的排列和模块的访问路径字段名称数据类型字段大小是否主键说明idint11Y模块编号namevarchar500N模块名称snvarchar500N系统标识urlvarchar500N访问路径orderNovarchar500N优先级标识parentIdint11N父亲模块编号2)用户表(user)-登录系统的用户定义字段名称数据类型字段大小是否主键说明idint11Y用户idusernamevarchar500N用户名称passwordvarchar500N密码personIdint11N员工idcreateTimedatetimeN/YN创建时间3)角色类型表(role)-用户访问系统的权限通过用户角色所授予的权限获得字段名称数据类型字段大小是否主键说明idint11Y角色idnamevarchar500N角色类型id4)用户角色(user_role)-该表通过用户控制角色和权限优先级字段名称数据类型字段大小是否主键说明idint11Y用户角色iduserIdvarchar500N用户idroleIdvarchar500N角色类型idorderNovarchar500N优先级标识5)访问控制表(acl)-访问控制表是应用层在服务器接口的指令列表,这些指令列表通过数字标识确定优先级和告诉服务器允许访问的模块字段名称数据类型字段大小是否主键说明idint11Y权限idprincipalTypevarchar500N授权角色类型principalSnint11N权限优先级标识resourceSnint11N授权模块序号aclStateint11N授权状态aclTriStateint11N启用状态6)员工个人信息报表设计所涉及的表(person)序号姓名性别年龄员工编号职务电话部门住址1超级管理员男10001总公司字段名称数据类型字段大小是否主键说明idint11Y员工idnamevarchar500N员工姓名sexvarchar500N性别ageint11N年龄addressvarchar500N地址phoneint11N电话numberint11N员工编号dutyint11N职务departmentidint11N部门编号groupIdint11N工资组编号descriptiontextY/NN个人简历createTimedatetimeY/NN入职时间7)员工工资报表设计所涉及的表payroll序号姓名员工编号职务部门基本工资增加扣除总金额发薪时间1超级管理员10001总公司7400500079002015-01-15字段名称数据类型字段大小是否主键说明idint11Y序号personIdint11N员工idgroupIdint11N所属工资组号increaseint11N额外奖金reduceint11N扣除费用statusvarchar500N审批状态remarkvarchar500N备注baseint11N应发总薪资opinionvarchar500N审批意见totalint11N实发总薪资payTimedatetimeY/NN发薪资时间createTimedatetimeY/NN添加工资单时间4设计说明
4.1系统概述在本系统中,涉及到很多的就是对数据的增删改查,当然在系统中最重要的部分,是对于这些操作要控制在严格的权限中(应用层)我们利用struts2自身的IoC(反向控制)容器以struts2配置的形式来管理核心组件规范了开发,方便组员分配任务降低了耦合+(持久层)为了防止sql注入式攻击和提高效率(例如多表查询时,通过B表查询A表的值,只需在表B的映射类中变量的类型是表A的映射类),同时延迟装载机制使得数据只有在JSP页面调用的时候才会查询处理,并且Hibernate与数据库类型无关,在分页技术上,没有繁杂的sql语句只需query.setFirstResultFirst;query.setMaxResultsPageSize;所以,我们选择了hibernate操作数据库+(业务层)spring充当了管理容器的角色实现了简单的CRUD操作在mvc与三层架构之间我们选择了三层架构,当然他们本质相同这里采用三层架构,也就是数据访问层、业务逻辑层、表示层这样有利于分工和标准化增加代码的复用性但由于业务无法直接访问数据库必须通过中间层完成反映时间间隔用操作是否成功界面代替
4.2数据源的配置为了防止中文乱码的产生我们将整个项目改为UTF-8,数据库设为UTF-8,由于HTML页面参数—以浏览器的编码方式发送—JSP页面—以JSP定义的编码方式被编译—被JSP引擎编译为*.class文件—在JSP容器中运行—传递给Mysql数据库—以数据库的编码方式读取数据并存储—读取Mysql—以数据库的编码方式读取—JSP页面接受后在浏览器中显示以浏览器编码方式解码显示;我们需要解决问题有1)所有*.jsp的头文件设置为%@pagelanguage=javapageEncoding=UTF-8%以至于在浏览器中直接访问此页面时无乱码数据库设置的是全部使用UTF-8编码,乱码问题归根到底是字符集的问题,查看mysql字符集如下mysqlshowvariableslikecharacter%;+--------------------------+---------------------------------------------------------+|Variable_name|Value|+--------------------------+---------------------------------------------------------+|character_set_client|latin1||character_set_connection|latin1||character_set_database|utf8||character_set_filesystem|binary||character_set_results|latin1||character_set_server|latin1||character_set_system|utf8||character_sets_dir|C:\ProgramFiles\MySQL\MySQLServer
5.5\share\charsets\|+--------------------------+---------------------------------------------------------+修改my.iniMySQLServerInstanceConfiguration文件#CLIENTSECTION[client]port=3306[MySQL]default-character-set=utf-8#SERVERSECTION[MySQLd]default-character-set=utf-82修改data目录中相应数据库目录下的db.opt配置文件default-character-set=utf-8default-collation=utf8_general_ci修改后查看mysql字符集如下mysqlshowvariableslikecharacter%;+--------------------------+---------------------------------------------------------+|Variable_name|Value|+--------------------------+---------------------------------------------------------+|character_set_client|utf8||character_set_connection|utf8||character_set_database|utf8||character_set_filesystem|binary||character_set_results|utf8||character_set_server|utf8||character_set_system|utf8||character_sets_dir|C:\ProgramFiles\MySQL\MySQLServer
5.5\share\charsets\|+--------------------------+---------------------------------------------------------+8rowsinset
0.00sec3数据库连接串中指定字符集URL=jdbc:MySQL://yourIP/collegeuser=rootpassword=123useUnicode=truecharacterEncoding=utf-84在创建数据库时指定字符集createdatabasegzglxtCHARACTERSETutf-8;根据数据库设计建表,使用Mysql界面软件SQLyog-
8.
7.1并做POJO持久化的数据库的映射对象,并实现序列化以便扩展,当然而在Struts2中的Action由于可以不继承任何的接口,所以在这种情况下Action是POJO,但是Struts2中的Action也可以继承ActionSupport类就不再属于POJO了POJO里面是可以包含业务逻辑处理和持久化逻辑,也可以包含类似与JavaBean属性和对属性访问的set和get方法的对hibernate.cfg.xml做如下配置xmlversion=
1.0encoding=UTF-8!DOCTYPEhibernate-configurationPUBLIC-//Hibernate/HibernateConfigurationDTD
3.0//ENhttp://hibernate.sourceforge.net/hibernate-configuration-
3.
0.dtd!--GeneratedbyMyEclipseHibernateTools.--hibernate-configurationsession-factorypropertyname=connection.usernameroot/propertypropertyname=connection.password123/propertypropertyname=connection.urljdbc:mysql://
127.
0.
0.1:3306/gzglxt/propertypropertyname=dialectorg.hibernate.dialect.MySQLDialect/propertypropertyname=myeclipse.connection.profilemysql/propertypropertyname=connection.driver_classcom.mysql.jdbc.Driver/propertypropertyname=show_sqltrue/propertypropertyname=c3p
0.max_size30/propertypropertyname=c3p
0.min_size5/propertypropertyname=c3p
0.timeout3000/propertypropertyname=c3p
0.max_statements100/propertymappingclass=cs.xj.pojo.Department/mappingclass=cs.xj.pojo.Role/mappingclass=cs.xj.pojo.Payroll/mappingclass=cs.xj.pojo.UserRole/mappingclass=cs.xj.pojo.Group/mappingclass=cs.xj.pojo.Change/mappingclass=cs.xj.pojo.User/mappingclass=cs.xj.pojo.Person/mappingclass=cs.xj.pojo.GroupDetail/mappingclass=cs.xj.pojo.Leave/mappingclass=cs.xj.pojo.Account/mappingclass=cs.xj.pojo.Module/mappingclass=cs.xj.pojo.ACL//session-factory/hibernate-configuration2)Hibernate与POJO对像的交互流程图如下图4-2Hibernate与POJO对像的交互流程图图
4.3Spring配置Spring作为业务层,结合hibernateFilter文件处理,filterfilter-namehibernateFilter/filter-namefilter-classorg.springframework.orm.hibernate
3.support.OpenSessionInViewFilter/filter-class/filterfilter-mappingfilter-namehibernateFilter/filter-nameurl-pattern/*/url-pattern/filter-mapping
4.4Struts2配置为了简化Struts2的配置,是编程更容易模块化进行,可以通过对各个Action对应的xml文件的调度,对各个Action进行调度xmlversion=
1.0encoding=UTF-8!DOCTYPEstrutsPUBLIC-//ApacheSoftwareFoundation//DTDStrutsConfiguration
2.0//ENhttp://struts.apache.org/dtds/struts-
2.
0.dtdstrutsconstantname=devModevalue=true/packagename=baseextends=struts-defaultnamespace=/!--退出登录配置--actionname=zhuXiaoclass=zhuxiao.ZhuXiaoActionresultname=success/index.jsp/result/action/packageincludefile=cs/xj/action/login/login.xml/!--登录管理--includefile=cs/xj/action/department/department.xml/!--部门管理--includefile=cs/xj/action/role/role.xml/!--角色管理--includefile=cs/xj/action/user/user.xml/!--用户管理--includefile=cs/xj/action/acl/acl.xml/!--权限分配管理--includefile=cs/xj/action/personReport/personReport.xml/!--生成员工信息报表管理--includefile=cs/xj/action/payrollReport/payrollReport.xml/!--生成工资信息报表管理--/struts5模块一登录模块
5.1登录模块以及响应基础类BaseAction类的配置1)运用strusts2开发需要一个动作对应到一个Action,但这些Action的有些属性和方法是相同的,本系统中我们用到了调用数据库对应模块的路径实现分层调用,该类继承ActionSupport并重载(Override)的execute方法把客户端请求request和服务端响应response,session会话的处理在Baseaction中封装并利用Java反射技术对ModelDriven实现抽象BaseAction代码如下publicabstractclassBaseActionextendsActionSupportimplementsServletRequestAwareServletResponseAwareSessionAwareModelDrivenObjectPreparable{privatestaticfinallongserialVersionUID=6813377869976477588L;protectedHttpServletRequestrequest;//客户端请求protectedHttpServletResponseresponse;//服务端响应protectedMapStringObjectsession;//会话protectedStringnotice;//提示信息//前提publicvoidpreparethrowsException{}//执行重写方法@OverridepublicStringexecutethrowsException{returnSUCCESS;}//响应模块publicObjectgetModel{returnnull;}//设置客户端请求方法publicvoidsetServletRequestHttpServletRequestrequest{this.request=request;}//设置服务端相应方法publicvoidsetServletResponseHttpServletResponseresponse{this.response=response;}//设置Session会话方法publicvoidsetSessionMapStringObjectsession{this.session=session;}//得到提示信息的方法publicStringgetNotice{returnnotice;}//设置提示信息的方法publicvoidsetNoticeStringnotice{this.notice=notice;}//sql中isnull函数,使用指定的替换值替换NULLpublicbooleanisNullStringvalue{returnvalue==null||.equalsvalue;}}2)配置LoginAction继承BaseAction通过调用UserService接口中的loginStringusernameStringpassword方法用session.putloginuser;result=SUCCESS;实现数据库user表的映射登录模块对应的流程图5-1图5-1系统登录流程图
5.2对应类之间的调用1)用户登录时类间的调用图5-2用户登录时类间的调用流程图2)登录页面index.jsp获取表单中的用户名和密码函数scripttype=text/javascriptlanguage=javascriptfunctionsubmitForm{document.getElementByIdloginForm.submit;}/script3)主页面pay_main.jsp包含top.jsp顶部框架、left.jsp左侧模块显示框架、内容body、底部footer.jsp框架部分代码如下framesetrows=120*60framespacing=0frameborder=noframename=bannerscrolling=nonoresizesrc=${cxt}/pages/top.jspframesetcols=168*framespacing=0frameborder=noid=mainframeChangeframename=contentsscrolling=nonoresizesrc=${cxt}/pages/left.jspframename=mainsrc=${cxt}/pages/main.jsp/framesetframename=banner1scrolling=nonoresizesrc=${cxt}/pages/footer.jspnoframesbodyLEFTMARGIN=0TOPMARGIN=0MARGINWIDTH=0MARGINHEIGHT=0/body/noframes/frameset
5.3部分算法设计1)登录方法@InputConfigresultName=loginInputpublicStringloginthrowsException{Useruser=userService.loginusernamepassword;Stringresult=;ifuser!=null{session.putloginuser;result=SUCCESS;}else{session.putnotice账号或密码不正确;result=LOGIN;}returnresult;}publicStringlogoutthrowsException{session.clear;returnlogout;}//验证publicvoidvalidateLogin{ifisNullusername{addFieldErrorusername账号不能为空;}ifisNullpassword{addFieldErrorpassword密码不能为空;}}2)查找模块id的算法publicStringfindModulesthrowsException{Useruser=Usersession.getlogin;//保存User对象为loginmodules=newArrayListModule;//设置模块集合moduleList=newArrayListModuleList;modules=aclService.findModulesuser.getId;ModuleListml=null;forModulem:modules{ifm.getModule==null{ml=newModuleList;ml.setParentm;forModulemod:modules{//增强for循环ifmod.getModule!=nullm.getId.equalsmod.getModule.getId{ml.getChild.addmod;}}moduleList.addml;}}count=moduleList.size;//获得模块的大小session.putmoduleListmoduleList;//抛出模块列表session.putcountcount;returnfindModules;}
5.4接口1)登录模块接口调用图图5-3用户登录登录模块接口调用图
5.5子功能模块的测试1管理员登录测试图2部门经理登录测试3)通过用户服务接口操作用户表的测试代码publicclassUserServiceTestextendsTestCase{privateUserServiceuserService;//用户服务接口protectedvoidsetUpthrowsException{ApplicationContextcxt=newFileSystemXmlApplicationContext/WebRoot/WEB-INF/applicationContext.xml;userService=UserServicecxt.getBeanuserService;}@TestpublicvoidtestSaveOrUpdate{Useru=newUser;u.setUsername李二;u.setPasswordli;userService.saveOrUpdateu5;}publicvoidtestFindByUsername{Useru=userService.findByUsernamezy;System.out.printlnu.getUsername;}publicvoidtestLogin{Useru=userService.loginadminadmin;System.out.printlnu;}@TestpublicvoidtestDelete{Useru=userService.findById17;userService.deleteu;}publicvoidtestFindUserRole{ListUserRoleuserRole=userService.findUserRole1;System.out.printlnuserRole;}}4)通过权限控制服务接口操作数据库用户角色表的测试代码publicclassAclServiceTestextendsTestCase{privateAclServiceaclService;//权限控制服务接口@BeforeprotectedvoidsetUpthrowsException{ApplicationContextcxt=newFileSystemXmlApplicationContext/WebRoot/WEB-INF/applicationContext.xml;aclService=AclServicecxt.getBeanaclService;}@TestpublicvoidtestSave{ACLacl=newACL;acl.setPrincipalTypeRole;acl.setPrincipalSn2;acl.setResourceSn19;acl.setPermission1true;aclService.saveOrUpdateacl;}publicvoidtestSaveOrUpdatePermission{aclService.saveOrUpdatePermissionRole1080true;}publicvoidtestfindACLs{ListObject[]list=aclService.findACLsRole1;forObject[]obj:list{forObjecto:obj{System.out.printo+---;}System.out.println;}}}6模块二系统模块
6.1功能模块一部门管理模块实现
6.
1.1Strusts的配置运用strusts2开发需要一个动作对应到一个Action,但这些Action的有些属性和方法是相同的,本系统中我们用到了调用数据库对应模块的路径实现分层调用,系统管理模块,需要在包中添加包含文件includefile=cs/xj/action/department/department.xml/!--部门管理--Department.xml的配置如下xmlversion=
1.0encoding=UTF-8!DOCTYPEstrutsPUBLIC-//ApacheSoftwareFoundation//DTDStrutsConfiguration
2.0//ENhttp://struts.apache.org/dtds/struts-
2.
0.dtdstrutspackagename=departmentextends=struts-defaultnamespace=/departmentinterceptorsinterceptorname=securityInterceptorclass=cs.xj.interceptor.SecurityInterceptor/interceptor/interceptorsglobal-resultsresultname=error/pages/pay_main.jsp/resultresultname=logintype=redirect/index.jsp/result/global-resultsactionname=departmentActionclass=cs.xj.action.department.DepartmentAction!--departmentAction对应的Action--resultname=find/pages/department/department.jsp/result!--显示部门管理界面--resultname=select/pages/department/select_dep.jsp/result!--显示查找部门管理界面--resultname=add/pages/department/add_dep.jsp/result!--显示添加部门管理界面--resultname=saveInput/pages/department/add_dep.jsp/result!--显示保存部门管理界面--resultname=savetype=redirect/pages/common/success.jsp/result!--显示添加部门管理成功界面--resultname=show/pages/department/show_dep.jsp/result!--显示部门管理界面--resultname=edit/pages/department/edit_dep.jsp/result!--显示修改部门管理界面--resultname=updateInput/pages/department/edit_dep.jsp/result!--显示修改部门管理界面保存--resultname=updatetype=redirect/pages/common/success.jsp/result!--显示部门管理成功界面--resultname=deletetype=redirect/pages/common/del_success.jsp/result!--显示删除部门管理成功界面--interceptor-refname=paramsPrepareParamsStack/interceptor-refinterceptor-refname=securityInterceptor/interceptor-ref/action/package/struts
6.
1.2配置DepartmentAction继承BaseAction通过调用DepartmentService接口中的方法用实现数据库表department的操作部门管理模块对应的流程图5-1图5-1部门管理流程图
6.
1.2对应类之间的调用1)进行部门管理时类间的调用图5-2进行部门管理时类间的调用流程图2)添加部门界面add_dep.jsp验证部门名称的函数scripttype=text/javascriptlanguage=javascriptfunctionsubmitForm{varname=document.getElementByIddepName;ifname.value.length==0{alert部门名称不能为空;return;}document.getElementByIddepForm.submit;}/script
6.
1.3部分算法设计1Action中的查找方法publicStringfindthrowsException{intoffset=0;try{offset=Integer.parseIntrequest.getParameterpager.offset;}catchRuntimeExceptione{}pagerModel=departmentService.findoffsetPageSize.NORMAL;iftrue.equalsselect{returnselect;}returnfind;}2)Action中的添加部门的方法publicStringaddthrowsException{returnadd;}//添加部门@InputConfigresultName=saveInputpublicStringsavethrowsException{departmentService.saveOrUpdatedepartment;session.putnotice添加部门成功;returnsave;}//验证publicvoidvalidateSave{ifisNulldepartment.getName{addFieldErrorname部门名称不能为空;}elseifdepartmentService.findByNamedepartment.getName!=null{addFieldErrorname部门名称已存在;}}3)Action中的客服端响应方法publicStringshowthrowsException{request.setAttributedepdepartment;returnshow;}4)Action中的修改部门的方法publicStringeditthrowsException{request.setAttributedepdepartment;returnedit;}//修改@InputConfigresultName=updateInputpublicStringupdatethrowsException{departmentService.saveOrUpdatedepartment;session.putnotice修改部门成功;returnupdate;}//验证publicvoidvalidateUpdate{ifisNulldepartment.getName{addFieldErrorname部门名称不能为空;}else{Departmentdep=departmentService.findByNamedepartment.getName;ifdep!=null{ifdepartment.getName.equalsdep.getName!department.getId.equalsdep.getId{addFieldErrorname部门名称已存在;}}}}5)Action中的删除部门的方法publicStringdeletethrowsException{departmentService.deletedepartment;session.putnotice删除部门成功;returndelete;}
6.
1.4接口2)部门管理模块接口调用图图6-1部门管理模块接口调用图
6.
1.5子功能模块的测试1)部门管理显示部门测试图2)添加部门测试3)修改部门测试4)删除部门测试5)操作数据库部门表的测试的测试代码publicclassDepartmentServiceTestextendsTestCase{privateDepartmentServicedepartmentService;//部门管理业务操作服务接口@BeforeprotectedvoidsetUpthrowsException{ApplicationContextcxt=newFileSystemXmlApplicationContext/WebRoot/WEB-INF/applicationContext.xml;departmentService=DepartmentServicecxt.getBeanDepartmentService;}@Testpublicvoidtestfind{Departmentdpt=departmentService.findById1;System.out.printlndpt.getName;}@Test//添加和保存部门publicvoidtestsaveOrUpdateDepartmentd{Departmentdept=newDepartment;dept.setId21;dept.setName人事部;dept.setDescriptionhhhhhh;departmentService.saveOrUpdatedept;}}
6.2功能模块二角色管理模块实现
6.
2.1Strusts的配置运用strusts2开发需要一个动作对应到一个Action,但这些Action的有些属性和方法是相同的,本系统中我们用到了调用数据库对应模块的路径实现分层调用,权限管理模块,需要在包中添加包含文件includefile=cs/xj/action/role/role.xml/!--角色管理--includefile=cs/xj/action/acl/acl.xml/!--权限分配管理--role.xml的配置如下strutspackagename=roleextends=struts-defaultnamespace=/roleinterceptorsinterceptorname=securityInterceptorclass=cs.xj.interceptor.SecurityInterceptor/interceptor/interceptorsglobal-resultsresultname=error/pages/pay_main.jsp/resultresultname=logintype=redirect/index.jsp/result/global-resultsactionname=roleActionclass=cs.xj.action.role.RoleActionresultname=find/pages/role/role.jsp/result!--角色管理界面--resultname=select/pages/role/select_role.jsp/result!--角色分配界面--resultname=add/pages/role/add_role.jsp/result!--添加角色--resultname=saveInput/pages/role/add_role.jsp/result!--添加角色保存--resultname=savetype=redirect/pages/common/success.jsp/result!--添加角色成功--resultname=edit/pages/role/edit_role.jsp/result!--修改角色--resultname=updateInput/pages/role/edit_role.jsp/result!--修改角色保存--resultname=updatetype=redirect/pages/common/success.jsp/result!--添加角色成功--resultname=deletetype=redirect/pages/common/del_success.jsp/result!--删除角色成功--interceptor-refname=paramsPrepareParamsStack/interceptor-refinterceptor-refname=securityInterceptor/interceptor-ref/action/package/strutsacl.xml的配置如下xmlversion=
1.0encoding=UTF-8!DOCTYPEstrutsPUBLIC-//ApacheSoftwareFoundation//DTDStrutsConfiguration
2.0//ENhttp://struts.apache.org/dtds/struts-
2.
0.dtdstrutspackagename=aclextends=struts-defaultnamespace=/aclactionname=aclActionclass=cs.xj.action.acl.AclActionresultname=find/pages/acl/acl.jsp/result!--权限分配界面--!--defaultStack无法接收prepare需要的数据,而应借助paramsPrepareParamsStack拦截器栈--interceptor-refname=paramsPrepareParamsStack/interceptor-ref/action/package/struts
6.
2.2配置RoleAction和AclAction继承BaseActionRoleAction通过调用RoleService接口中的方法用实现数据库表role的操作AclAction通过调用AclService、UserService、RoleService、ModuleService接口中的方法用实现数据库表acl、user、moudule的操作角色管理模块对应的流程图6-1图6-1角色管理流程图
6.
2.2对应类之间的调用1)进行角色管理时类间的调用图5-2进行角色管理时类间的调用流程图2)添加角色界面add_role.jsp验证角色名称的函数scripttype=text/javascriptlanguage=javascriptfunctionsubmitForm{varname=document.getElementByIdroleName;ifname.value.length==0{alert角色名称不能为空;return;}document.getElementByIdroleForm.submit;}/script3)role.jsp界面删除角色的函数scripttype=text/javascriptfunctionopenDeleteDialogurlconfirmString{varc=confirmString;ifconfirmc{returnwindow.showModalDialogurlwindow123dialogHeight:150px;dialogWidth:350px;resizable:no;help:yes;status:no;scroll:no;}returnfalse;}functiondelurlinfo{ifopenDeleteDialogurlinfo{window.location.reloadtrue;}}/script4)授权acl.jsp界面修改或保存函数权限的函数scripttype=text/javascript//修改或保存函数functionsaveOrUpdatePermissionfield{iffield.checked{if!$field.resourceSn+_USE.checked{$field.resourceSn+_USE.checked=true;}c:iftest=${acl.principalTypeeqUser}if!$field.resourceSn+_EXT.checked{$field.resourceSn+_EXT.checked=true;}/c:if}aclService.saveOrUpdatePermission${acl.principalType}${acl.principalSn}field.resourceSnfield.permissionfield.checked;}functionsaveOrUpdateUserExtendsfield{aclService.saveOrUpdateUserExtends${acl.principalSn}field.resourceSn!field.checked;}functionusePermissionfield{dwr.engine.setAsyncfalse;iffield.checked{saveOrUpdatePermission$field.resourceSn+_C;saveOrUpdatePermission$field.resourceSn+_R;saveOrUpdatePermission$field.resourceSn+_U;saveOrUpdatePermission$field.resourceSn+_D;c:iftest=${acl.principalTypeeqUser}saveOrUpdateUserExtends$field.resourceSn+_EXT;/c:if}else{aclService.deletePermission${acl.principalType}${acl.principalSn}field.resourceSn;$field.resourceSn+_C.checked=false;$field.resourceSn+_R.checked=false;$field.resourceSn+_U.checked=false;$field.resourceSn+_D.checked=false;c:iftest=${acl.principalTypeeqUser}$field.resourceSn+_EXT.checked=false;/c:if}}functioninitACL{/*alert${acl.principalType}++${acl.principalSn};*/aclService.findACLs${acl.principalType}${acl.principalSn}functiondata{forvari=0;idata.length;i++{varresourceSn=data[i]
[0];varcState=data[i]
[1];varrState=data[i]
[2];varuState=data[i]
[3];vardState=data[i]
[4];varextState=data[i]
[5];$resourceSn+_C.checked=cState==0false:true;$resourceSn+_R.checked=rState==0false:true;$resourceSn+_U.checked=uState==0false:true;$resourceSn+_D.checked=dState==0false:true;c:iftest=${acl.principalTypeeqUser}$resourceSn+_EXT.checked=extState==0true:false;/c:if$resourceSn+_USE.checked=true;}};}/script5)
6.
2.3部分算法设计1RoleAction中的查看角色方法publicStringfindthrowsException{intoffset=0;try{offset=Integer.parseIntrequest.getParameterpager.offset;}catchRuntimeExceptione{}pagerModel=roleService.findoffsetPageSize.NORMAL;iftrue.equalsselect{returnselect;}returnfind;}2)RoleAction中的添加角色的方法publicStringaddthrowsException{returnadd;}@InputConfigresultName=saveInputpublicStringsavethrowsException{roleService.saveOrUpdaterole;session.putnotice添加角色成功;returnsave;}publicvoidvalidateSave{ifisNullrole.getName{addFieldErrorname角色名称不能为空;}elseifroleService.findByNamerole.getName!=null{addFieldErrorname角色名称已存在;}}3)AclAction中的获得模块的方法publicStringfindthrowsException{ifACL.TYPE_USER.equalsacl.getPrincipalType{user=userService.findByIdacl.getPrincipalSn;}elseifACL.TYPE_ROLE.equalsacl.getPrincipalType{role=roleService.findByIdacl.getPrincipalSn;//获取优先级}modules=moduleService.findnewString[]{module}newObject[]{null}0Integer.MAX_VALUE.getDatas;//得到模块returnfind;}
6.
2.4接口5)角色管理模块接口调用图图6-1角色管理模块接口调用图
6.
2.5子功能模块的测试1)角色管理首页测试图2)添加角色测试3)修改角色测试4)删除角色测试5)为财务人员授权6)通过权限控制服务接口操作数据库用户角色表的测试代码publicclassAclServiceTestextendsTestCase{privateAclServiceaclService;//权限控制服务接口@BeforeprotectedvoidsetUpthrowsException{ApplicationContextcxt=newFileSystemXmlApplicationContext/WebRoot/WEB-INF/applicationContext.xml;aclService=AclServicecxt.getBeanaclService;}@TestpublicvoidtestSave{ACLacl=newACL;acl.setPrincipalTypeRole;acl.setPrincipalSn2;acl.setResourceSn19;acl.setPermission1true;aclService.saveOrUpdateacl;}publicvoidtestSaveOrUpdatePermission{aclService.saveOrUpdatePermissionRole1080true;}publicvoidtestfindACLs{ListObject[]list=aclService.findACLsRole1;forObject[]obj:list{forObjecto:obj{System.out.printo+---;}System.out.println;}}}
6.3功能模块三用户管理模块实现
6.
3.1Strusts的配置运用strusts2开发需要一个动作对应到一个Action,但这些Action的有些属性和方法是相同的,本系统中我们用到了调用数据库对应模块的路径实现分层调用,用户管理模块,需要在包中添加包含文件includefile=cs/xj/action/user/user.xml/!--用户管理--user.xml的配置如下strutspackagename=userextends=struts-defaultnamespace=/userinterceptorsinterceptorname=securityInterceptorclass=cs.xj.interceptor.SecurityInterceptor/interceptor/interceptorsglobal-resultsresultname=error/pages/pay_main.jsp/resultresultname=logintype=redirect/index.jsp/result/global-resultsactionname=userActionclass=cs.xj.action.user.UserActionresultname=find/pages/user/user.jsp/result!--用户界面--resultname=addUser/pages/user/add_user.jsp/result!--添加用户界面--resultname=saveUserInput/pages/user/add_user.jsp/result!--添加用户界面--resultname=saveUsertype=redirect/pages/common/success.jsp/resultresultname=passwordtype=redirect/pages/common/success.jsp/resultresultname=deleteUsertype=redirect/pages/common/del_success.jsp/resultresultname=showUserRole/pages/user/show_user_role.jsp/result!--分配用户角色界面--resultname=saveUserRoletype=redirect/pages/common/success.jsp/resultresultname=saveUserRoleInput/pages/role/select_role.jsp/result!--分配用户角色界面--resultname=deleteUserRoletype=redirect/pages/common/del_success.jsp/resultinterceptor-refname=paramsPrepareParamsStack/interceptor-refinterceptor-refname=securityInterceptor/interceptor-ref/action/package/struts
6.
3.2配置UserAction继承BaseActionUserAction通过调用UserService接口中的方法用实现数据库表user的操作用户管理模块对应的流程图6-1图6-1用户管理流程图
6.
3.2对应类之间的调用1)进行用户管理时类间的调用图5-2进行用户管理时类间的调用流程图2)用界面user.jsp进行用户操作的函数scripttype=text/javascriptfunctionaddRoleuserNameuserId{varname=userName;varid=userId;ifname.length==0{alert请先给用户分配账号;return;}window.open${cxt}/user/userAction!showUserRoleid=+idshowUserRolewidth=500height=320top=250rezisable=yesscrollbars=yes}functionopenDeleteDialogurlconfirmString{varc=confirmString;ifconfirmc{returnwindow.showModalDialogurlwindow123dialogHeight:150px;dialogWidth:350px;resizable:no;help:yes;status:no;scroll:no;}returnfalse;}functiondelurlinfo{ifopenDeleteDialogurlinfo{window.location.reloadtrue;}}/script3)select_role.jsp界面选择角色的函数scripttype=text/javascriptfunctionsubmitForm{varno=document.getElementByIdorderNo;ifno.value.length==0{alert优先级不能为空;return;}document.getElementByIdroleForm.submit;}/script
6.
3.3部分算法设计1UserAction类中的方法根据员工编号查询publicStringfindthrowsException{intoffset=0;try{offset=Integer.parseIntrequest.getParameterpager.offset;}catchRuntimeExceptione{}ifpersonNumber!=null{pagerModel=personService.findnewString[]{number}newString[]{personNumber}newMatchMode[]{MatchMode.ANYWHERE}offsetPageSize.NORMAL;}else{pagerModel=personService.findoffsetPageSize.NORMAL;}returnfind;}2UserAction类中的方法分配账号publicStringaddUserthrowsException{person=personService.findByIdpersonId;request.setAttributepersonperson;returnaddUser;}@InputConfigresultName=saveUserInputpublicStringsaveUserthrowsException{userService.saveOrUpdateuserpersonId;session.putnotice分配账号成功;returnsaveUser;}publicvoidvalidateSaveUser{ifisNulluser.getUsername{addFieldErrorusername账号不能为空;}else{Useru=userService.findByUsernameuser.getUsername;ifu!=null{ifuser.getUsername.equalsu.getUsername!u.getId.equalsuser.getId{addFieldErrorusername账号已存在;}}}ifisNulluser.getPassword{addFieldErrorpassword密码不能为空;}}3UserAction类中的方法删除账号publicStringdeleteUserthrowsException{userService.deleteuser;session.putnotice删除账号成功;returndeleteUser;}4)显示用户角色publicStringshowUserRolethrowsException{userRole=userService.findUserRoleid;returnshowUserRole;}5)分配角色@InputConfigresultName=saveUserRoleInputpublicStringsaveUserRolethrowsException{userService.saveOrUpdateUserRoleidroleIdorderNo;session.putnotice分配角色成功;returnsaveUserRole;}publicvoidvalidateSaveUserRole{ifroleId==null||roleId==0{addFieldErrorroleId角色不能为空;}iforderNo==null||orderNo==0{addFieldErrororderNo优先级不能为空;}}6UserAction类中的方法删除用户角色publicStringdeleteUserRolethrowsException{userService.deleteUserRoleidroleId;session.putnotice删除角色成功;returndeleteUserRole;}@InputConfigresultName=passwordInputpublicStringpasswordthrowsException{userService.saveOrUpdateuser;session.putloginuser;session.putnotice密码修改成功;returnpassword;}publicvoidvalidatePassword{ifisNulluser.getPassword{addFieldErrorpassword密码不能为空;}}
6.
3.4接口1用户管理模块接口调用图图6-1角色管理模块接口调用图
6.
3.5子功能模块的测试1)用户管理首页测试图2)分配账户测试图3)删除账号测试图4)分配角色测试图6)通过用户服务接口操作用户表的测试代码publicclassAclServiceTestextendsTestCase{privateAclServiceaclService;//权限控制服务接口@BeforeprotectedvoidsetUpthrowsException{ApplicationContextcxt=newFileSystemXmlApplicationContext/WebRoot/WEB-INF/applicationContext.xml;aclService=AclServicecxt.getBeanaclService;}@TestpublicvoidtestSave{ACLacl=newACL;acl.setPrincipalTypeRole;acl.setPrincipalSn2;acl.setResourceSn19;acl.setPermission1true;aclService.saveOrUpdateacl;}publicvoidtestSaveOrUpdatePermission{aclService.saveOrUpdatePermissionRole1080true;}publicvoidtestfindACLs{ListObject[]list=aclService.findACLsRole1;forObject[]obj:list{forObjecto:obj{System.out.printo+---;}System.out.println;}}}7模块七报表管理模块
7.1功能模块一员工报表管理模块实现
7.
1.1Strusts的配置由于POI的稳定性,我选择了POI报表技术,运用strusts2开发需要一个动作对应到一个Action,但这些Action的有些属性和方法是相同的,本系统中我们用到了调用数据库对应模块的路径实现分层调用,报表管理模块,需要在包中添加包含文件includefile=cs/xj/action/personReport/personReport.xml/!--生成员工信息报表管理--personReport.xml的配置如下strutspackagename=personReportextends=struts-defaultnamespace=/personReportinterceptorsinterceptorname=securityInterceptorclass=cs.xj.interceptor.SecurityInterceptor/interceptor/interceptorsglobal-resultsresultname=error/pages/pay_main.jsp/resultresultname=logintype=redirect/index.jsp/result/global-resultsactionname=personReportActionclass=cs.xj.action.personReport.PersonReportActionresultname=find/pages/personReport/person_report.jsp/result!--员工信息报表管理系统--resultname=getExceltype=streamparamname=contentTypeapplication/vnd.ms-excel/paramparamname=contentDispositionfilename=persons.xls/param!--初始化报表名称--paramname=inputNamedownloadFile/param/resultinterceptor-refname=paramsPrepareParamsStack/interceptor-refinterceptor-refname=securityInterceptorparamname=includeMethodsfindgetExcel/param/interceptor-ref/action/package/struts
7.
1.2PersonReportAction继承BaseAction通过调用DepartmentService接口中的方法用实现数据库表department、person的操作员工报表管理模块对应的流程图5-1图5-1员工报表管理流程图
7.
1.2对应类之间的调用1)进行员工报表管理时类间的调用图5-2进行员工报表管理时类间的调用流程图2)person_report.jsp页面获取员工表单的函数scripttype=text/javascriptfunctionsubmitForm{document.getElementByIdpersonForm.submit;}/script
7.
1.3部分算法设计1Action中的获得报表信息方法publicStringfindthrowsException{intoffset=0;try{offset=Integer.parseIntrequest.getParameterpager.offset;//总条数,基于pager-taglib包JavaWeb的分页设计}catchRuntimeExceptione{}pagerModel=personService.findnewString[]{department}newObject[]{department}offsetPageSize.NORMAL;//显示条数为10forPersonp:pagerModel.getDatas{//增强for循环得到员工报表数据条数ifp.getDepartment!=null{System.out.printlnp.getDepartment.getName;}}returnfind;}}returnfind;}2)输出员工报表excel的数据流方法@TransactionalreadOnly=true//方法重新定义publicInputStreamgetInputStreamString[]propertyNameObject[]value{HSSFWorkbookwbexcel=newHSSFWorkbook;//创建一个无任何内容的excel工作表HSSFSheetsheet=wbexcel.createSheetsheet1;//在已创建的excel工作表对象中创建一个图表//在已创建的图表中创建行:HSSFRowrow=HSSFSheet对象.createRowshort从0开始的行号;HSSFRowrow=sheet.createRow0;//在已创建的行中创建单元格:HSSFCellcell=HSSFRow对象.createCellshort从0开始的列号;HSSFCellcell=row.createCellshort0;cell.setEncodingHSSFCell.ENCODING_UTF_16;//每个单元格都要设置编码格式,但在poi
3.5中已经没有了cell.setEncoding方法来设置编码了cell.setCellValue序号;cell=row.createCellshort1;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValue姓名;cell=row.createCellshort2;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValue性别;cell=row.createCellshort3;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValue年龄;cell=row.createCellshort4;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValue员工编号;cell=row.createCellshort5;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValue职务;cell=row.createCellshort6;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValue电话;cell=row.createCellshort7;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValue部门;cell=row.createCellshort8;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValue住址;//到此表头已经设计好了ListPersonlist=personDao.findpropertyNamevalue0Integer.MAX_VALUE.getDatas;//获取数据库信息forinti=0;ilist.size;i++{//循环迭代Personp=list.geti;//获得一条记录Departmentd=p.getDepartment;row=sheet.createRowi+1;//产生下面的其他行cell=row.createCellshort0;//第一个单元格cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValuei+1;//向单元格里面添加值cell=row.createCellshort1;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValuep.getName;cell=row.createCellshort2;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValuep.getSex;cell=row.createCellshort3;cell.setEncodingHSSFCell.ENCODING_UTF_16;ifp.getAge!=null{cell.setCellValuep.getAge;}else{cell.setCellValue;}cell=row.createCellshort4;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValuep.getNumber;cell=row.createCellshort5;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValuep.getDuty;cell=row.createCellshort6;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValuep.getPhone;cell=row.createCellshort7;cell.setEncodingHSSFCell.ENCODING_UTF_16;ifd!=null{cell.setCellValued.getName;}else{cell.setCellValue;}cell=row.createCellshort8;cell.setEncodingHSSFCell.ENCODING_UTF_16;cell.setCellValuep.getAddress;}/**以上就生成了所需的excel文件*下面写另外一个方法直接不产生临时文件,就在内存中*/ByteArrayOutputStreamos=newByteArrayOutputStream;//字节数组输出流try{wbexcel.writeos;//将对象写入硬盘}catchIOExceptione{e.printStackTrace;}byte[]content=os.toByteArray;InputStreamis=newByteArrayInputStreamcontent;returnis;}
7.
1.4接口6)部门管理模块接口调用图图6-1部门管理模块接口调用图
7.
1.5子功能模块的测试1)员工报表管理显示测试图2)选着部门测试7)员工查询测试图7)操作个人信息服务接口方法的测试代码publicclassPersonServiceTestextendsTestCase{@Resourcename=personServiceprivatePersonServicepersonService;@Resourcename=departmentServiceprivateDepartmentServicedepartmentService;/*setup主要实现测试前的初始化工作,而teardown则主要实现测试完成后的垃圾回收等工作*/protectedvoidsetUpthrowsException{ApplicationContextcxt=newFileSystemXmlApplicationContext/WebRoot/WEB-INF/applicationContext.xml;personService=PersonServicecxt.getBeanpersonService;departmentService=DepartmentServicecxt.getBeandepartmentService;}//删除测试publicvoidtestDelete{System.out.printlnpersonService.findById21;personService.deletepersonService.findById21;}publicvoidtestDeleteAll{}//获取部门测试publicvoidtestGetInputStream{personService.getInputStreamnewString[]{department}newObject[]{null};}publicvoidtestFind{System.out.printlnpersonService.findnewString[]{department}newObject[]{departmentService.findById1}0Integer.MAX_VALUE;}}
7.2功能模块一工资报表管理模块实现
7.
2.1Strusts的配置运用strusts2开发需要一个动作对应到一个Action,但这些Action的有些属性和方法是相同的,本系统中我们用到了调用数据库对应模块的路径实现分层调用,系统管理模块,需要在包中添加包含文件includefile=cs/xj/action/payrollReport/payrollReport.xml/!--生成工资信息报表管理--payrollReport.xml的配置如下strutspackagename=payrollReportextends=struts-defaultnamespace=/payrollReportinterceptorsinterceptorname=securityInterceptorclass=cs.xj.interceptor.SecurityInterceptor/interceptor/interceptorsglobal-resultsresultname=error/pages/pay_main.jsp/resultresultname=logintype=redirect/index.jsp/result/global-resultsactionname=payrollReportActionclass=payrollReportActionresultname=find/pages/payrollReport/payroll_report.jsp/result!--工资报表管理界面--resultname=getExceltype=streamparamname=contentTypeapplication/vnd.ms-excel/paramparamname=contentDispositionfilename=personssalary.xls/param!--生成excel表personssalary.xls--paramname=inputNamedownloadFile/param/resultinterceptor-refname=paramsPrepareParamsStack/interceptor-refinterceptor-refname=securityInterceptorparamname=includeMethodsfindgetExcel/param/interceptor-ref/action/package/struts
7.
2.2PersonReportAction继承BaseAction通过调用DepartmentService接口中的方法用实现数据库表department、person的操作工资报表管理模块对应的流程图5-1图5-1工资报表管理流程图
7.
2.2对应类之间的调用1)进行员工报表管理时类间的调用图5-2进行员工报表管理时类间的调用流程图2)payroll_report.jsp页面获取工资表单的代码%ifrequest.getParameterfirstDay!=nullrequest.getParameterlastDay!=null{%ahref=${cxt}/payrollReport/payrollReportAction!getExcelfirstDay=%=request.getParameterfirstDay%lastDay=%=request.getParameterlastDay%style=color:white生成Excel报表/a%}else{%ahref=${cxt}/payrollReport/payrollReportAction!getExcelstyle=color:white生成Excel报表/a%}%
7.
2.3部分算法设计1Action中的获得工资表查询信息方法publicStringfindthrowsException{intoffset=0;try{offset=Integer.parseIntrequest.getParameterpager.offset;}catchRuntimeExceptione{}iffirstDay!=nulllastDay!=null{pagerModel=payrollService.findByTimeAndDepartmentfirstDaylastDayoffsetPageSize.NORMAL;}else{pagerModel=payrollService.findnewString[]{status}newObject[]{Status.SUCCESS}offsetPageSize.NORMAL;}returnfind;}//下载publicInputStreamgetDownloadFile{returnpayrollService.getInputStreamfirstDaylastDaynewString[]{status}newObject[]{Status.SUCCESS};}//生成excel表publicStringgetExcelthrowsException{returngetExcel;}
7.
2.4接口8)部门管理模块接口调用图图6-1部门管理模块接口调用图
7.
2.5子功能模块的测试1)工资报表管理显示测试图2)选着日期测试图9)员工工资单查询结果测试图8)操作员工工资信息的测试的测试代码publicclassPayrollServiceTestextendsTestCase{privatePayrollServicepayrollService;privatePersonServicepersonService;protectedvoidsetUpthrowsException{ApplicationContextcxt=newFileSystemXmlApplicationContext/WebRoot/WEB-INF/applicationContext.xml;payrollService=PayrollServicecxt.getBeanpayrollService;personService=PersonServicecxt.getBeanpersonService;}publicvoidtestfind{Personperson=personService.findById1;PagerModelPayrollpayroll=payrollService.findnewString[]{person}newObject[]{person}08;System.out.printlnpayroll.getDatas.size;forPayrollp:payroll.getDatas{System.out.printlnp.getId++p.getRemark;}}//获取时间测试publicvoidtestGet{DateFormatdf=DateFormat.getDateInstance;Dated1;Dated2;try{d1=df.parse2011-02-5;d2=df.parse2011-02-20;forPayrollp:payrollService.findByTimeAndDepartmentd1d20Integer.MAX_VALUE.getDatas{System.out.printlnp.getPayTime;}}catchParseExceptione{e.printStackTrace;}}publicvoidtestDate{Dated=newDate;java.sql.Datesd=newjava.sql.Dated.getTime;System.out.printlnsd.toString;}}8权限控制技术:在ssh集成开发中做权限控制开发前需要设计用户表(user)、角色表(role)、用户角色表(user_role)、角色权限控制表(acl).如下图8-1图8-1:权限控制结构图1)远程调用java代码dwrDirectWebRemoting的使用加入包,配置web.xml,配置dwr.xml(WEB-INF下)在页面中引入相关js,代码如下!--dwr权限监听器类--listenerlistener-classorg.directwebremoting.servlet.DwrListener/listener-class/listenerservletservlet-namedwr-invoker/servlet-nameservlet-classorg.directwebremoting.servlet.DwrServlet/servlet-classinit-paramparam-namedebug/param-nameparam-valuetrue/param-value/init-param/servletservlet-mappingservlet-namedwr-invoker/servlet-nameurl-pattern/dwr/*/url-pattern/servlet-mapping2)权限安全登录控制在cs.xj.util包下配置SecurityFunction类@ComponentsecurityFunctionpublicclassSecurityFunction{privatestaticAclServiceaclService;//权限控制服务接口,使用spring注入//权限验证publicstaticbooleansecurityIntegeruserIdStringsnIntegerpermission{returnaclService.hasPermissionByResourceSnuserIdsnpermission;}@Resourcename=aclServicepublicvoidsetAclServiceAclServiceaclService{SecurityFunction.aclService=aclService;}}3)JSTL函数,完成权限的即时认证 使用自定义标签my.tld代码如下xmlversion=
1.0encoding=UTF-8taglibxmlns=http://java.sun.com/xml/ns/j2eexmlns:xsi=http://www.w
3.org/2001/XMLSchema-instancexsi:schemaLocation=http://java.sun.com/xml/ns/j2eehttp://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_
0.xsdversion=
2.0display-nameJSTLfunctions/display-nametlib-version
1.1/tlib-versionshort-namemy/short-nameurihttp://www.oa.com/jsp/jstl/functions/uri!--引入自定义标签进行权限控制--functionnamesecurity/namefunction-classcs.xj.util.SecurityFunction/function-classfunction-signaturebooleansecurityjava.lang.Integerjava.lang.Stringjava.lang.Integer/function-signature/function/taglib4)实现权限服务AclService接口5)在loginAction中实现根据登录用户的id通过JSTL函数,完成权限的即时认证方法publicStringfindModulesthrowsException{Useruser=Usersession.getlogin;//保存User对象为loginmodules=newArrayListModule;//设置模块集合moduleList=newArrayListModuleList;modules=aclService.findModulesuser.getId;//根据登录用户的id通过JSTL函数,完成权限的即时认证ModuleListml=null;forModulem:modules{ifm.getModule==null{ml=newModuleList;ml.setParentm;forModulemod:modules{//增强for循环ifmod.getModule!=nullm.getId.equalsmod.getModule.getId{ml.getChild.addmod;}}moduleList.addml;}}count=moduleList.size;//获得模块数session.putmoduleListmoduleList;//抛出模块列表session.putcountcount;returnfindModules;}10技术控制9技术控制(参考网址http://fangang.iteye.com/blog/47670)
1.编写DAO的时候不要直接去使用hibernate或spring对hibernate的支持现在我们在编写DAO的时候普遍都是直接继承spring对hibernate的封装类HibernateDaoSupport,然后使用该类提供的诸如saveOrUpdatesaveOrUpdateCopyfind等等另外,在使用excute方法实现一些更复杂的hibernate功能的时候还会使用hibernate的类,诸如QuerySessionType等这样直接使用spring和hibernate的类存在的问题在于,你的代码将不得不依赖与spring和hibernate的某个版本比如说,现在hibernate3出来了,改动挺大,实际上最要命的是包结构,hibernate2的包结构是net.sf.hibernate.*,然而hibernate3是org.hibernate.*同样,spring为了支持hibernate3,包名也改为org.springframework.orm.hibernate
3.*假如,你现在新开发一个项目,这没什么关系,如果是升级一个项目问题就来了如果你希望将你的一个项目从hibernate2升级为hibernate3,你不得不修改DAO中所有对hibernate和spring-hibernate的引用如果你的代码中出现hibernate2与hibernate3不兼容的方法和类,比如saveOrUpdateCopy(在hibernate3中已经没有了)你还将不得不改写那么你可能会说,我不会这样升级如果你的软件生命周期有好多年,hibernate升级到4,升级到5,你还是依然使用hibernate2?如果你以这种方式开发一个平台,你能要求所有使用你平台的软件项目都只能使用hibernate2?更进一步说,我现在开发一个产品,今后的客户将是成千上万经过
1、2年我需要升级了,这时我的升级包有几十M,几乎把所有的DAO都换了个遍,这样的升级无异于重装也许,有人会提出另一个方案,在HibernateDaoSupport与DAO中间增加了一个基础类,这样将基础类中的org.springframework.orm.hibernate.support.HibernateDaoSupport,改为了org.springframework.orm.hibernate
3.support.HibernateDaoSupport,这样其下面继承的DAO就不用改动了然而在源码上是小小的改动,但对于类来说,两个不同版本的HibernateDaoSupport其相关的属性和方法还是有不少变化,那么在基础类重新编译的同时,你的继承类重新编译否既然已经重新编译了,因此你的所有DAO在升级的时候依然要打入升级包,问题依然存在以上问题,究其原因,是我们项目中的DAO依赖于hibernate和spring,因为我们对它们的使用是继承,是一种很强的关联,就是一种依赖我们只需要稍微进行一些调整,就可以解决这个问题,那就是不使用直接继承,而使用接口进行分离可以先建立一个BaseDao类,它是所有DAO的基础类,实现DAO操作所需的所有诸如get、saveOrUpdate、delete、findById等方法,除了一些基本的方法,像翻页查询、PagerModel、解析查询条件形成HQL语句等功能也在这里实现,但不使用与hibernate或spring有关的任何方法和类同时,BaseDao调用一个叫DaoSupport的接口,DaoSupport的接口则是提供持久化所需的基本方法整个结构如下图所示
2.编写Action的时候不要直接使用spring和spring的继承类前面我说了应当避免DAO引用spring或hibernate及其继承类同样的事情也发生在Action中由于Action通常不纳入spring的管理,因此Action在通过spring调用某个BUS(总线)的时候,往往是去引用一个叫SpringContext的类(spring的类ContextLoaderServlet的继承类),然后使用它的getBean方法如此的使用,我们的Action将依赖与spring我们同样可以使用一个叫BasicAction的父类,然后用一个接口来隔离spring由于Action通常不纳入spring的管理,我们通过一个*.property的配置文件来决定接口到底调用哪个实现类这样的结构的另一个好处是,我们还可以将所有Action都必须使用的诸如写日志、用户校验、异常处理都放在父类BasicAction中,提高系统的可维护性
3.当UI表示层需要获取别的模块的数据的时候,不要直接去使用该模块的DAO我举一个简单的例子我需要设计一个软件评审的管理软件,该软件分为评审组织者制订评审计划、评审者分别填写评审表后由评审组织者汇总评审表、评审组织者制作评审报告这是一个非常简单的项目,分成了三个人来完成但是项目进行快结束的时候却出现了问题填写评审表需要获得评审计划中的一些数据,制作评审报告的数据来源于评审表项目组在开始编程前先开了一次会,大家约定好了各个部分的数据格式及其规则,然后开始工作然而数天后项目组把各个模块整合以后发现,系统根本跑不起来,为什么呢?设计评审计划的人发现,所有评审计划应当按照产品编号来进行管理而不是项目编号由于这个变更,填写评审表模块在待评审列表中什么都无法显示;同样,设计评审表的人发现,在一个评审计划中评审表与评审者不是一对多的关系,而是一对一的关系,因而修改了这两个表的关联因为这样,在制作评审报告时就不能正确得到评审表数据其实一个软件项目在整个进行过程中总是不断变更我们需要做的不是去抑制这些变更,而应当是通过软件的结构去适应这些变更,即是降低各模块间的依赖(耦合),提高内聚拿这个实例来说,当评审表需要调用评审计划的数据的时候,不应当是自己写一个DAO去调用评审计划的数据,而应当是调用评审计划的接口,将这个任务交给评审计划类来完成当评审报告需要调用评审表的数据的时候,同样应当去调用评审表的接口,由评审表来实现同时,这种调用应当是去调用BUS层的接口为什么呢?比如在评审计划中的一个业务逻辑是只有在评审计划发布以后才能制作评审表,那么怎样才是已发布的评审计划呢?这个业务逻辑应当由谁来定义?当然是评审计划在什么地方定义?当然是BUS而不是DAO,因为DAO仅仅是实现数据的持久化,而BUS才是实现业务逻辑的地方既然如此,如果评审表去调用评审计划的DAO,那么已发布评审计划的业务逻辑必然包含在了评审表的业务逻辑里了我们假设有一天,已发布评审计划的业务逻辑发生变更了(实际上这样的会在你毫不经意间就发生了),编写评审计划的人会很快就修改了评审计划的业务实现并且测试通过了他不知道评审表里也包含了这样的业务逻辑,因而修改后的程序在运行到评审表的时候就很可能会出错不幸的是,在实际工作中,同样一个业务逻辑可能包含在无数个你可能知道,但你也可能不知道的代码中这样的结构就是一个不易于维护的差的结构10参考文献:
[1]朱雪琴 作者 常建功 作者亮剑javaWeb项目开发案例导航广州:人民教育出版社
2011.
10.
9.选题调查研究资料查询开发环境熟悉学习ssh技术概要设计数据库的设计功能模块开发和详细设计功能模块测试系统调试和修改需求分析选题调查研究资料查询开发环境熟悉学习ssh技术概要设计数据库的设计功能模块开发和详细设计功能模块测试系统调试和修改需求分析部门管理用户管理角色管理系统管理报表管理员工报表管理工资报表管理数据库Hibernate业务逻辑层业务逻辑层表示层JDBC开始输入用户名及密码登录验证打印“用户名或密码错误”N进入系统结束LoginAction.class输入用户名及密码验证登陆成功进入pay_main.jsp页面登录页面index.jsplogin方法findModulesLoginAction类用于响应表示层的用户登录和权限控制AclService权限控制服务接口AclDao操作数据库中的权限控制表acl的方法的接口UserService用户服务接口UserDao操作用户表的Dao接口调用调用调用调用开始添加、修改或删除操作成功或失败结束获得该模块权限验证进入修改部门edit_dep.jsp页面部门管理界面department.jspDepartmentAction类实现部门管理添加,修改,删除Action调用add方法添加部门界面add_dep.jsp调用update方法进入删除部门del_success.jsp调用delete方法调用DepartmentAction类用于响应表示层的部门管理的操作DepartmentService部门管理业务操作服务接口DepartmentDao操作数据库部门表的方法接口调用开始操作成功或失败授权、修改或删除结束获得该模块权限验证进入权限分配acl.jsp页面角色管理界面role.jspRoleAction类实现用户角色授权,修改,删除的Action添加添加角色界面add_role.jsp授权进入删除角色del_success.jsp删除AclAction类实现角色权限控制ActionRoleAction类操作角色管理业务操作服务的ActionAclService权限控制服务接口ModuleService模块服务接口AclAction类用于权限控制操作UserService用户服务接口调用调用调用UserDao操作用户表的Dao接口调用AclDao权限控制表acl的方法的接口调用调用RoleService角色管理方法服务接口RoleService用户权限管理方法服务接口RoleDao操作数据库角色表的Dao接口调用调用开始操作成功或失败查询、分配(帐号、角色)或删除结束获得该模块权限验证进入显示用户分配角色界面show_user_role.jsp用户管理界面user.jspUserAction类实现用户的查询,分配(角色,帐号),删除的Action分配(帐号)执行userAction!addUserpersonId=${person.id}方法分配(角色)执行userAction!deleteUserid=${person.user.id}方法删除进入选择角色select_role.jsp页面PersonService个人信息数据库表操作接口UserService模块服务接口UserAction类用于用户管理操作调用调用PersonDao操作数据库表person的接口调用调用UserDao操作用户表的Dao接口开始选择部门、查询员生成报表结束获得该模块权限验证员工信息报表管理系统person_report.jspPersonReportAction类实现员工选择、查询、生成报表的Action选择部门执行departmentAction!findselect=true方法调用personReportAction!find方法执行personReportAction!getExceldepId=${depId}方法查询员工调用PersonService个人信息服务接口PersonReportAction类生成员工信息excel报表DepartmentService部门信息服务接口调用调用DepartmentDao操作数据库部门表的方法接口调用PersonDao操作数据库表person的接口开始选择查询日期,查询生成报表结束获得该模块权限验证工资报表管理界面payroll_report.jspPayrollReportAction类实现员工选择日期、生成报表的Action选择日期firstDay=%=request.getParameterfirstDay%lastDay=%=request.getParameterlastDay%执行payrollReportAction!find方法payrollReportAction!getExcelfirstDay=%=request.getParameterfirstDay%lastDay=%=request.getParameterlastDay方法工资表查询调用PayrollReportAction类生成员工工资信息excel报表PayrollService部门信息服务接口调用PayrollDao操作数据库薪资表接口。