zoukankan      html  css  js  c++  java
  • day37_Spring学习笔记_05_CRM_01

    一、CRM 客户关系管理系统

    CRM : custom releation manager 客户关系管理系统,用于维护客户和公司之间关系。
    我们要做的是:学校 和 大家 之间关系。

    • 完成功能:
    • 员工管理:
      1、登录(登录拦截器、服务器端校验)
      2、查询(普通查询、高级查询)
      3、编辑员工(标签回显、ajax 二级联动)
    • 课程类别:
      1、查询(查询所有 + 条件 + 分页)
      2、添加和编辑
    • 班级管理:
      1、查询
      2、课表的上传、下载
    • 工具类
      1、BaseDao
      2、BaseAction

    二、环境搭建

    2.1、导入jar包

    2.2、创建数据库和表

    create database if not exists `day36_crmdb`;
    USE `day36_crmdb`;
    --------------------------------------------------------
    CREATE TABLE `crm_department` (
      `depId` varchar(255NOT NULL PRIMARY KEY,
      `depName` varchar(50DEFAULT NULL
    );

    insert into `crm_department`(`depId`,`depName`
        values  ('2c9091c14c78e58b014c78e67de10001','java学院'),
                ('2c9091c14c78e58b014c78e68ded0002','咨询部');
    --------------------------------------------------------
    CREATE TABLE `crm_post` (
      `postId` varchar(255NOT NULL PRIMARY KEY,
      `postName` varchar(100DEFAULT NULL,
      `depId` varchar(255DEFAULT NULL,
      CONSTRAINT FOREIGN KEY (`depId`REFERENCES `crm_department` (`depId`)
    );

    insert into `crm_post`(`postId`,`postName`,`depId`
        values  ('2c9091c14c78e58b014c78e6b34a0003','总监','2c9091c14c78e58b014c78e67de10001'),
                ('2c9091c14c78e58b014c78e6d4510004','讲师','2c9091c14c78e58b014c78e67de10001'),
                ('2c9091c14c78e58b014c78e6f2340005','主管','2c9091c14c78e58b014c78e68ded0002');
    --------------------------------------------------------
    CREATE TABLE `crm_staff` (
      `staffId` varchar(255NOT NULL PRIMARY KEY,
      `loginName` varchar(100DEFAULT NULL,
      `loginPwd` varchar(100DEFAULT NULL,
      `staffName` varchar(100DEFAULT NULL,
      `gender` varchar(20DEFAULT NULL,
      `onDutyDate` datetime DEFAULT NULL,
      `postId` varchar(255DEFAULT NULL,
      CONSTRAINT FOREIGN KEY (`postId`REFERENCES `crm_post` (`postId`)
    );

    insert into `crm_staff`(`staffId`,`loginName`,`loginPwd`,`staffName`,`gender`,`onDutyDate`,`postId`
        values  ('2c9091c14c78e58b014c78e5c32a0000','jack','81dc9bdb52d04dc20036dbd8313ed055','管理员',NULL,NULL,NULL),
                ('2c9091c14c78e58b014c78e759b40006','rose','81dc9bdb52d04dc20036dbd8313ed055','肉丝','女','2013-04-16 00:00:00','2c9091c14c78e58b014c78e6f2340005'),
                ('2c9091c14c78e58b014c78e7ecd90007','tom','81dc9bdb52d04dc20036dbd8313ed055','汤姆','男','2014-04-24 00:00:00','2c9091c14c78e58b014c78e6d4510004');
    --------------------------------------------------------
    CREATE TABLE `crm_course_type` (
      `courseTypeId` varchar(255NOT NULL PRIMARY KEY,
      `courseCost` double DEFAULT NULL,
      `total` int(11DEFAULT NULL,
      `courseName` varchar(500DEFAULT NULL,
      `remark` varchar(5000DEFAULT NULL
    );

    insert into `crm_course_type`(`courseTypeId`,`courseCost`,`total`,`courseName`,`remark`
        values  ('2c9091c14c78e58b014c78e829b70008',2000,1000,'java基础',''),
                ('2c9091c14c78e58b014c78e867b80009',18000,4000,'java就业','');
    --------------------------------------------------------
    CREATE TABLE `crm_classes` (
      `classesId` varchar(50NOT NULL PRIMARY KEY,
      `courseTypeId` varchar(255DEFAULT NULL,
      `name` varchar(50DEFAULT NULL,
      `beginTime` datetime DEFAULT NULL,
      `endTime` datetime DEFAULT NULL,
      `status` varchar(20DEFAULT NULL,
      `totalCount` int(11DEFAULT NULL,
      `upgradeCount` int(11DEFAULT NULL,
      `changeCount` int(11DEFAULT NULL,
      `runoffCount` int(11DEFAULT NULL,
      `remark` varchar(500DEFAULT NULL,
      `uploadTime` datetime DEFAULT NULL,
      `uploadPath` varchar(200DEFAULT NULL,
      `uploadFilename` varchar(100DEFAULT NULL,
      CONSTRAINT FOREIGN KEY (`courseTypeId`REFERENCES `crm_course_type` (`courseTypeId`)
    ) ;

    insert into `crm_classes`(`classesId`,`courseTypeId`,`name`,`beginTime`,`endTime`,`status`,`totalCount`,`upgradeCount`,`changeCount`,`runoffCount`,`remark`,`uploadTime`,`uploadPath`,`uploadFilename`
        values  ('2c9091c14c78e58b014c78e8cc62000a','2c9091c14c78e58b014c78e829b70008','1期','2015-03-10 00:00:00','2015-04-30 00:00:00',NULL,80,2,0,2,'','2015-04-02 16:33:09','/WEB-INF/upload/0d7a042741544da988b2d2462c683e57','(第173期)2015年01月22日 JavaEE就业班.xls'),
                ('2c9091c14c78e58b014c78e9106e000b','2c9091c14c78e58b014c78e829b70008','2期','2015-04-28 00:00:00','2015-05-27 00:00:00',NULL,67,0,0,0,'',NULL,NULL,NULL),
                ('2c9091c14c78e58b014c78e9601a000c','2c9091c14c78e58b014c78e867b80009','1期ee','2015-03-29 00:00:00','2015-07-13 00:00:00',NULL,120,0,0,0,'',NULL,NULL,NULL);

    ER图如下:

    2.3、项目目录命名规范

    com.itheima.crm.子模块.分层
    例如:
    com.itheima.crm.staff.dao.impl          员工dao层和实现类
    com.itheima.crm.staff.service.impl      员工service层和实现类
    com.itheima.crm.staff.web.action        员工web
    com.itheima.crm.staff.domain            员工javabean

    2.4、编写PO类+对应的配置文件Xxx.hbm.xml

    仅以 CrmClasses.java、CrmClasses.hbm.xml 和 CrmCourseType.java、CrmCourseType.hbm.xml 为示例:
    CrmClasses.java

    package com.itheima.crm.classes.domain;

    import java.util.Date;

    import com.itheima.crm.coursetype.domain.CrmCourseType;

    public class CrmClasses {
        /*
            CREATE TABLE `crm_classes` (
              `classesId` varchar(50) NOT NULL PRIMARY KEY,
              `courseTypeId` varchar(255) DEFAULT NULL,
              `name` varchar(50) DEFAULT NULL,
              `beginTime` datetime DEFAULT NULL,
              `endTime` datetime DEFAULT NULL,
              `status` varchar(20) DEFAULT NULL,
              `totalCount` int(11) DEFAULT NULL,
              `upgradeCount` int(11) DEFAULT NULL,
              `changeCount` int(11) DEFAULT NULL,
              `runoffCount` int(11) DEFAULT NULL,
              `remark` varchar(500) DEFAULT NULL,
              `uploadTime` datetime DEFAULT NULL,
              `uploadPath` varchar(200) DEFAULT NULL,
              `uploadFilename` varchar(100) DEFAULT NULL,
              CONSTRAINT FOREIGN KEY (`courseTypeId`) REFERENCES `crm_course_type` (`courseTypeId`)
            ) ;
         */

        private String classesId;
        private String name;            // 班级名称
        private Date beginTime;         // 开班时间
        private Date endTime;           // 毕业时间

        private String status;          // 状态(未开课/已开课/已结束)数据库不需要保存,页面通过计算获得,此字段可以删除
        private Integer totalCount;     // 学生总数
        private Integer upgradeCount;   // 升学数

        private Integer changeCount;    // 转班数(转来)
        private Integer runoffCount;    // 退费数(流失)
        private String remark;          // 其他说明

        private Date uploadTime;        // 上传时间
        private String uploadPath;      // 上传课表路径
        private String uploadFilename;  // 上传课表名称

        // 多对一:多个班级共享【一个课程类别】
        private CrmCourseType courseType;

        // getter 和 setter 方法
        // ......
    }

    CrmClasses.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-mapping>
        <class name="com.itheima.crm.classes.domain.CrmClasses" table="crm_classes">
            <id name="classesId">
                <generator class="uuid"></generator>
            </id>

            <property name="name"></property>
            <property name="beginTime" type="date"></property>
            <property name="endTime" type="date"></property>

            <property name="status"></property>
            <property name="totalCount"></property>
            <property name="upgradeCount"></property>

            <property name="changeCount"></property>
            <property name="runoffCount"></property>
            <property name="remark"></property>

            <property name="uploadTime">
                <column name="uploadTime" sql-type="datetime"></column>
            </property>
            <property name="uploadPath"></property>
            <property name="uploadFilename"></property>

            <!-- 多对一:多个班级共享【一个课程类别】  -->
            <many-to-one name="courseType" class="com.itheima.crm.coursetype.domain.CrmCourseType" column="courseTypeId"></many-to-one>
        </class>
    </hibernate-mapping>

    CrmCourseType.java

    public class CrmCourseType {
        /*
            CREATE TABLE `crm_course_type` (
              `courseTypeId` varchar(255) NOT NULL PRIMARY KEY,
              `courseCost` double DEFAULT NULL,
              `total` int(11) DEFAULT NULL,
              `courseName` varchar(500) DEFAULT NULL,
              `remark` varchar(5000) DEFAULT NULL
            );
         */

        private String courseTypeId;
        private Double courseCost;  // 课程费用
        private Integer total;      // 总课时
        private String courseName;  // 课程类别名称
        private String remark;      // 课程介绍模板

        // 一对多:一个课程类别有【多个班级】
        private Set<CrmClasses> classesSet = new HashSet<CrmClasses>();

        // getter 和 setter 方法
        // ......
    }

    CrmCourseType.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-mapping>
        <class name="com.itheima.crm.coursetype.domain.CrmCourseType" table="crm_course_type">
            <id name="courseTypeId">
                <generator class="uuid"></generator>
            </id>

            <property name="courseCost"></property>
            <property name="total"></property>
            <property name="courseName"></property>
            <property name="remark"></property>

            <!-- 一对多:一个课程类别有【多个班级】  -->
            <set name="classesSet">
                <key column="courseTypeId"></key>
                <one-to-many class="com.itheima.crm.classes.domain.CrmClasses"/>
            </set>
        </class>
    </hibernate-mapping>

    2.5、spring 配置

    2.5.1、源码文件夹的使用

    • 注意1:如何移除源码文件夹属性
    • 注意2:如何添加源码文件夹属性
    • 注意3:清除classes目录下的文件并再次编译
      选中项目 --> Project --> Clean… --> 选择要清理的项目 --> Ok 即可。

    2.5.2、spring 配置文件位置

    • 在applicationContext.xml 中配置其他 applicationContext.-staff.xml 的引用,如下图所示:

    2.5.3、web.xml 配置

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
        http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

        id="WebApp_ID" version="3.1">


        <!-- 1.1、spring配置文件位置 
               方式1: 【建议该方式】
               <param-value>classpath:spring/applicationContext.xml</param-value> 
                    需要在applicationContext.xml 配置<import> 导入其他  applicationContext-staff.xml(例如) 文件
               方式2: 
               <param-value>classpath:spring/applicationContext*.xml</param-value> 
                    加载所有,不需要配置<import> 导入其他配置文件
        -->

        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/applicationContext.xml</param-value>
        </context-param>

        <!-- 1.2、 加载spring配置文件所使用的监听器 -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    </web-app>

    2.5.4、spring 配置文件内容

    applicationContext.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:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                  http://www.springframework.org/schema/beans/spring-beans.xsd
                                  http://www.springframework.org/schema/tx 
                                  http://www.springframework.org/schema/tx/spring-tx.xsd
                                  http://www.springframework.org/schema/aop 
                                  http://www.springframework.org/schema/aop/spring-aop.xsd
                                  http://www.springframework.org/schema/context 
                                  http://www.springframework.org/schema/context/spring-context.xsd"
    >

        <!-- 公共配置项 -->
        <!-- 1.1、加载properties配置文件 -->
        <context:property-placeholder location="classpath:JdbcInfo.properties"/>

        <!-- 1.2、配置数据源,基本四项 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driverClass}"></property>
            <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
            <property name="user" value="${jdbc.user}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>

        <!-- 2、配置 LocalSessionFactoryBean,获得SessionFactory -->
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource"></property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                </props>
            </property>
            <property name="mappingLocations" value="classpath:com/itheima/crm/*/domain/*.hbm.xml"></property>
        </bean>

        <!-- 3、事务管理 -->
        <!-- 3.1、 事务管理器 :HibernateTransactionManager -->
        <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
        <!-- 3.2 、事务详情 ,给ABC进行具体的事务设置 ,增删改:读写,查询:只读-->
        <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="add*"/>
                <tx:method name="update*"/>
                <tx:method name="delete*"/>
                <tx:method name="find*" read-only="true"/>
            </tx:attributes>
        </tx:advice>
        <!-- 3.3、AOP编程,从 ABCD 业务中 筛选出 ABC,如果强制使用cglib代理 :  proxy-target-class="true" -->
        <aop:config>
            <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.crm.*.service..*.*(..))"/>
        </aop:config>

        <!-- 导入其他配置文件 -->
        <import resource="applicationContext-staff.xml"/>
    </beans>

    2.6、struts 配置

    2.6.1、struts 配置文件位置

    • struts 的配置文件有一个要求:struts的根文件struts.xml必须放在类路径下,即在源码文件夹下(也即classes目录下)
    • struts.xml 加载其它 struts-staff.xml

    struts.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">


    <struts>
        <!-- 1、常量配置 -->
        <!-- 1.1、开发模式 -->
        <constant name="struts.devMode" value="true"></constant>
        <!-- 1.2、标签主题:简单风格 -->
        <constant name="struts.ui.theme" value="simple"></constant>

        <!-- 2 、配置公共项 -->
        <package name="common" namespace="/" extends="struts-default">

        </package>  

        <!-- 3、 加载其他配置文件 -->
        <include file="struts/struts-staff.xml"></include>
    </struts>
    • 其他struts-staff.xml配置,继承 struts.xml配置的公共项

    struts-staff.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">


    <struts>
        <!-- 员工的配置 -->
        <package name="sta" namespace="/" extends="common">

        </package>  
    </struts>

    截图如下:


    2.6.2、web.xml 配置

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
        http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

        id="WebApp_ID" version="3.1">


        <!-- 1.1、spring配置文件位置 
               方式1: 【建议该方式】
               <param-value>classpath:spring/applicationContext.xml</param-value> 
                    需要在applicationContext.xml 配置<import> 导入其他  applicationContext-staff.xml(例如) 文件
               方式2: 
               <param-value>classpath:spring/applicationContext*.xml</param-value> 
                    加载所有,不需要配置<import> 导入其他配置文件
        -->

        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/applicationContext.xml</param-value>
        </context-param>

        <!-- 1.2、 加载spring配置文件所使用的监听器 -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

        <!-- 2、struts 前端控制器的配置 -->
        <filter>
            <filter-name>struts2</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>struts2</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>   
    </web-app>

    2.7、代码编写思路


    三、员工登录

    思路:
        1. 编写dao层:通过账号和密码查询
        2. 编写service层:主要事务管理(已经配置)
        3. 配置spring
        4. jsp 登录表单
        5. struts-staff.xml 配置
        6. StaffAction编写
            通过service查询
                查询到结果:将信息保存session作用域,重定向首页。(action方法中直接return了,重定向在xml中完成)
                没有结果:在request作用域保存提示信息,请求转发显示提示信息。(在struts中,request作用域 == 值栈) 

    3.1、dao 层

    • 注意:之后我们在spring配置dao层时,需要注入SessionFactory。

    StaffDao.java

    public interface StaffDao {
        /**
         * 通过用户名和密码查询
         * 
         * @param loginName
         * @param loginPwd
         * @return
         */

        public CrmStaff find(String loginName, String loginPwd);
    }

    StaffDaoImpl.java

    public class StaffDaoImpl extends HibernateDaoSupport implements StaffDao {

        @Override
        public CrmStaff find(String loginName, String loginPwd) {
            List<CrmStaff> allStaff = this.getHibernateTemplate().find("from crm_staff where loginName=? and loginPwd=?", loginName, loginPwd);
            if (allStaff.size() == 1) {
                return allStaff.get(0);
            }
            return null;
        }
    }

    3.2、service 层

    StaffService.java

    public interface StaffService {
        /**
         * 用户登录
         * 
         * @param staff
         * @return
         */

        public CrmStaff login(CrmStaff staff);
    }

    StaffServiceImpl.java

    public class StaffServiceImpl implements StaffService {

        private StaffDao staffDao;
        public void setStaffDao(StaffDao staffDao) {
            this.staffDao = staffDao;
        }

        @Override
        public CrmStaff login(CrmStaff staff) {
            return staffDao.find(staff.getLoginName(), staff.getLoginPwd());
        }
    }

    3.3、spring 配置

    applicationContext-staff.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:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                  http://www.springframework.org/schema/beans/spring-beans.xsd
                                  http://www.springframework.org/schema/tx 
                                  http://www.springframework.org/schema/tx/spring-tx.xsd
                                  http://www.springframework.org/schema/aop 
                                  http://www.springframework.org/schema/aop/spring-aop.xsd
                                  http://www.springframework.org/schema/context 
                                  http://www.springframework.org/schema/context/spring-context.xsd"
    >


        <!-- 员工配置项  dao、service-->
        <bean id="staffDao" class="com.itheima.crm.staff.dao.impl.StaffDaoImpl">
            <property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
        <bean id="staffService" class="com.itheima.crm.staff.service.impl.StaffServiceImpl">
            <property name="staffDao" ref="staffDao"></property>
        </bean>
    </beans>

    3.4、jsp 文件位置

    • 实际开发中,所有的jsp页面在WEB-INF目录下。(因为这样,就不能通过浏览器直接访问它们了)
    • 例如:WEB-INF/pages/模块/*.jsp,如下图所示:

    3.5、修改登录表单

    • 登录表单位置:/day36_06_Spring_crm/WebRoot/WEB-INF/pages/login.jsp
    • 表单是否需要struts标签(<%@ taglib uri="/struts-tags" prefix="s"%>),取决于:是否回显。要回显,就需要struts标签。

    login.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>

    <%@ taglib uri="/struts-tags" prefix="s"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML><HEAD>
    <STYLE>
    .cla1 {
    FONT-SIZE12pxCOLOR#4b4b4bLINE-HEIGHT18pxTEXT-DECORATION: none
    }
    .login_msg{
        font-family:serif;
    }
    .login_msg .msg{
        background-color#acf;
    }
    .login_msg .btn{
        background-color#9be;
        width73px;
        font-size18px;
        font-family: 微软雅黑;
    }
    </STYLE>

    <TITLE></TITLE>
        <script type="text/javascript">
            if(self != top){
                top.location = self.location;
            }
        
    </script>
    <META http-equiv=Content-Type content="text/html; charset=utf-8">
    <LINK href="${pageContext.request.contextPath}/css/style.css" type=text/css rel=stylesheet>
    <META content="MSHTML 6.00.2600.0" name=GENERATOR></HEAD>
    <BODY leftMargin=0 topMargin=0 marginwidth="0" marginheight="0" background="${pageContext.request.contextPath}/images/rightbg.jpg">
    <div ALIGN="center">
        <table border="0" width="1140px" cellspacing="0" cellpadding="0" id="table1">
            <tr>
                <td height="93"></td>
                <td></td>
            </tr>
            <tr>
                <td background="${pageContext.request.contextPath}/images/right.jpg"  width="740" height="412"></td>
                <td class="login_msg" width="400">
                    <!-- 表单 -->
                    <s:form namespace="/" action="staffAction_login">
                        &nbsp;<img src="${pageContext.request.contextPath}/images/title.png" width="185" height="26"/>
                        <br/>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                        <font color="#ff0000">
                            <s:fielderror></s:fielderror>
                        </font> 
                        <br/>
                        用户名:<s:textfield name="loginName" cssClass="msg"></s:textfield><br/><br/>
                        密&nbsp;码:<s:password name="loginPwd" cssClass="msg" showPassword="true"></s:password><br/><br/>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                        <s:submit value="登录" cssClass="btn"></s:submit>         
                    </s:form>
                    <!-- 
                    <form action="${pageContext.request.contextPath}/pages/frame.jsp" method="post">
                        &nbsp;<img src="${pageContext.request.contextPath}/images/title.png" width="185" height="26"/>
                        <br/>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                        <font color="#ff0000">
                            错误提示
                        </font> 
                        <br/>
                        用户名:<input type="text" name="loginName" class="msg" /><br/><br/>
                        密&nbsp;码:<input type="password" class="msg" /><br/><br/>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                        <input type="submit" class="btn" value="登录 " />
                    </form>
                    -->


                    <!-- jsp的页面,作用:测试用,用完后删除掉-->
                    <a href="${pageContext.request.contextPath}/pages/frame.jsp">jsp页面</a>
                </td>
            </tr>
        </table>

        <script type="text/javascript">
            /* s标签中直接编写JavaScript代码时,不支持el表达式,只能提供单独的函数
            function registerUrl() {
                document.location='${pageContext.request.contextPath}/uiAction_staff_register';
            }
            */

        
    </script>
    </div>
    </BODY></HTML>

    3.6、struts-staff.xml 配置

    • /day36_06_Spring_crm/config/struts/struts-staff.xml

    struts-staff.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">


    <struts>
        <!-- 员工的配置 -->
        <package name="sta" namespace="/" extends="common">
            <action name="staffAction_*" class="com.itheima.crm.staff.web.action.StaffAction" method="{1}">
                <!-- 1、登录成功 -->
                <result name="success" type="redirectAction">staffAction_home</result>
                <!-- 2、登录不成功,需要重新登录 -->
                <result name="login">/WEB-INF/pages/login.jsp</result>
                <!-- 3、返回 首页-->
                <result name="home">/WEB-INF/pages/frame.jsp</result>
            </action>
        </package>  
    </struts>

    3.7、Action实现类

    StaffAction.java

    public class StaffAction extends ActionSupport implements ModelDriven<CrmStaff{

        // ****************************************************************
        // 公共代码

        // 封装数据
        private CrmStaff staff = new CrmStaff();

        @Override
        public CrmStaff getModel() {
            return staff;
        }

        // 默认按照名称进行注入
        private StaffService staffService;
        public void setStaffService(StaffService staffService) {
            this.staffService = staffService;
        }

        // ****************************************************************
        // 业务代码(功能代码)

        /**
         * 员工登录 
         * 
         * @return
         */

        public String login() {
            // 1、查询员工
            CrmStaff findStaff = staffService.login(staff);

            // 2、判断是否成功
            if (findStaff != null) {
                // 登录成功
                // 3.1、把数据保存在session作用域
                ActionContext.getContext().getSession().put("loginStaff", findStaff);
                // 3.2、重定向至首页,需要在 struts-staff.xml 中进行配置
                return "success";
            }
            // 4、登录不成功,添加错误显示信息
            this.addFieldError("""登录名或密码错误");
            // 5、请求转发显示
            return "login";
        }

        /**
         * 显示首页
         * 
         * @return
         */

        public String home() {
            return "home";
        }
    }

    3.8、密码加密

    • /day36_06_Spring_crm/src/com/itheima/crm/utils/MyStringUtils.java

    编写我的工具类
    MyStringUtils.java

    public class MyStringUtils {
        /**
         * 获得MD5加密后的数据
         * 
         * @param value 明文
         * @return  密文
         */

        public static String getMD5Value(String value{

            try {
                // 1、获得jdk所提供的消息摘要算法的工具类
                MessageDigest messageDigest = MessageDigest.getInstance("MD5");
                // 2、加密操作,加密的结果是十进制,需要转换为16进制
                byte[] md5ValueByteArray =  messageDigest.digest(value.getBytes());
                BigInteger bigInteger = new BigInteger(1, md5ValueByteArray);

                return bigInteger.toString(16);
            } catch (NoSuchAlgorithmException e) {
                // 法一:抛出异常
                throw new RuntimeException(e);
                // 法二:如果出现了异常,将返回默认值
                // return value;
            }
        }
    }
    • 修改service层代码
    package com.itheima.crm.staff.service.impl;

    import com.itheima.crm.staff.dao.StaffDao;
    import com.itheima.crm.staff.domain.CrmStaff;
    import com.itheima.crm.staff.service.StaffService;
    import com.itheima.crm.utils.MyStringUtils;

    public class StaffServiceImpl implements StaffService {

        private StaffDao staffDao;
        public void setStaffDao(StaffDao staffDao) {
            this.staffDao = staffDao;
        }

        @Override
        public CrmStaff login(CrmStaff staff) {
            // MD5加密操作
            String loginPwd = MyStringUtils.getMD5Value(staff.getLoginPwd());
            return staffDao.find(staff.getLoginName(), loginPwd);
        }
    }

    四、UiAction

    • 配置公共jsp访问的action

    struts.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">


    <struts>
        <!-- 1、常量配置 -->
        <!-- 1.1、开发模式 -->
        <constant name="struts.devMode" value="true"></constant>
        <!-- 1.2、标签主题:简单风格 -->
        <constant name="struts.ui.theme" value="simple"></constant>

        <!-- 2 、配置公共项 -->
        <package name="common" namespace="/" extends="struts-default">
        <!-- 2.1、配置公共jsp访问的action 
            版本1:通过自定义action实现,自定义的action继承父类ActionSupport
                <action name="uiAction" class="com.itheima.crm.web.action.UiAction">
                    <result name="success">/WEB-INF/pages/frame/top.jsp</result>
                </action>

            版本2:直接通过父类ActionSupport
                <action name="uiAction" class="com.opensymphony.xwork2.ActionSupport">
                    <result name="success">/WEB-INF/pages/frame/top.jsp</result>
                </action>

                能否将class属性删除呢? 因为class属性的默认值就是“ActionSupport”  
                <action name="uiAction">
                    <result name="success">/WEB-INF/pages/frame/top.jsp</result>
                </action>

                name属性值也可以删除掉,因为其默认值也是“success”
                <action name="uiAction">
                    <result>/WEB-INF/pages/frame/top.jsp</result>
                </action>

            版本3:使用通配符
                <action name="uiAction_*_*">
                    <result>/WEB-INF/pages/{1}/{2}.jsp</result>
                </action>

                uiAction_*_*
                    第一个星匹配的是文件夹的名称,通过{1}获取
                    第二个星匹配的是jsp文件名称,通过{2}获取
                例如:
                    uiAction_frame_top 匹配的是  /WEB-INF/pages/frame/top.jsp
            -->

            <action name="uiAction_*_*">
                <result>/WEB-INF/pages/{1}/{2}.jsp</result>
            </action>
        </package>  

        <!-- 3、 加载其他配置文件 -->
        <include file="struts/struts-staff.xml"></include>
    </struts>

    五、登录拦截器

    • 必须是登录状态,才能访问首页,否则不能访问。
    • 回顾登录拦截器实现类
    • struts中的配置
      1. 先注册,将登录拦截器实现类配置给struts
      2. 再使用
        2.1 每一个action单独使用登录拦截器
        2.2 将多个拦截器打包生成自定义栈,在action中使用自定义栈
        2.3 使用自定义的栈,把默认的栈覆盖(即把自定义栈声明成默认的栈)
    • 功能:判断session作用域中是否有用户信息,如果有就放行,如果没有就拦截掉。

    5.1、实现类

    LoginInterceptor.java

    public class LoginInterceptor extends MethodFilterInterceptor {

        @Override
        protected String doIntercept(ActionInvocation invocation) throws Exception {
            // 判断session作用域中是否有用户信息,如果有就放行,如果没有就拦截掉。
            CrmStaff crmStaff = (CrmStaff) ActionContext.getContext().getSession().get("loginStaff");
            if (crmStaff == null) {
                // 同理:StaffAction.java中的login()方法一样:
                // 1、获得当前运行的action
                Object action = invocation.getAction();
                // 2、判断:在运行时的action对象是否是ActionSupport对象
                if (action instanceof ActionSupport) {
                    // 如果是,就进行强转
                    ActionSupport actionSupport = (ActionSupport) action;
                    // 4、登录不成功,添加错误显示信息
                    actionSupport.addFieldError("""请重新登录");
                }

                // 没有登录,需要登录
                return "login";
            }
            // 已经登录了,就放行
            return invocation.invoke();
        }
    }

    5.2、struts.xml 中的配置

    struts.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">


    <struts>
        <!-- 1、常量配置 -->
        <!-- 1.1、开发模式 -->
        <constant name="struts.devMode" value="true"></constant>
        <!-- 1.2、标签主题:简单风格 -->
        <constant name="struts.ui.theme" value="simple"></constant>

        <!-- 2 、配置公共项 -->
        <package name="common" namespace="/" extends="struts-default">
            <!-- 2.2、登录拦截器的配置 
                前提:都要先声明
                方式一:每一个action单独使用登录拦截器,需要多次引用,否则默认的拦截器将被覆盖
                    <action name="uiAction_*_*">
                        <result>/WEB-INF/pages/{1}/{2}.jsp</result>
                        <interceptor-ref name="defaultStack"></interceptor-ref>
                        <interceptor-ref name="loginInterceptor"></interceptor-ref>
                    </action>

                方式二:将多个拦截器打包生成自定义栈,在action中使用自定义栈
                    <interceptor-stack name="loginStack">
                        <interceptor-ref name="defaultStack"></interceptor-ref>
                        <interceptor-ref name="loginInterceptor"></interceptor-ref>
                    </interceptor-stack>                

                    <action name="uiAction_*_*">
                        <result>/WEB-INF/pages/{1}/{2}.jsp</result>
                        <interceptor-ref name="loginStack"></interceptor-ref>
                    </action>

                方式三:使用自定义的栈,把默认的栈覆盖(即把自定义栈声明成默认的栈)
                    <default-interceptor-ref name="loginStack"></default-interceptor-ref>

                    <action name="uiAction_*_*">
                        <result>/WEB-INF/pages/{1}/{2}.jsp</result>
                        <interceptor-ref name="loginStack"></interceptor-ref>
                    </action>
            -->

            <interceptors>
                <!-- 2.2.1、声明(注册),将登录拦截器实现类配置给struts -->
                <interceptor name="loginInterceptor" class="com.itheima.crm.web.interceptor.LoginInterceptor"></interceptor>
                <!-- 2.2.2、 自定义拦截器栈 -->
                <interceptor-stack name="loginStack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <!-- 自定义登录拦截器:需要配置对login()方法不进行拦截 
                        * excludeMethods 配置不包含的方法,多个方法使用逗号分隔
                    -->

                    <interceptor-ref name="loginInterceptor">
                        <param name="excludeMethods">login</param>
                    </interceptor-ref>
                </interceptor-stack>
            </interceptors>

            <!-- 2.2.3、 使用自定义的栈,把默认的栈覆盖(即把自定义栈声明成默认的栈)-->
            <default-interceptor-ref name="loginStack"></default-interceptor-ref>
            <!-- 2.2.4、配置全局结果集 -->
            <global-results>
                <result name="login">/WEB-INF/pages/login.jsp</result>
            </global-results>

            <!-- 2.1、配置公共jsp访问的action -->
            <action name="uiAction_*_*">
                <result>/WEB-INF/pages/{1}/{2}.jsp</result>
                <interceptor-ref name="loginStack"></interceptor-ref>
            </action>
        </package>  

        <!-- 3、 加载其他配置文件 -->
        <include file="struts/struts-staff.xml"></include>
    </struts>

    5.3、登录拦截器总结图解

    六、查询所有员工

    思路:
        1. dao层:findAll()
        2. service层:findAllStaff()
        3. action类:findAll() --> staffAction_findAll
        4. jsp页面:显示数据

    6.1、dao 层

    StaffDao.java

        /**
         * 查询所有员工
         * 
         * @return
         */

        public List<CrmStaff> findAll();

    StaffDaoImpl.java

        @Override
        public List<CrmStaff> findAll() {
            return this.getHibernateTemplate().find("from CrmStaff");
        }

    6.2、service层

    StaffService.java

        /**
         * 查询所有员工
         * 
         * @return
         */

        public List<CrmStaff> findAllStaff();

    StaffServiceImpl.java

        @Override
        public List<CrmStaff> findAllStaff() {
            return this.staffDao.findAll();
        }

    6.3、jsp入口

    • 文件位置:/day36_06_Spring_crm/WebRoot/WEB-INF/pages/frame/left.jsp

    6.4、action类

    StaffAction.java

    ......
        /**
         * 查询所有员工
         * 
         * @return
         */

        public String findAll() {
            // 1、查询所有员工
            List<CrmStaff> allStaff = staffService.findAllStaff();
            // 2、将查询的结果放入值栈中,以方便jsp页面获得数据(原则:无论你怎么放,页面上能取的出来就行)
            // 方式一:context(大map中),使用put(key, value) 方法,jsp页面使用 “#key” 方式获得
            //      示例:ActionContext.getContext().put(key, value);
            // 方式二:root(值栈中),使用push(Object)方法,一般我们的查询结果为javabean 或者 为Map时,jsp页面使用 “属性”或者“key”    方式获得
            //      示例:ActionContext.getContext().getValueStack().push(obj);
            // 方式三:root(值栈中),使用set(key, value),一般我们的查询的结果为 集合List 时,jsp页面使用 “key” 方式获得
            //      注意:set(key, value) 的底层使用的是 new Map(key, value),再将Map集合 push(Map)

            // 这里我们使用方式一
            ActionContext.getContext().put("allStaff", allStaff);

            return "findAll";
        }
    ......

    6.5、jsp展示

    • 文件位置:/day36_06_Spring_crm/WebRoot/WEB-INF/pages/staff/listStaff.jsp

    • debug调试结果:

    6.6、web.xml 配置过滤器

    • OpenSessionInViewFilter,作用:延迟关闭session

    注意:必须配置在struts 的前端控制器之前

        <!-- 配置spring 过滤器,延时session的关闭 -->
        <filter>
            <filter-name>OpenSession</filter-name>
            <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>OpenSession</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    • 查询所有员工截图:
  • 相关阅读:
    ASP.NET 2.0 X64 引起的问题
    .net 俱乐部7月份资料下载 .net 开源项目
    用schemaSpy制作数据库文档
    IbatisNet支持2.0的版本Release 发布了
    Introduction to Model Driven Development with AndroMDA
    开放源代码与.NET应用程序平台的性能测试
    sqlserver 2000/2005 Ambiguous column error错误解决办法
    ASP.NET 2.0 中 Web 事件
    使用asp.net 2.0的CreateUserwizard控件如何向自己的数据表中添加数据
    Working with Windows Workflow Foundation in ASP.NET
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/9483593.html
Copyright © 2011-2022 走看看