速动画教程第十八集 SSH框架的构建


录像下载 http://sonic.peakle.net/download/sonic018.rar
 

此过程将包括以下几个框架

Struts 、 Spring 、 Hibernate 、 Tiles 、 validator

 

工具 :Eclipse3.1 、 MyEclipse4.1.1 、 Poperties Editor 插件

 

新建工程 oa

 

jstl标签库很好用,所以也把它加载上

 

增加 Struts 框架

因为在整个架构中 Struts 属于 UI 层,所以将 struts 放入 com.oa.view 包中

 

增加 Spring 框架

将配置文件放入 /WEB-INF/ 目录内

 

在增加 Hibernate 框架之前,如果没有配置过数据连接的话,请打开 MyEclipse Database Exploring 视图

配置连接:以连接 MySql 为例

 

增加 Hibernate 框架

在配置选项中选择使用 Spring 的配置文件,并输入 sessionFactory

Hibernate 属于 Data 层,所以将它放入 com.oa.data 包内

 

逻辑层的包为 com.oa.model

 

以下为目录结构

+ src

   + --com.oa.data  //数据层

    + --com.oa.data.bo   //BO对像和映射文件

    + --com.oa.data.dao   //DAO对像的接口

       + --com.oa.data.dao.impl   //DAO对像的实例

   + --com.oa.model 逻辑层

    + --com.oa.model.service   // Service对像的接口

       + --com.oa.model.service.impl   //Service对像的实例

   + --com.oa.view  视图层

    + --com.oa.view.action   // Action对像

    + --com.oa.view.tag     // 标签

  

 

集成框架:

   

    Spring 和 Hibernate 的集成已经由 MyEclipse 的向导完成

    Struts 和 Spring 的集成将使用 Struts 插件的方式进行集成

    Tiles 、 validator 和 Struts 的集成也是使用插件的方式

 

完整的配置文件如下 :

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

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

 

< struts-config >

    < data-sources />

    < form-beans />

    < global-exceptions />

    < global-forwards />

    < action-mappings />

    < message-resources parameter = "com.oa.web.struts.ApplicationResources" />

    < plug-in className = "org.apache.struts.tiles.TilesPlugin" >

       < set-property property = "definitions-parser-validate" value = "true" />

       < set-property property = "definitions-config" value = "/WEB-INF/tiles-config.xml" />

    </ plug-in >

    < plug-in className = "org.apache.struts.validator.ValidatorPlugIn" >

       < set-property property = "pathnames" value = "/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />

    </ plug-in >

    < plug-in className = "org.springframework.web.struts.ContextLoaderPlugIn" >

       < set-property property = "contextConfigLocation" value = "/WEB-INF/applicationContext.xml,/WEB-INF/serviceContext.xml,/WEB-INF/ view Context.xml" />

    </ plug-in >

</ struts-config >

 

创建 tiles-config.xml 文件 , 内容如下 :

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

<tiles-definitions>

</tiles-definitions>

 

注意以下几点:

  多个配置文件可用逗号分隔

  Validator 的配置文件 "/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" ,这两个文件在 /WEB-INF/ 目录都没有, validator-rules.xml 文件需要从 struts 的包中拷贝过来 , validation.xml 文件需要自行创建

  此文件中spring配置文件我将它分为三个,以区分三层结构中不同的配置,请不要直接在其它两个配置文件中写配置信息,最好是先将配置信息写入到 applicationContext.xml 中,因为只有在此文件中 MyEclipse 才会验证配置信息的合法性

 

还是以 Login 为例做一下测试

 

先将大概用到的包都创建好

 

将配置文件中提到的文件都准备好

   先将 spring 的配置文件创建好,文件格式使用 applicationContext.xml 的样式,内容如下:

     serviceContext.xml   viewContext.xml

 

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

<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >

< beans >

</ beans >

 

   拷贝 validator-rules.xml 到 /WEB-INF/ 目录

   创建 validation.xml 文件到 /WEB-INF/ 目录 , 文件内容可以为空

 

创建表 , 以下语句是使用 MySqlCC 生成的

