struts架构搭建(二)

    继续在前一节的基础上将登录的数据保存到数据库中,数据持久化用Hibernate3,数据库用mysql5。

    打开第一节的工程dianziStruts2Base。首先第一步,还是导入必备的jar包。

    本节要运用hibernate包,先简单介绍一下Hibernate,Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

    Hibernate下载:我下的版本是Hibernate-release-4.3.0-Beta ,解压后,一共有9个必备包:

  • hibernate-core-4.3.0.Beta2.jar
  • hibernate-commons-annotations-4.0.1.Final.jar
  • hibernate-jpa-2.1-api-1.0.0.Draft-16.jar
  • jandex-1.1.0.Alpha1.jar
  • jboss-logging-3.1.0.GA.jar
  • jboss-transaction-api_1.2_spec-1.0.0.Alpha1.jar
  • antlr-2.7.7.jar
  • dom4j-1.6.1.jar
  • javassist-3.15.0-GA.jar

    mysql驱动包: 我下载的版本是5.0.8,然后解压得到:

  • mysql-connector-java-5.0.8-bin

    另外还有三个包是必备的,可以到findjar网站 搜索并下载,这个网站真的是很有用的一个工具网站:

  • log4j-1.2.13.jar 
  • slf4j-api-1.5.6.jar 
  • slf4j-log4j12-1.5.6.jar

    其次是安装mysql5,我安装的是5.6.11,有关mysql的安装请查看《mysql5全新安装手册》。

    环境都准备好了,下面我们开始正式的组装我们的代码了。

    1,建立实体类 "com.dianzi.model.User.java" 以及其父类SuperAModel,其父类SuperAModel主要实现公共id,代码如下:

    SuperAModel.java:

package com.dianzi.model;

public class SuperAModel {
	protected int id;//主键id

	public int getId() {
		return id;
	};

	public void setId(int id) {
		this.id = id;
	}
}

     User.java:

/**
 * 
 */
package com.dianzi.model;

/**
 * 用户实体
 * 
 * @author frand
 * @date 2013-05-10
 * @version 1.0
 */
public class User extends SuperAModel {

	private static final long serialVersionUID = -2135003197973935025L;
	private String name;//用户名
	private String password;//密码
	private int roleId;//角色

	public User() {

	}

