实现DAO层
public class Application implements Serializable { private static final long serialVersionUID = 48L; private Integer id; private String reason; private boolean result; private CheckBack check; private AttendType type; private Attend attend; public Application(){ } public Application(Integer id , String reason , boolean result , Attend attend , AttendType type , CheckBack check) { this.id = id; this.reason = reason; this.result = result; this.attend = attend; this.type = type; this.check = check; } public Integer getId() { return id; } 。。。。。。 }
public class Attend implements Serializable { private static final long serialVersionUID = 48L; private Integer id; private String dutyDay; //打卡时间 private Date punchTime; //代表本次打卡是否为上班打卡 private boolean isCome; private Employee employee; private AttendType type; public Attend() { } public Attend(Integer id , String dutyDay , Date punchTime , boolean isCome , AttendType type , Employee employee) { this.id = id; this.dutyDay = dutyDay; this.punchTime = punchTime; this.isCome = isCome; this.type = type; this.employee = employee; } public Integer getId() { return id; } 。。。。。。 public boolean equals(Object obj) { if (this == obj) { return true; } if (obj != null && obj.getClass() == Attend.class) { Attend attend = (Attend)obj; return getEmployee().equals(attend.getEmployee()) && getDutyDay().equals(attend.getDutyDay()) && getIsCome() == attend.getIsCome(); } return false; } public int hashCode () { if (getIsCome()) { return dutyDay.hashCode() + 29 * employee.hashCode() + 1; } return dutyDay.hashCode() + 29 * employee.hashCode(); } }
public class AttendType implements Serializable { private Integer id; private String name; //此类出勤对应的罚款 private double amerce; public AttendType() { } public AttendType(Integer id , String name , double amerce) { this.id = id; this.name = name; this.amerce = amerce; } public Integer getId() { return id; } 。。。。。。 }
public class Employee implements Serializable { private static final long serialVersionUID = 48L; private Integer id; private String name; private String pass; private double salary; private Manager manager; private Set<Payment> payments=new HashSet<Payment>(); private Set<Attend> attends=new HashSet<Attend>(); public Employee(){ } public Employee(Integer id , String name , String pass , double salary , Manager manager , Set<Attend> attends , Set<Payment> payments) { this.id = id; this.name = name; this.pass = pass; this.salary = salary; this.manager = manager; this.attends = attends; this.payments = payments; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } 。。。。。。 public boolean equals(Object obj){ if(this==obj){ return true; } if(obj!=null && obj.getClass()==Employee.class){ Employee employee=(Employee)obj; return this.getName().equals(employee.getName()) && this.getPass().equals(employee.getPass()); } return false; } public int hashCode() { return name.hashCode() + pass.hashCode() * 17; } }
对于1-N关系,映射成双向关联,并由N的一端控制关联关系。例如:
Attend.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- Hibernate映射文件的根元素 --> <hibernate-mapping package="org.crazyit.hrsystem.domain"> <class name="Attend" table="attend_table"> <cache usage="read-only"/> <id name="id" type="integer" column="attend_id"> <generator class="identity"/> </id> <property name="dutyDay" column="duty_day" type="string" not-null="true" length="50"/> <property name="punchTime" column="punch_time" type="java.util.Date" /> <property name="isCome" column="is_come" type="boolean" not-null="true"/> <many-to-one name="type" column="type_id" class="AttendType" not-null="true" lazy="false"/> <many-to-one name="employee" column="emp_id" class="Employee" not-null="true" lazy="false"/> </class> </hibernate-mapping>
AttendType.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- Hibernate映射文件的根元素 --> <hibernate-mapping package="org.crazyit.hrsystem.domain"> <class name="AttendType" table="type_table"> <cache usage="read-only"/> <!-- 映射标识属性 --> <id name="id" type="integer" column="type_id"> <generator class="identity"/> </id> <property name="name" column="type_name" type="string" not-null="true" length="50"/> <property name="amerce" column="amerce_amount" type="double" not-null="true" /> </class> </hibernate-mapping>
Employee.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- Hibernate映射文件的根元素 --> <hibernate-mapping package="org.crazyit.hrsystem.domain"> <class name="Employee" table="emp_table" discriminator-value="1"> <cache usage="read-only"/> <id name="id" type="integer" column="emp_id"> <generator class="identity"/> </id> <discriminator column="emp_type" type="int"></discriminator> <!-- 映射普通属性 --> <property name="name" column="emp_name" type="string" not-null="true" length="50" unique="true"/> <property name="pass" column="emp_pass" type="string" not-null="true" length="50"/> <property name="salary" column="emp_salary" type="double" not-null="true" /> <many-to-one name="manager" column="mgr_id" class="Manager" lazy="false"/> <set name="attends" inverse="true"> <key column="emp_id" /> <one-to-many class="Attend"/> </set> <set name="payments" inverse="true"> <key column="emp_id" /> <one-to-many class="Payment"/> </set> <subclass name="Manager" discriminator-value="2"> <property name="dept" column="dept_name" type="string" length="50"/> <set name="employees" inverse="true"> <key column="mgr_id" /> <one-to-many class="Employee"/> </set> <set name="checks" inverse="true"> <key column="mgr_id" /> <one-to-many class="CheckBack"/> </set> </subclass> </class> </hibernate-mapping>
对于不同的持久层技术,Spring的DAO提供一个DAO模板,Spring为Hibernate提供的支持类是HibernateDaoSupport.
DAO定义了DAO组件应该实现的方法,使逻辑组件与DAO组件低耦合。
例如:DAO接口ApplicationDao
public interface ApplicationDao { public Application get(Integer id); public Integer save(Application application); public void update(Application application); public void delete(Application application); public void delete(Integer id); public List<Application> findAll(); public List<Application> findByEmp(Employee empl); }
Spring为Hibernate提供的DAO基类是HibernateDaoSupport,只需要传人SessionFactory引用,即可得到HibernateTemplate实例,改实例具有强大的功能。
为了增加分页查询方法,实际应用扩展了HibernateDaoSupport,为YeekuHibernateDaoSupport,
public class YeekuHibernateDaoSupport extends HibernateDaoSupport { /** * 使用hql语句进行分页查询 * @param hql 需要查询的hql语句 * @param offset 第一条记录索引 * @param pageSize 每页需要显示的记录数 * @return 当前页的所有记录 */ public List findByPage(final String hql, final int offset, final int pageSize) { //通过一个HibernateCallback对象来执行查询 List list = getHibernateTemplate() .executeFind(new HibernateCallback() { //实现HibernateCallback接口必须实现的方法 public Object doInHibernate(Session session) throws HibernateException, SQLException { //执行Hibernate分页查询 List result = session.createQuery(hql) .setFirstResult(offset) .setMaxResults(pageSize) .list(); return result; } }); return list; } /** * 使用hql语句进行分页查询 * @param hql 需要查询的hql语句 * @param value 如果hql有一个参数需要传入,value就是传入hql语句的参数 * @param offset 第一条记录索引 * @param pageSize 每页需要显示的记录数 * @return 当前页的所有记录 */ public List findByPage(final String hql , final Object value , final int offset, final int pageSize) { //通过一个HibernateCallback对象来执行查询 List list = getHibernateTemplate() .executeFind(new HibernateCallback() { //实现HibernateCallback接口必须实现的方法 public Object doInHibernate(Session session) throws HibernateException, SQLException { //执行Hibernate分页查询 List result = session.createQuery(hql) //为hql语句传入参数 .setParameter(0, value) .setFirstResult(offset) .setMaxResults(pageSize) .list(); return result; } }); return list; } /** * 使用hql语句进行分页查询 * @param hql 需要查询的hql语句 * @param values 如果hql有多个个参数需要传入,values就是传入hql的参数数组 * @param offset 第一条记录索引 * @param pageSize 每页需要显示的记录数 * @return 当前页的所有记录 */ public List findByPage(final String hql, final Object[] values, final int offset, final int pageSize) { //通过一个HibernateCallback对象来执行查询 List list = getHibernateTemplate() .executeFind(new HibernateCallback() { //实现HibernateCallback接口必须实现的方法 public Object doInHibernate(Session session) throws HibernateException, SQLException { //执行Hibernate分页查询 Query query = (Query) session.createQuery(hql); //为hql语句传入参数 for (int i = 0 ; i < values.length ; i++) { query.setParameter( i, values[i]); } List result = ((org.hibernate.Query) query.setFirstResult(offset) .setMaxResults(pageSize)) .list(); return result; } }); return list; } }
实际应用中,DAO实现类都要继承HibernateDaoSupport(YeekuHibernateDaoSupport),并实现相应的DAO接口;而业务组件类则面向接口编程。
例如ApplicationDaoHibernate.java
public class ApplicationDaoHibernate extends YeekuHibernateDaoSupport implements ApplicationDao { @Override public Application get(Integer id) { // TODO Auto-generated method stub return this.getHibernateTemplate().get(Application.class, id); } @Override public Integer save(Application application) { // TODO Auto-generated method stub return (Integer)this.getHibernateTemplate().save(application); } @Override public void update(Application application) { // TODO Auto-generated method stub this.getHibernateTemplate().update(application); } @Override public void delete(Application application) { // TODO Auto-generated method stub this.getHibernateTemplate().delete(application); } @Override public void delete(Integer id) { // TODO Auto-generated method stub this.getHibernateTemplate().delete(get(id)); } @Override public List<Application> findAll() { // TODO Auto-generated method stub return (List<Application>)this.getHibernateTemplate().find("from Application"); } @Override public List<Application> findByEmp(Employee empl) { // TODO Auto-generated method stub return (List<Application>)this.getHibernateTemplate().find("from Application as a where a.attend.employee=?",empl); } }
部署DAO层:
Spring容器为DAO运行注入所需的SessionFactory.
ApplicationContext.xml
配置数据源:
<!-- 定义数据源Bean,使用C3P0数据源实现 --> <!-- 设置连接数据库的驱动、URL、用户名、密码 连接池最大连接数、最小连接数、初始连接数等参数 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" p:driverClass="com.mysql.jdbc.Driver" p:jdbcUrl="jdbc:mysql://localhost:3306/hrSystem" p:user="root" p:password="111111" p:maxPoolSize="40" p:minPoolSize="1" p:initialPoolSize="1" p:maxIdleTime="20"/>
配置SessionFactory Bean
<!-- 定义Hibernate的SessionFactory --> <!-- 依赖注入数据源,注入正是上面定义的dataSource --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" p:dataSource-ref="dataSource"> <!-- mappingResouces属性用来列出全部映射文件 --> <property name="mappingResources"> <list> <!-- 以下用来列出Hibernate映射文件 --> <value>org/crazyit/app/hrsystem/domain/Application.hbm.xml</value> <value>org/crazyit/app/hrsystem/domain/Attend.hbm.xml</value> <value>org/crazyit/app/hrsystem/domain/AttendType.hbm.xml</value> <value>org/crazyit/app/hrsystem/domain/CheckBack.hbm.xml</value> <value>org/crazyit/app/hrsystem/domain/Employee.hbm.xml</value> <value>org/crazyit/app/hrsystem/domain/Payment.hbm.xml</value> </list> </property> <!-- 定义Hibernate的SessionFactory的属性 --> <property name="hibernateProperties"> <!-- 指定数据库方言、是否自动建表 是否生成SQL语句等 --> <value> hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect hibernate.hbm2ddl.auto=update hibernate.show_sql=true hibernate.format_sql=true #开启二级缓存 hibernate.cache.use_second_level_cache=true #设置二级缓存的提供者 hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider </value> </property> </bean>
配置DAO组件,daoContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 配置DAO组件的模板 --> <bean id="daoTemplate" abstract="true" lazy-init="true" p:sessionFactory-ref="sessionFactory"> </bean> <bean id="employeeDao" class="org.crazyit.app.hrsystem.dao.impl.EmployeeDaoHibernate" parent="daoTemplate"/> <bean id="managerDao" class="org.crazyit.app.hrsystem.dao.impl.ManagerDaoHibernate" parent="daoTemplate"/> <bean id="attendDao" class="org.crazyit.app.hrsystem.dao.impl.AttendDaoHibernate" parent="daoTemplate"/> <bean id="attendTypeDao" class="org.crazyit.app.hrsystem.dao.impl.AttendTypeDaoHibernate" parent="daoTemplate"/> <bean id="appDao" class="org.crazyit.app.hrsystem.dao.impl.ApplicationDaoHibernate" parent="daoTemplate"/> <bean id="checkDao" class="org.crazyit.app.hrsystem.dao.impl.CheckBackDaoHibernate" parent="daoTemplate"/> <bean id="payDao" class="org.crazyit.app.hrsystem.dao.impl.PaymentDaoHibernate" parent="daoTemplate"/> </beans>
首先配置DAO组件模板,为该模板注入SessionFactory;DAO组件继承该模板,因此DAO组件也注入了SessionFactory.
实现Service层
public interface MgrManager { /** * 根据经理返回该部门的没有批复的申请 * @param mgr 经理名 * @return 该部门的全部申请 */ List<AppBean> getAppsByMgr(String mgr)throws HrException; /** * 处理申请 * @param appid 申请ID * @param mgrName 经理名字 * @param result 是否通过 */ void check(int appid, String mgrName, boolean result); /** * 根据经理返回该部门的全部员工 * @param mgr 经理名 * @return 经理的全部下属 */ List<EmpBean> getEmpsByMgr(String mgr)throws HrException; /** * 新增员工 * @param emp 新增的员工 * @param mgr 员工所属的经理 */ void addEmp(Employee emp , String mgr) throws HrException; /** * 根据经理返回所有的部门上个月工资 * @param mgr 新增的员工名 * @return 部门上个月工资 */ List<SalaryBean> getSalaryByMgr(String mgr)throws HrException; }
public class MgrManagerImpl implements MgrManager { private ApplicationDao appDao; private AttendDao attendDao; private AttendTypeDao typeDao; private CheckBackDao checkDao; private EmployeeDao empDao; private ManagerDao mgrDao; private PaymentDao payDao; public ApplicationDao getAppDao() { return appDao; } public void setAppDao(ApplicationDao appDao) { this.appDao = appDao; } public AttendDao getAttendDao() { return attendDao; } public void setAttendDao(AttendDao attendDao) { this.attendDao = attendDao; } public AttendTypeDao getTypeDao() { return typeDao; } public void setTypeDao(AttendTypeDao typeDao) { this.typeDao = typeDao; } public CheckBackDao getCheckDao() { return checkDao; } public void setCheckDao(CheckBackDao checkDao) { this.checkDao = checkDao; } public EmployeeDao getEmpDao() { return empDao; } public void setEmpDao(EmployeeDao empDao) { this.empDao = empDao; } public ManagerDao getMgrDao() { return mgrDao; } public void setMgrDao(ManagerDao mgrDao) { this.mgrDao = mgrDao; } public PaymentDao getPayDao() { return payDao; } public void setPayDao(PaymentDao payDao) { this.payDao = payDao; } /** * 根据经理返回该部门的没有批复的申请 * @param mgr 经理名 * @return 该部门的全部申请 */ @Override public List<AppBean> getAppsByMgr(String mgr) throws HrException { // TODO Auto-generated method stub Manager m=mgrDao.findByName(mgr); if(m==null){ throw new HrException("您是经理吗?或你还未登录?"); } //查询该经理对应的全部员工 List<Employee> emps=this.empDao.findByMgr(m); if(emps==null || emps.size()<1){ throw new HrException("您的部门没有员工"); } //封装VO集 List<AppBean> result=new ArrayList<AppBean>(); for(Employee e:emps){ List<Application> apps=appDao.findByEmp(e); if(apps!=null && apps.size()>1){ for(Application app:apps){ //只选择还未处理的申请 if(app.getResult()==false){ Attend attend=app.getAttend(); result.add(new AppBean(app.getId(),e.getName(),attend.getType().getName(),app.getType().getName(),app.getReason())); } } } } return result; } /** * 处理申请 * @param appid 申请ID * @param mgrName 经理名字 * @param result 是否通过 */ @Override public void check(int appid, String mgrName, boolean result) { // TODO Auto-generated method stub Application app=appDao.get(appid); CheckBack check=new CheckBack(); check.setApp(app); //同意通过申请 if(result){ //设置通过申请 check.setResult(true); //修改申请为已经批复 app.setResult(true); appDao.save(app); //为真时,还需要修改出勤的类型 Attend attend=app.getAttend(); attend.setType(app.getType()); attendDao.update(attend); } else { //没有通过申请 check.setResult(false); app.setResult(true); appDao.save(app); } //保存申请批复 checkDao.save(check); } /** * 根据经理返回该部门的全部员工 * @param mgr 经理名 * @return 经理的全部下属 */ @Override public List<EmpBean> getEmpsByMgr(String mgr) throws HrException { // TODO Auto-generated method stub Manager m=mgrDao.findByName(mgr); if(m==null){ throw new HrException("您是经理吗?或你还未登录?"); } //查询该经理对应的全部员工 List<Employee> emps=empDao.findByMgr(m); //部门依然没有员工 if (emps == null || emps.size() < 1) { throw new HrException("您的部门没有员工"); } //封装VO集 List<EmpBean> result =new ArrayList<EmpBean>(); for (Employee e : emps) { result.add(new EmpBean(e.getName(),e.getPass(),e.getSalary())); } return result; } /** * 新增员工 * @param emp 新增的员工 * @param mgr 员工所属的经理 */ @Override public void addEmp(Employee emp, String mgr) throws HrException { // TODO Auto-generated method stub Manager m = mgrDao.findByName(mgr); if (m == null) { throw new HrException("新增员工的业务异常"); } emp.setManager(m); empDao.save(emp); } /** * 根据经理返回所有的部门上个月工资 * @param mgr 新增的员工名 * @return 部门上个月工资 */ @Override public List<SalaryBean> getSalaryByMgr(String mgr) throws HrException { // TODO Auto-generated method stub Manager m = mgrDao.findByName(mgr); if (m == null) { throw new HrException("您是经理吗?或你还未登录?"); } //查询该经理对应的全部员工 List<Employee> emps = empDao.findByMgr(m); //部门依然没有员工 if (emps == null || emps.size() < 1) { throw new HrException("您的部门没有员工"); } Calendar c = Calendar.getInstance(); c.add(Calendar.MONTH , -1); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); String payMonth = sdf.format(c.getTime()); List<SalaryBean> result = new ArrayList<SalaryBean>(); //遍历本部门每个员工 for (Employee e : emps) { Payment p = payDao.findByMonthAndEmp(payMonth , e); if (p != null) { result.add(new SalaryBean(e.getName() , p.getAmount())); } } return result; } }
事务管理
applicationContext.xml
<!-- 配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 --> <!-- 该类实现PlatformTransactionManager接口,是针对Hibernate的特定实现--> <!-- 并注入SessionFactory的引用 --> <bean id="transactionManager" class= "org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"/> <!-- 配置事务增强处理Bean,指定事务管理器 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 用于配置详细的事务语义 --> <tx:attributes> <!-- 所有以'get'开头的方法是read-only的 --> <tx:method name="get*" read-only="true"/> <!-- 其他方法使用默认的事务设置 --> <tx:method name="*"/> </tx:attributes> </tx:advice> <aop:config> <!-- 配置一个切入点,匹配empManager和mgrManager 两个Bean的所有方法的执行 --> <aop:pointcut id="leePointcut" expression="bean(empManager)||bean(mgrManager)"/> <!-- 指定在leePointcut切入点应用txAdvice事务增强处理 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="leePointcut"/> </aop:config>
<aop:advisor />用于配置自动代理。
部署业务逻辑组件:
<!-- 定义业务逻辑组件模板 --> <!-- 为之注入DAO组件 --> <bean id="managerTemplate" abstract="true" lazy-init="true" p:appDao-ref="appDao" p:attendDao-ref="attendDao" p:typeDao-ref="attendTypeDao" p:checkDao-ref="checkDao" p:empDao-ref="employeeDao" p:mgrDao-ref="managerDao" p:payDao-ref="payDao"/> <!-- 定义两个业务逻辑组件,继承业务逻辑组件的模板 --> <bean id="empManager" class="org.crazyit.hrsystem.service.impl.EmpManagerImpl" parent="managerTemplate"/> <bean id="mgrManager" class="org.crazyit.hrsystem.service.impl.MgrManagerImpl" parent="managerTemplate"/>
Spring容器管理各组件间的依赖关系,把依赖关系从代码中抽离,放在配置文件中进行管理,很好的实现组件之间的解耦。
实现Web层
web.xml 配置Struts2
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!-- 配置Spring配置文件的位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/HRSystem/applicationContext.xml, /HRSystem/daoContext.xml</param-value> </context-param> <!-- 使用ContextLoaderListener初始化Spring容器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- 定义Struts 2的核心Filter --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <!-- 让Struts 2的核心Filter拦截所有请求 --> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 定义Web应用的首页 --> <welcome-file-list> <welcome-file>/content/index.jsp</welcome-file> </welcome-file-list> </web-app>
两个Action基类:
public class EmpBaseAction extends ActionSupport { //依赖的业务逻辑组件 protected EmpManager mgr; //依赖注入业务逻辑组件所必须的setter方法 public void setEmpManager(EmpManager mgr) { this.mgr = mgr; } }
public class MgrBaseAction extends ActionSupport { protected MgrManager mgr; public void setMgrManager(MgrManager mgr) { this.mgr = mgr; } }
loginAction.java
public class LoginAction extends EmpBaseAction { //定义一个常量作为员工登录成功的Result名 private final String EMP_RESULT = "emp"; //定义一个常量作为经理登录成功的Result名 private final String MGR_RESULT = "mgr"; //封装请求参数 private Manager manager; //登录的验证码 private String vercode; //处理登录后的提示信息 private String tip; public Manager getManager() { return manager; } public void setManager(Manager manager) { this.manager = manager; } public String getVercode() { return vercode; } public void setVercode(String vercode) { this.vercode = vercode; } public String getTip() { return tip; } public void setTip(String tip) { this.tip = tip; } public String execute() throws Exception{ ActionContext ctx=ActionContext.getContext(); int result=mgr.validLogin(getManager()); //登录结果为普通员工 if(result==LOGIN_EMP){ ctx.getSession().put(WebConstant.USER , manager.getName()); ctx.getSession().put(WebConstant.LEVEL,WebConstant.EMP_LEVEL); setTip("您已经成功登录系统"); return EMP_RESULT; } //登录结果为经理 else if (result == LOGIN_MGR){ ctx.getSession().put(WebConstant.USER, manager.getName()); ctx.getSession().put(WebConstant.LEVEL, WebConstant.MGR_LEVEL); return MGR_RESULT; } //用户名和密码不匹配 else{ setTip("用户名/密码不匹配"); return ERROR; } } }
struts.xml
<!-- 定义处理登录系统的的Action --> <action name="processLogin" class="org.crazyit.app.hrsystem.action.LoginAction"> <result name="input">/content/login.jsp</result> <result name="mgr">/content/manager/index.jsp</result> <result name="emp">/content/employee/index.jsp</result> <result name="error">/content/login.jsp</result> </action>
校验规则文件LoginAction_validation.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.3//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd"> <validators> <field name="manager.name"> <field-validator type="requiredstring"> <message>用户名必填!</message> </field-validator> <field-validator type="regex"> <param name="expression"><![CDATA[(\w{4,25})]]></param> <message>您输入的用户名只能是字母和数字,且长度必须在4到25之间</message> </field-validator> </field> <field name="manager.pass"> <field-validator type="requiredstring"> <message>密码必填!</message> </field-validator> <field-validator type="regex"> <param name="expression"><![CDATA[(\w{4,25})]]></param> <message>您输入的密码只能是字母和数字,且长度必须在4到25之间</message> </field-validator> </field> <field name="vercode"> <field-validator type="requiredstring"> <message>验证码必填!</message> </field-validator> <field-validator type="regex"> <param name="expression"><![CDATA[(\w{6,6})]]></param> <message>您输入的验证码只能是字母和数字,且长度必须在6位</message> </field-validator> </field> </validators>
public class PunchAction extends EmpBaseAction { //封装处理结果的punchIsValid属性 private int punchIsValid; public int getPunchIsValid() { return punchIsValid; } public void setPunchIsValid(int punchIsValid) { this.punchIsValid = punchIsValid; } public String execute() throws Exception{ //创建ActionContext实例 ActionContext ctx = ActionContext.getContext(); //获取HttpSession中的user属性 String user = (String)ctx.getSession() .get(WebConstant.USER); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //格式化当前时间 String dutyDay=sdf.format(new Date()); //调用业务逻辑方法处理用户请求 int result=mgr.validPunch(user, dutyDay); this.setPunchIsValid(result); return "success"; } }
<!-- 进入打卡 --> <action name="*Punch" class="org.crazyit.app.hrsystem.action.PunchAction"> <interceptor-ref name="empStack"/> <result>/content/{1}/punch.jsp</result> </action>
。。。。。
使用拦截器完成权限管理:
import org.crazyit.app.hrsystem.action.WebConstant; import com.opensymphony.xwork2.*; import com.opensymphony.xwork2.interceptor.*; public class EmpAuthorityInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub //创建ActionContext实例 ActionContext ctx = ActionContext.getContext(); //获取HttpSession中的level属性 String level = (String)ctx.getSession() .get(WebConstant.LEVEL); //如果level不为null,且level为emp或mgr if (level != null && (level.equals(WebConstant.EMP_LEVEL) || level.equals(WebConstant.MGR_LEVEL))) { return invocation.invoke(); } else { return Action.LOGIN; } } }
如果HttpSession里的level不为null,且level为emp或mgr,放行。
public class MgrAuthorityInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub //创建ActionContext实例 ActionContext ctx = ActionContext.getContext(); //获取HttpSession中的level属性 String level = (String)ctx.getSession() .get(WebConstant.LEVEL); //如果level不为null,且level为mgr if ( level != null && level.equals(WebConstant.MGR_LEVEL)) { return invocation.invoke(); } else { return Action.LOGIN; } } }
<interceptors> <!-- 配置普通员工角色的权限检查拦截器 --> <interceptor name="empAuth" class= "org.crazyit.app.hrsystem.action.authority.EmpAuthorityInterceptor"/> <!-- 配置经理角色的权限检查拦截器 --> <interceptor name="mgrAuth" class= "org.crazyit.app.hrsystem.action.authority.MgrAuthorityInterceptor"/> <!-- 配置普通员工的默认的拦截器栈 --> <interceptor-stack name="empStack"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="empAuth"/> </interceptor-stack> <!-- 配置经理的默认的拦截器栈 --> <interceptor-stack name="mgrStack"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="mgrAuth"/> </interceptor-stack> </interceptors>