CREATE TABLE `userlist` (

  `id` int(11) NOT NULL auto_increment,

  `userName` varchar(100) NOT NULL default '',

  `userPwd` varchar(100) NOT NULL default '',

  PRIMARY KEY  (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1;

 

打开 MyEclipse Database Exploring 视图 , 创建 userlist 表的映射

根据向导创建映射文件 , 包插抽像类和 DAO , 更改 Userlist 表映射为 User 对像

 

* 这里使用 MyEclipse4.1.1 创建映射文件后 , 文件并没有放到指定的包中 , 所以需要做以下修改

    1 、移动 AbstractUser.java 、 User.java 、 User.hbm.xml 文件到 com.oa.data.bo 包内

    2 、移动 UserDAO.java 文件到 com.oa.data.dao.impl 包内

    3 、修改 applicationContext.xml 文件 , 红色字体部份为修改后的内容

    < bean id = "sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" >

       < property name = "dataSource" >

           < ref bean = "dataSource" />

       </ property >

       < property name = "hibernateProperties" >

           < props >

              < prop key = "hibernate.dialect" > org.hibernate.dialect.MySQLDialect </ prop >

           </ props >

       </ property >

       < property name = "mappingResources" >

           < list >

              < value > com/oa/data/bo/User.hbm.xml </ value >

           </ list >

       </ property >

    </ bean >

    < bean id = "UserDAO" class = " com.oa.data.dao.impl.UserDAO " >

       < property name = "sessionFactory" >

           < ref bean = "sessionFactory" />

       </ property >

    </ bean >

       4 、 修改 User.hbm.xml 文件

       将 < class name = "com.oa.data.bo.User" table = "userlist" catalog = "test" >

          改为 < class name = "com.oa.data.bo.User" table = "userlist" >

       如果不修改的话将会出现以下错误信息

org.springframework.jdbc.BadSqlGrammarException : Hibernate operation: could not execute query; bad SQL grammar [select user0_.id as id, user0_.userName as userName0_, user0_.userPwd as userPwd0_ from test__userlist user0_ where userName=?]; nested exception is java.sql.SQLException : Table 'test.test__userlist' doesn't exist

 

 

创建 UserDAO 的接口文件 IUserDAO , 移动到 com.oa.data.dao 包内 , 修改 UserDAO 的错误

 

创建 IUserService 接口文件 , 内容如下 :

package com.oa.model.service;

import com.oa.data.bo.User;

public interface IUserService {

//  验证用户是否合法 , 并返回一个 User 对像

    public User isValidUser(String username,String password);

}

 

创建此接口的实例 UserService , 此实例需要用到 userDAO , 所以需要做以下声明

private IUserDAO userDAO;

 

userDAO 属性需要使用 ioc 注入

完整代码如下 :

package com.oa.model.service.impl;

 

import com.oa.data.bo.User;

import com.oa.data.dao.IUserDAO;

import com.oa.model.service.IUserService;

 

public class UserService implements IUserService {

 

    private IUserDAO userDAO;

   

    public User isValidUser(String username, String password) {

        // TODO Auto-generated method stub

        return null;

    }

 

    public IUserDAO getUserDAO() {

        return userDAO;

    }

 

    public void setUserDAO(IUserDAO userDAO) {

        this.userDAO = userDAO;

    }

 

}

 

配置 applicationContext.xml 文件 , 增加以下代码 :

       <!-- 创建事务管理代理类 -->

    < bean id = "transactionManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager" >

       < property name = "sessionFactory" >

           < ref local = "sessionFactory" />

       </ property >

    </ bean >

    <!-- 创建用户事务代理类 -->

    < bean id = "userDaoProxy" class = "org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >

       < property name = "transactionManager" >

           < ref bean = "transactionManager" />

       </ property >

       < property name = "target" >

           < ref local = "UserDAO" />

       </ property >

       < property name = "transactionAttributes" >

           < props >

              < prop key = "insert*" > PROPAGATION_REQUIRED </ prop >

              < prop key = "update*" > PROPAGATION_REQUIRED,readOnly </ prop >

              < prop key = "*" > PROPAGATION_REQUIRED,readOnly </ prop >

           </ props >

       </ property >

    </ bean >

 

增加 ioc 注入的配置代码 , UserDAO 为 UserService 类中的 UserDAO 属性

    < bean id = "UserService" class = "com.oa.model.service.impl.UserService" >

       < property name = "userDAO" >

           < ref bean = "userDaoProxy" />

       </ property >

    </ bean >

 

这一段代码先拷贝到 applicationContext.xml 文件中 , 保存后没有错误提示后再拷贝到 serviceContext.xml 文件中

 

创建 jsp 、 from 、 Action , 这里的 Action 将继承于 org.apache.struts.actions.DispatchAction , 并改名为 UserAction 关于这个对像的说明请参考我以前发表的录像

 

修改 Action 的配置信息为 : 增加了绿色字体部份

< action

      attribute = "loginForm"

      input = "/login.jsp"

      name = "loginForm"

      parameter = "method"

      path = "/login"

      validate="true"

      scope = "request"

      type = "com.oa.web.struts.action. User Action" />

 

修改 UserAction 文件内容 , 增加 userService 属性 , 并创建 set 、 get 方法

 

配置 spring 文件 , 使用 IoC 注入到 User Action 中

在 viewContext.xml 中配置以下内容 :

    < bean name = "/login" class = "com.oa. view .struts.action.UserAction" singleton = "false" >

       < property name = "userService" >

           < ref bean = "UserService" />

       </ property >

    </ bean >

 

* 检测的话请拷贝到 applicationContext.xml 中

 

修改 Action 的配置信息为 : 将 type 修改为 spring 的代理 , 这样注入才能成功

< action

      attribute = "loginForm"

      input = "/login.jsp"

      name = "loginForm"

      parameter = "method"

      path = "/login"

      scope = "request"

      validate = "true"

      type = " org.springframework.web.struts.DelegatingActionProxy " />

 

 

修改 validation.xml 文件 , 做验证处理 , 内容如下 :

< form-validation >

    < global >

       <!-- 密码由数字、 26 个英文字母或者下划线组成的字符串   -->

       < constant >

           < constant-name > pwd </ constant-name >

           < onstant-value > ^\w+$ </ onstant-value >

       </ constant >

    </ global >

    < formset >

       < form name = "loginForm" >

           <!-- 这里的用户名使用邮箱,验证时使用正则表达式进行验证 -->

           < field property = "username" depends = "required,email" >

              < arg0 key = "user.name" />

           </ field >

           < field property = "password" depends = "required,minlength,maxlength,mask" >

              < msg name = "mask" key = "user.register.text15" />

               < arg0 key = "user.register.text09" />

              < arg1 name = "minlength" key = "${var:minlength}" resource = "false" />

              < arg2 name = "maxlength" key = "${var:maxlength}" resource = "false" />

              < var >

                                   <!-- 使用正则表达式规则验证 -->

                  < var-name > mask </ var-name >

                  < var-value > ^\w+$ </ var-value >

              </ var >

              < var >

                                   <!-- 长度不少于 6 位 -->

                  < var-name > minlength </ var-name >

                  < var-value > 6 </ var-value >

              </ var >

              < var >

                                   <!-- 密码长度不大于 20 位 -->

                  < var-name > maxlength </ var-name >

                  < var-value > 20 </ var-value >

              </ var >

           </ field >

       </ form >

    </ formset >

</ form-validation >

 

修改 ApplicationResources 资源文件内容

user.name = User Name

user.password = Password

errors.required = {0} is required.

errors.minlength = {0} cannot be less than {1} characters.

errors.maxlength = {0} cannot be greater than {1} characters.

errors.email = {0} is an invalid email address.

user.login.text1 = Password formate error!

user.login.text2 = Welcome !

user.login.text3 = Login failed !

user.login.text4 = Login succeed!

page.command.submit = Submit

 

 

创建 ApplicationResources_zh_CN 资源文件

user.name = 用户名称

user.password = 登录密码

errors.required = {0} 必需填写 !

errors.minlength = {0} 不能小于 {1} 字符

errors.maxlength = {0} 不能大于 {2} 字符

errors.email = {0} 不是有效的 E-Mail 地址

user.login.text1 = 密码格式不正确 !

user.login.text2 = 欢迎您 !

user.login.text3 = 密码错误 !

user.login.text3 = 登录成功 !

page.command.submit = 提交

 

修改 IUserDAO 文件 , 加入以下方法 :

public abstract User findByUsername(String username);

 

打开 UserDAO 文件 , 实现 findByUsername 方法 , 代码如下 :

public User findByUsername(String username) {

        // TODO Auto-generated method stub

        log.debug("getting User instance with userName: " + username);

        try {

            List list = getHibernateTemplate().find(

                    "from User as u where userName = ?", username);

            if(list.size() > 0) {

                User instance = (User) list.get(0);

                return instance;

            } else {

                return null;

            }

        } catch (RuntimeException re) {

            log.error("get failed", re);

            throw re;

        }

    }

 

修改 UserService 文件中的 isValidUser 方法 , 代码如下 :

    public User isValidUser(String username, String password) {

        // TODO Auto-generated method stub

        User user = userDAO.findByUsername(username);

        if(user == null)

            return null;

        if(user.getUserPwd().equals(password))

            return user;

        return null;

    }

 

新建 ok.jsp 文件 , 内容如下 :

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

<%@ taglib uri = "http://jakarta.apache.org/struts/tags-bean" prefix = "bean" %>

<%@ taglib uri = "http://jakarta.apache.org/struts/tags-html" prefix = "html" %>

 

< html >

    < head >

       < title > OK!!! </ title >

    </ head >

    < body >

       < bean:message key = "user.login.text4" />

    </ body >

</ html >

 

修改 login.jsp 文件 , 内容如下 :

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

<%@ taglib uri = "http://jakarta.apache.org/struts/tags-bean" prefix = "bean" %>

<%@ taglib uri = "http://jakarta.apache.org/struts/tags-html" prefix = "html" %>

 

< html >

    < head >

       < title > JSP for loginForm form </ title >

    </ head >

    < body >

       < html:errors />< br >

       < html:form action = "/login" >

           < bean:message key = "user.name" /> : < html:text property = "username" />< br />

           < bean:message key = "user.password" /> : < html:password property = "password" />< br />

           < input type = "submit" value = " < bean:message key = "page.command.submit" /> " onclick = "document.forms[0].action='login.do?method=loginAction';document.forms[0].submit();" >

       </ html:form >

    </ body >

</ html >

 

 

修改 struts-config.xml 文件 , 配置转向 :

<global-forwards >

    <forward name="goOk" path="/ok.jsp" />

</global-forwards>

 

修改 loginAction 事件代码 :

public ActionForward loginAction(

        ActionMapping mapping,

        ActionForm form,

        HttpServletRequest request,

        HttpServletResponse response) {

        DynaValidatorForm loginForm = (DynaValidatorForm) form;

        // TODO Auto-generated method stub

        ActionMessages errors = new ActionMessages();

        String username = loginForm.getString("username");

        String password = loginForm.getString("password");

        User user = userService.isValidUser(username,password);

        if(user != null){

            request.setAttribute("USER",user);

            return mapping.findForward("goOk");

        } else {

            errors.add("loginfailure",new ActionMessage("user.login.text3"));

            saveErrors(request,errors);

            return mapping.getInputForward();

        }

    }

 

代码完成 , 进行测试 :http://localhost/oa/login.jsp 在此之前请在数据库中手动增加一行记录 , 如 :oksonic@tom.com   abc

 

如果出现 action 出错,一般是 spring 的配置文件出现问题了,可在 src 目录下创建一个 log4j.properties 文件,内容如下:

log4j.rootLogger = DEBUG,CONSOLE,A1,im

log4j.addivity.org.apache = true

# 应用于控制台

log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender

log4j.appender.Threshold = DEBUG

log4j.appender.CONSOLE.Target = System.out

log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout

log4j.appender.CONSOLE.layout.ConversionPattern = [framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n

 

此文件将会输出日志信息到控制台,这样就可以得到错误的具体信息了。

 

此集到此结束!

 

 http://www.oksonic.cn

Email: oksonic@tom.com

   QQ: 71279650