	public User(String username, String password) {
		this.name = username;
		this.password = password;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getRoleId() {
		return roleId;
	}

	public void setRoleId(int roleId) {
		this.roleId = roleId;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

 2、建立映射文件 "User.hbm.xml" 放在 "mapping" 包下,这个文件就是将代码中的类和数据库中的表映射起来,一一对应。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping package="com.dianzi.model">
        <!-- 代码中的类com.dianzi.model.User对应数据库中的表T_USER_TEST -->
	<class name="User" table="T_USER_TEST">
                <!--代码中的字段 id ,对应数据库中的列 id,以下情形相同 -->
		<id name="id" column="id" type="java.lang.Integer">
		         <generator class="native"></generator>
               </id>
		<property name="name" column="name" type="java.lang.String"
			length="100">
		</property>
		<property name="password" column="password"
			type="java.lang.String" length="100">
		</property>
		<property name="roleId" column="roleId"
			type="java.lang.Integer">
		</property>
	</class>
</hibernate-mapping>

    3、在 src 目录下建 "hibernate.cfg.xml" 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<!-- session-factory配置 -->
	<session-factory>
		<!-- 数据库url -->
		<property name="hibernate.connection.url">
			jdbc:mysql://localhost:3306/struts2
		</property>
		<!-- 数据库jdbc驱动 -->
		<property name="hibernate.connection.driver_class">
			 com.mysql.jdbc.Driver
		</property>
		<!-- 数据库用户名 -->
		<property name="hibernate.connection.username">root</property>
		<!-- 数据库用户密码 -->
		<property name="hibernate.connection.password">frandfeng</property>
		
		<!-- dialect,每个数据库都有其对应的dialect以匹配其平台特性 Hibernate2.0-->
		<property name="dialect">
                    org.hibernate.dialect.MySQLDialect
                </property>
		
		<!-- 是否将运行期生成的sql输出到日志以供调试 -->
		<property name="hibernate.show_sql">TRUE</property>
		<!-- 是否使用数据库外连接 -->
		<property name="hibernate.user_outer_join">TRUE</property>
		<!-- 事务管理类型,这里使用JDBC Transaction 
		<property name="hibernate.transation.factory_class">
			org.hibernate.transaction.JDBCTransactionFactory
		</property>-->

		<!-- 映射文件配置,注意配置文件名必须包含其相对于根的全路径 -->
		<mapping resource="mapping/User.hbm.xml" />
	</session-factory> 

</hibernate-configuration>

    4,建立"AutoExportDB.java"工具类,我们执行如下代码,就能轻松将User类导入数据库转变成数据库中的表。不过,前提是我们已经在MySQL中建立了一个名为"struts2"的数据库(根据配置文件hibernate.cfg.xml得来)。

/**
 * 
 */
package com.dianzi.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

/**
 * 生成数据库表
 * 
 * @author frand
 * @date 2013-5-10
 * @version 1.0
 */
public class AutoExportDB {
	static Session session;

	static Configuration config = null;
	static Transaction tx = null;

	/**
	 * 运行此类,通过POJO类和配置文件,创建数据库结构
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("开始自动创建数据库结构...");
		try {
			config = new Configuration().configure();

			SessionFactory sessionFactory = config.buildSessionFactory();
			session = sessionFactory.openSession();
			tx = session.beginTransaction();

			SchemaExport schemaExport = new SchemaExport(config);
			schemaExport.create(true, true);

			tx.commit();
			System.out.println("数据库结构创建成功...");
		} catch (HibernateException e) {
			e.printStackTrace();
			System.out.println("数据库结构创建失败...");
			try {
				tx.rollback();
			} catch (HibernateException e1) {
				e1.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("数据库结构创建失败...");
			try {
				tx.rollback();
			} catch (HibernateException e1) {
				e1.printStackTrace();
			}
		} finally {
			System.out.println("结束...");
		}
	}
}

     5,建立获取SessionFactory和管理Session的HibernateUtil.java类:

/**
 * 
 */
package com.dianzi.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Session管理类
 * @author frand
 * @date 2013-05-10
 * @version 1.0
 */
public class HibernateUtil {
	// 声明Hibernate配置文件所在的路径
	private static String configFile = "/hibernate.cfg.xml";
	// 建Configuration对象
	private static Configuration configuration = new Configuration();
	// 建Session工厂对象
	private static SessionFactory sessionFactory = null;

	/**
	 * 单例模式,只初始化一次,只产生一个SessionFactory对象(线程安全)
	 */
	static {
		try {
			// 通过hibernate.cfg.xml配置数据库连接
			configuration.configure(configFile);
			// 建立一个Session工厂
			sessionFactory = configuration.buildSessionFactory();
			System.out.println("[标记]初始化SessionFactory");
		} catch (Exception e) {
			System.out.println("[异常]创建SessionFactory时发生异常,异常原因如下:");
			e.printStackTrace();
		}
	}

	/**
	 * getSession()方法
	 * 
	 * @return Session对象
	 * @throws HibernateException
	 */
	public Session getSession() {
		Session session = null;
		try {
			session = sessionFactory.openSession();
		} catch (Exception e) {
			System.out.println("[异常]开启Session时发生异常,异常原因如下:");
			e.printStackTrace();
		}
		return session;


	}

	/**
	 * closeSession()方法
	 * 
	 * @param session
	 *            要关闭的Session对象
	 */
	public void closeSession(Session session) {
		try {
			if (null != session)
				session.close();
		} catch (Exception e) {
			System.out.println("[异常]关闭Session时发生异常,异常原因如下:");
			e.printStackTrace();
		}
	}

}

     6、DAO层设计:在"com.dianzi.dao" 包下建立两个类,一个是接口,一个是实现类。

    其中,UserDao接口如下:

package com.dianzi.dao;


import com.dianzi.model.User;

/**
 * 
 * @author frand
 * @date 2013-05-10
 * @version 1.0
 */
public interface UserDao {

	/**

	 * 增加用户
	 * 
	 * @param user增加用户。0:异常; >0:成功(即返回该记录ID)
	 */
	public int add(User user);

	/**
	 * 系统登录验证
	 * 
	 * @param user
	 * @return -1:不存在用户名 ; -2:密码不正确 ;0:异常; >0:登录成功(即返回该记录ID)
	 */
	public int login(User user);

}

    UserDaoImpl.java代码如下:

/**
 * 
 */
package com.dianzi.dao;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.dianzi.model.User;
import com.dianzi.util.HibernateUtil;

/**
 * 
 * @author frand
 * @date 2013-05-10
 * @version 1.0
 */
public class UserDaoImpl implements UserDao {
	HibernateUtil util = new HibernateUtil();

	public int add(User user) {
		int result = 0;
		Session session = util.getSession();
		Transaction ts = null;
		try {
			ts = session.beginTransaction();
			session.save(user);
			ts.commit();
			result = user.getId();
		} catch (Exception e) {
			System.out.println("UserDaoImpl.add()方法发生异常:");
			e.printStackTrace();
			result = -1;
		} finally {
			util.closeSession(session);
		}
		return result;
	}

	public int login(User user) {
		// int state = 0 ; //初始化状态变量
		Session session = util.getSession();
		try {
			Query queryName = session
					.createQuery("from User u where u.name = ?");
			queryName.setString(0, user.getName());
			List listName = queryName.list();
			if (null == listName ||listName.isEmpty()) {
				return -1; // 用户名不存在
			}
			Query queryNamePswd = session
					.createQuery("from User u where u.name = ? and u.password = ?");
			queryNamePswd.setString(0, user.getName());
			queryNamePswd.setString(1, user.getPassword());
			List listNamePswd = queryNamePswd.list();
			if (null == listNamePswd ||listNamePswd.isEmpty()) {
				return -2; // 密码不正确
			}
			Iterator it = listNamePswd.iterator();
			User userquery = (User) it.next();
			return userquery.getId(); // 验证成功,取ID值
		} catch (Exception e) {
			System.out.println("UserDaoImpl.isExist()方法发生异常:");
			e.printStackTrace();
			return 0; // 异常时返回0
		} finally {
			util.closeSession(session);
		}
	}

}

     7,在web.xml中修改Struts 2.0配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>login</display-name>

	<!-- 用过滤器配置Struts2支持 -->
	<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>

	<welcome-file-list>
		<welcome-file>jsp/login/login.jsp</welcome-file>
	</welcome-file-list>
</web-app>

     8,创建登录页面login.jsp/注册页面register.jsp/登陆成功页面success.jsp并且将其都放在WebContent/jsp/login下。

    login.jsp页面代码如下:

<%@ page language="java" contentType="text/html; charset=gbk"
	pageEncoding="gbk"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<title>登录</title>
</head>
<body>
<p><a href="preRegisterAction.action">用户注册</a>|用户登录</p>
<s:form action="loginAction" theme="simple">
	<table>
		<tr>
			<td style="text-align: right">账号</td>
			<td><s:textfield name="username" label="账号" /></td>
		</tr>
		<tr>
			<td style="text-align: right">密码</td>
			<td><s:password name="password" label="密码" /></td>
		</tr>
		<tr>
			<td style="text-align: right">验证码</td>
			<td><s:textfield name="inputCertCode" label="验证码"
				cssStyle="width:100px" /> <img src="jsp/util/makeCertPic.jsp"
				height="30"></td>
		</tr>
		<tr>
			<td style="text-align: right"><s:submit value="登录" /></td>
			<td style="text-align: left"><s:reset value="重置" /></td>
		</tr>
		<s:if test="#{printResult}!=null">
			<tr>
				<td align="center" colspan="2">${printResult }</td>
			</tr>
		</s:if>
		<s:if test="#{result}!=null">
			<tr>
				<td align="center" colspan="2">${result }</td>
			</tr>
		</s:if>

	</table>
</s:form>
<s:fielderror cssStyle="color:red" />
</body>
</html>

     注册页register.jsp代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>注册</title>
</head>

<body>
<p><a href="preLoginAction.action">用户登录</a>|用户注册</p>
<s:form action="registerAction" theme="simple">
	<table>
		<tr>
			<td style="text-align: right">请输入账号</td>
			<td><s:textfield name="user.name" label="账号" /></td>
		</tr>
		<tr>
			<td style="text-align: right">请输入密码</td>
			<td><s:password name="user.password" label="密码" /></td>
		</tr>
		<tr>
			<td style="text-align: right">请再次输入密码</td>
			<td><s:password name="repwd" label="重复密码" /></td>
		</tr>
		<tr>
			<td style="text-align: right">请输入验证码</td>
			<td><s:textfield name="inputCertCode" label="验证码"
				cssStyle="width:100px" /> <img src="jsp/util/makeCertPic.jsp"
				height="30"></td>
		</tr>
		<tr>
			<td style="text-align: right"><s:submit value="注册" /></td>
			<td style="text-align: left"><s:reset value="取消" /></td>
		</tr>
	</table>
</s:form>
<s:fielderror cssStyle="color:red" />
</body>
</html>

     登录成功页面success.jsp代码如下:

<%@ page language="java" contentType="text/html; charset=GBK"
	pageEncoding="GBK"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>登录成功</title>
</head>
<body>
<table align="center">
	<tr>
		<td>登录成功!</td>
	</tr>
	<tr>
		<td>用户名:(EL表达式)</td>
		<td>${username}</td>
	</tr>
	<tr>
		<td>用户名:(s:property表达式)</td>
		<td><s:property value="username" ></s:property></td>
	</tr>
	<tr>
		<td><a href="logoutAction.action">退出</a>
		</td>
	</tr>
	
</table>
</body>
</html>

    9,在JSP页中所用到的验证码的生成页面makeCertPic.jsp,放在WebContent/jsp/util下:

<%@page contentType="image/jpeg" pageEncoding="gbk"%>
<jsp:useBean id="image" scope="page"
	class="com.dianzi.jspused.validate.MakeCertPic" />
<%
	String str = image.getCertPic(0, 0, response.getOutputStream());
	// 将验证码保存到Session中

	try {
		session.setAttribute("certCode", str);

		////////以下两行必加,详见http://guoyiqi.iteye.com/blog/75929///////////////
		out.clear();
		out = pageContext.pushBody();
	} catch (Exception e) {
		System.out.println("服务器错误");
	}
%>

     其中,它调用了名为makeCertPic的Bean ,这个类主要用来生成彩色的验证图片,其代码如下:

/**
 * 
 */
package com.dianzi.jspused.validate;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;

/**
 * 生成验证码图片
 * 
 * @author 点子二木
 * @date 2009-1-8
 * @version 1.0
 */
public class MakeCertPic {
	// 验证码图片中可以出现的字符集,可根据需要修改
	// private char mapTable[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
	// 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
	// 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
	// '9' };

	private char mapTable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
			'9' };

	/**
	 * 生成彩色验证码图片
	 * 
	 * @param width生成的图片的宽度
	 * @param height生成的图片的高度
	 * @param os页面的输出流
	 * @return 返回生成的校验码
	 */
	public String getCertPic(int width, int height, OutputStream os) {
		if (width <= 0)
			width = 60;
		if (height <= 0)
			height = 20;
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		// 获取图形上下文
		Graphics g = image.getGraphics();
		// 设定背景色
		g.setColor(new Color(0xDCDCDC));
		g.fillRect(0, 0, width, height);
		// 画边框
		g.setColor(Color.black);
		g.drawRect(0, 0, width - 1, height - 1);
		// 取随机产生的认证码
		String strEnsure = "";
		// 4代表4位验证码,如果要生成更多位的认证码,则加大数值
		for (int i = 0; i < 4; ++i) {
			strEnsure += mapTable[(int) (mapTable.length * Math.random())];
		}
		// 将认证码显示到图象中,如果要生成更多位的认证码,增加drawString语句
		g.setColor(Color.black);
		g.setFont(new Font("Atlantic Inline", Font.PLAIN, 18));
		String str = strEnsure.substring(0, 1);
		g.drawString(str, 8, 17);
		str = strEnsure.substring(1, 2);
		g.drawString(str, 20, 15);
		str = strEnsure.substring(2, 3);
		g.drawString(str, 35, 18);
		str = strEnsure.substring(3, 4);
		g.drawString(str, 45, 15);
		// 随机产生10个干扰点
		Random rand = new Random();
		for (int i = 0; i < 10; i++) {
			int x = rand.nextInt(width);
			int y = rand.nextInt(height);
			g.drawOval(x, y, 1, 1);
		}
		// 释放图形上下文
		g.dispose();
		try {
			// 输出图象到页面
			ImageIO.write(image, "JPEG", os);
		} catch (IOException e) {
			return "";
		}finally{
			
		}
		return strEnsure;
	}
}

     10,此时,我们很有必要来配置一下struts-login.xml其全部代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configeration 2.0//EN" 
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
	<package name="login" extends="struts-default">
		<!-- 定向至用户登录 -->
		<action name="preLoginAction"
			class="com.dianzi.action.login.LoginAction" method="preLogin">
			<result name="success">/jsp/login/login.jsp</result>
			<result name="input">/jsp/login/login.jsp</result>
			<result name="error">/jsp/error.jsp</result>
		</action>
		<!-- 用户登录 -->
		<action name="loginAction"
			class="com.dianzi.action.login.LoginAction" method="login">
			<result name="success">/jsp/login/success.jsp</result>
			<result name="input">/jsp/login/login.jsp</result>
			<result name="error">/jsp/error.jsp</result>
		</action>
		<!-- 定向至用户注册 -->
		<action name="preRegisterAction"
			class="com.dianzi.action.login.RegisterAction"
			method="preRegister">
			<result name="success">/jsp/login/register.jsp</result>
			<result name="input">/jsp/login/register.jsp</result>
			<result name="error">/jsp/error.jsp</result>
		</action>
		<!-- 用户注册 -->
		<action name="registerAction"
			class="com.dianzi.action.login.RegisterAction" method="register">
			<result name="success">/jsp/login/login.jsp</result>
			<result name="input">/jsp/login/register.jsp</result>
			<result name="error">/jsp/error.jsp</result>
		</action>
		<!-- 用户登出 -->
		<action name="logoutAction"
			class="com.dianzi.action.login.LoginAction" method="logout">
			<result name="success" type="redirect">preLoginAction.action</result>
			<result name="error">/jsp/error.jsp</result>
		</action>
	</package>
</struts>

     11、Action层设计:两个非常关键的类,其中LoginAction.java的代码如下:

/**
 * 
 */
package com.dianzi.action.login;

import java.util.Map;

import com.dianzi.dao.UserDao;
import com.dianzi.dao.UserDaoImpl;
import com.dianzi.model.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 登录
 * @author frand
 * @date 2013-05-10
 * @version 1.0
 */
public class LoginAction extends ActionSupport {
	private UserDao userDao = new UserDaoImpl(); // 操纵数据库DAO类(Hibernate实现),通过Struts.xml注入值
	private int id;

	private String inputCertCode; // 验证码
	private String username;// 用户名(值由struts注入)
	private String password;// 密码(值由struts注入)
	private String printResult;// 结果打印

	/**
	 * 定向至登录
	 * 
	 * @return
	 */
	public String preLogin() {
		try {
			return SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ERROR;
		}
	}
	
	/**
	 * 登录
	 * 
	 * @return
	 */
	public String login() {
		User user = new User(username, password);
		int state = userDao.login(user);
		System.out.println("state=" + state);
		if (state == -1) {
			this.addFieldError("username", "用户名不正确,请先注册!");
			return INPUT;
		} else if (state == -2) {
			this.addFieldError("password", "密码不正确,请重新输入密码!");
			return INPUT;
		} else if (state > 0) {
			System.out.println("[测试]登录成功!用户ID=" + state);
			this.setId(state);
			return SUCCESS;
		} else {
			this.addFieldError("username", "登录失败,请与管理员联系!");
			return INPUT;
		}
	}

	/**
	 * 登出
	 * 
	 * @return
	 */
	public String logout() {
		try {
			return SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ERROR;
		}
	}

	
	/**
	 * 验证码验证login()
	 */
	public void validateLogin() {
		if (null == inputCertCode || "".equals(inputCertCode)) {
			this.addFieldError("inputCertCode", "验证码不能为空!");
		} else {
			Map session = ActionContext.getContext().getSession();
			String certCode = session.get("certCode").toString();
			if (!certCode.equals(this.inputCertCode)) {
				this.addFieldError("inputCertCode", "验证码不正确!");
			}
		}
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getInputCertCode() {
		return inputCertCode;
	}

	public void setInputCertCode(String inputCertCode) {
		this.inputCertCode = inputCertCode;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getPrintResult() {
		return printResult;
	}

	public void setPrintResult(String printResult) {
		this.printResult = printResult;
	}

}

     RegisterAction.java的代码如下:

/**
 * 
 */
package com.dianzi.action.login;

import java.util.Map;

import com.dianzi.dao.UserDao;
import com.dianzi.dao.UserDaoImpl;
import com.dianzi.model.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 注册
 * @author 点子二木
 * @date 2009-1-8
 * @version 1.0
 */
public class RegisterAction extends ActionSupport {
	private UserDao userDao = new UserDaoImpl();
	private User user; // 注册提交的用户对象
	private String repwd; // 重复密码
	private String inputCertCode; // 验证码
	private String printResult; // 结果打印

	/**
	 * 定向至注册
	 * 
	 * @return
	 */
	public String preRegister() {
		try {
			return SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ERROR;
		}
	}
	
	/**
	 * 注册
	 * @return
	 * @throws Exception
	 */
	public String register() throws Exception {
		
		int newId = userDao.add(user); // 保存注册的user对象
		if(newId>0){
			printResult = "注册成功,请登录!";
			return SUCCESS;
		}else{
			return ERROR;
		}
		
	}

	
	/**
	 * 验证码验证register()
	 */

	public void validateRegister() {
		if (null == inputCertCode || "".equals(inputCertCode)) {
			this.addFieldError("inputCertCode", "验证码不能为空!");
		} else {
			Map session = ActionContext.getContext().getSession();
			String certCode = session.get("certCode").toString();
			if (!certCode.equals(this.inputCertCode)) {
				this.addFieldError("inputCertCode", "验证码不正确!");
			}
		}

	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String getRepwd() {
		return repwd;
	}

	public void setRepwd(String repwd) {
		this.repwd = repwd;
	}

	public String getInputCertCode() {
		return inputCertCode;
	}

	public void setInputCertCode(String inputCertCode) {
		this.inputCertCode = inputCertCode;
	}

	public String getPrintResult() {
		return printResult;
	}

	public void setPrintResult(String printResult) {
		this.printResult = printResult;
	}

}

     12,不要忘记配置校验框架,与上面两个Action同一个目录下。

    注意命名规范:

    (1).Action名-validation.xml,此规范表示对该Action所有方法进行验证。

    (2).Action名-Struts配置文件中的Action标签的name属性-validation.xml,此规范表示对某一Action特定的方法进行验证。

LoginAction-loginAction-validation.xml代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
	<!-- 用户名验证 -->
	<field name="username">
		<field-validator type="requiredstring">
			<param name="trim">true</param>
			<message>用户名不能为空!</message>
		</field-validator>
		<field-validator type="regex">
			<param name="expression"><![CDATA[(\w{4,8})]]></param>
			<message>账号必须是长度为4-8的数字或字母!</message>
		</field-validator>
	</field>
	<!-- 密码验证 -->
	<field name="password">
		<field-validator type="requiredstring">
			<param name="trim">true</param>
			<message>密码不能为空!</message>
		</field-validator>
		<field-validator type="regex">
			<param name="expression"><![CDATA[(\w{4,8})]]></param>
			<message>密码必须长度为4-8的数字或字母!</message>
		</field-validator>
	</field>
</validators>

 RegisterAction-registerAction-validation.xml代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
	<!-- 用户名验证 -->
	<field name="user.name" >
		<field-validator type="requiredstring">
			<param name="trim">true</param>
			<message>用户名不能为空!</message>
		</field-validator>
		<field-validator type="regex">
			<param name="expression"><![CDATA[(\w{4,8})]]></param>
			<message>账号必须是长度为4-8的数字或字母!</message>
		</field-validator>
	</field>
	<!-- 密码验证 -->
	<field name="user.password">
		<field-validator type="requiredstring">
			<param name="trim">true</param>
			<message>密码不能为空!</message>
		</field-validator>
		<field-validator type="regex">
			<param name="expression"><![CDATA[(\w{4,8})]]></param>
			<message>密码必须长度为4-8的数字或字母!</message>
		</field-validator>
	</field>
	<field name="repwd">
		<field-validator type="requiredstring" short-circuit="true">
			<param name="trim">true</param>
			<message>重复密码不能为空!</message>
		</field-validator>
		<field-validator type="fieldexpression">
			<param name="expression"><![CDATA[(repwd==user.password)]]></param>
			<message>两次输入的密码要一致!</message>
		</field-validator>
	</field>
</validators>

     13,如果没有生成数据库,可以用如下sql代码:

DROP DATABASE IF EXISTS `struts2`;
CREATE DATABASE `struts2` /*!40100 DEFAULT CHARACTER SET gbk */;
USE `struts2`;

#
# Table structure for table t_user_test
#

CREATE TABLE `t_user_test` (
  `Id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL default '',
  `password` varchar(255) NOT NULL default '',
  `roleId` int(11) NOT NULL default '0',
  PRIMARY KEY  (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;

 声称数据库后可看到:

mysql> show create table t_user_test;
+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table       | Create Table                                                                                                                                                                                                                                                     |
+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_user_test | CREATE TABLE `t_user_test` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '',
  `password` varchar(255) NOT NULL DEFAULT '',
  `roleId` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk |
+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

    整个工程结构:

     1,src文件:

            struts架构搭建(二)

    lib文件夹:

            struts架构搭建(二)

    webcontent文件夹:

            struts架构搭建(二) 

由此便可运行工程。