开发工具:MyEclipse6.0 ,Tomcat 5.5 ,JDK 1.5 ,MySQL 5.0 ;开发准备:下载Struts2.0和Hibernate 3.2,大家可Struts和Hibernate的官方网站下载这两个框架。我们先来总览一下开发完成后的包—类图:
首先NEW一个Web Project ,名为"LoginSystem",在 lib 目录下加入Struts 2.0的Jar包和Hibernate 3.2的Jar包,然后按下面的步骤来:
1、在 src 目录下建 "hibernate.cfg.xml" 全部代码如下:
1 <?xml version='1.0' encoding='UTF-8'?>
2 <!DOCTYPE hibernate-configuration PUBLIC
3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
5
6 <!-- Generated by MyEclipse Hibernate Tools. -->
7 <hibernate-configuration>
8 <session-factory>
9 <property name="connection.username">root</property>
10 <property name="connection.url">
11 jdbc:mysql://localhost:3306/LoginSystem
12 </property>
13 <property name="dialect">
14 org.hibernate.dialect.MySQLDialect
15 </property>
16 <property name="myeclipse.connection.profile">
17 LoginSystem
18 </property>
19 <property name="connection.password">root</property>
20 <property name="connection.driver_class">
21 com.mysql.jdbc.Driver
22 </property>
23 <property name="show_sql">true</property>
24 <!-- POJO类映射配置 -->
25 <mapping resource="com/rong/ORM/User.hbm.xml" />
26 </session-factory>
27 </hibernate-configuration>
2、建立实体类 "User.java" 及其映射文件 "User.hbm.xml" 两者都放在"com.rong.ORM" 包下。其中"User.java"的代码如下:
1 package com.rong.ORM;
2
3 public class User {
4
5 private int id; //主键ID
6 private String name; //用户名
7 private String pwd; //密码
8
9 /*
10 * Getter方法与Setter方法
11 */
12 public String getName() {
13 return name;
14 }
15 public void setName(String name) {
16 this.name = name;
17 }
18 public String getPwd() {
19 return pwd;
20 }
21 public void setPwd(String pwd) {
22 this.pwd = pwd;
23 }
24 public int getId() {
25 return id;
26 }
27 public void setId(int id) {
28 this.id = id;
29 }
30 }
User.hbm.xml的代码如下:
1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4
5 <hibernate-mapping>
6 <class name="com.rong.ORM.User" table="tb_user">
7 <id name="id">
8 <generator class="native"/>
9 </id>
10 <property name="name" type="java.lang.String" length="20"/>
11 <property name="pwd" type="java.lang.String" length="20"/>
12 </class>
13 </hibernate-mapping>
3、建立"ExportDB.java"工具类,我们执行如下代码,就能轻松将User类导入数据库转变成数据库中的表。不过,前提是我们已经在MySQL中建立了一个名为"LoginSystem"的数据库。
1 package tool;
2
3 import org.hibernate.cfg.Configuration;
4 import org.hibernate.tool.hbm2ddl.SchemaExport;
5
6 public class ExportDB {
7
8 /*
9 * 运行此类,通过POJO类和配置文件,生成数据库的表
10 */
11 public static void main(String[] args){
12 Configuration cfg = new Configuration().configure();
13 SchemaExport export = new SchemaExport(cfg);
14 export.create(true, true);
15 }
16 }
17
4、建立获取SessionFactory和管理Session的HibernateUtil.java类:
1 package com.rong.hibernate;
2
3 import org.hibernate.HibernateException;
4 import org.hibernate.Session;
5 import org.hibernate.SessionFactory;
6 import org.hibernate.cfg.Configuration;
7
8 public class HibernateUtil {
9
10 //声明Hibernate配置文件所在的路径
11 private static String configFile = "/hibernate.cfg.xml";
12 //建Configuration对象
13 private static Configuration configuration = new Configuration();
14 //建Session工厂对象
15 private static SessionFactory sessionFactory = null;
16
17 /**
18 * 单例模式,只初始化一次,只产生一个SessionFactory对象(线程安全)
19 */
20 static {
21 try{
22 //通过hibernate.cfg.xml配置数据库连接
23 configuration.configure(configFile);
24 //建立一个Session工厂
25 sessionFactory = configuration.buildSessionFactory();
26 System.out.println("[标记]初始化SessionFactory");
27 }catch(Exception e){
28 System.out.println("[异常]创建SessionFactory时发生异常,异常原因如下:");
29 e.printStackTrace();
30 }
31 }
32
33 /**
34 * getSession()方法
35 * @return Session对象
36 * @throws HibernateException
37 */
38 public Session getSession(){
39 Session session = null;
40 try{
41 session = sessionFactory.openSession();
42 }catch(Exception e){
43 System.out.println("[异常]开启Session时发生异常,异常原因如下:");
44 e.printStackTrace();
45 }
46 return session;
47 }
48
49 /**
50 * closeSession()方法
51 * @param session 要关闭的Session对象
52 */
53 public void closeSession(Session session){
54 try{
55 if(null != session)
56 session.close();
57 }catch(Exception e){
58 System.out.println("[异常]关闭Session时发生异常,异常原因如下:");
59 e.printStackTrace();
60 }
61 }
62
63
64
66 }
67
5、DAO层设计:在"com.rong.DAO"包下建立两个类,一个是接口,一个是实现类,其中UserDao.java代码如下:
1 package com.rong.DAO;
2
3 import java.util.List;
4 import com.rong.ORM.User;
5
6 public interface UserDao {
7
8 /**
9 * 增加用户
10 * @param user 要增加的用户
11 */
12 public void add(User user);
13
14 /**
15 * 登录验证
16 * @param name
17 * @param password
18 * @return -1:不存在用户名 ; -2:密码不正确 ; >0:登录成功(即返回该记录ID)
19 */
20 public int isExist(String name,String password);
21 }
UserDaoImpl.java的代码如下:
1 package com.rong.DAO;
2
3 import java.util.Iterator;
4 import java.util.List;
5 import org.hibernate.Query;
6 import org.hibernate.Session;
7 import org.hibernate.Transaction;
8 import com.rong.ORM.User;
9 import com.rong.hibernate.HibernateUtil;
10
11 public class UserDaoImpl implements UserDao {
12
13 HibernateUtil util = new HibernateUtil();
14
15 /**
16 * 增加用户
17 * @param user 要增加的用户
18 */
19 public void add(User user){
20 Session session = util.getSession();
21 Transaction ts = null;
22 try{
23 ts = session.beginTransaction();
24 session.save(user);
25 ts.commit();
26 }catch(Exception e){
27 System.out.println("UserDaoImpl.add()方法发生异常:");
28 e.printStackTrace();
29 }finally{
30 util.closeSession(session);
31 }
32 }
33
34 /**
35 * 登录验证
36 * @param name
37 * @param password
38 * @return -1:不存在用户名 ; -2:密码不正确 ; >0:登录成功(即返回该记录ID)
39 */
40 public int isExist(String name,String password){
41 //int state = 0 ; //初始化状态变量
42 Session session = util.getSession();
43 try{
44 Query query = session.createQuery("from User u where u.name = ?");
45 query.setString(0, name);
46 List list = query.list();
47 if(null == list || 0 == list.size()){
48 return -1 ; //用户名不存在
49 }
50 Query query2 = session.createQuery("from User u where u.name = ? and u.pwd = ?");
51 query2.setString(0, name);
52 query2.setString(1, password);
53 List list2 = query.list();
54 if(null == list2){
55 return -2 ; //密码不正确
56 }
57 Iterator it = list.iterator();
58 User user = (User)it.next();
59 return user.getId(); //验证成功,取ID值
60
61 }catch(Exception e){
62 System.out.println("UserDaoImpl.isExist()方法发生异常:");
63 e.printStackTrace();
64 return 0; //异常时返回0
65 }finally{
66 util.closeSession(session);
67 }
68 }
69 }
70
6、在web.xml中配置Struts2.0支持:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
6
7 <!-- 用过滤器配置Struts2支持 -->
8 <filter>
9 <filter-name>struts2</filter-name>
10 <filter-class>
11 org.apache.struts2.dispatcher.FilterDispatcher
12 </filter-class>
13 </filter>
14 <filter-mapping>
15 <filter-name>struts2</filter-name>
16 <url-pattern>/*</url-pattern>
17 </filter-mapping>
18
19 <welcome-file-list>
20 <welcome-file>login.jsp</welcome-file>
21 </welcome-file-list>
22 </web-app>
7、登录页面login.jsp代码如下:
1 <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
2 <%@ taglib prefix="s" uri="/struts-tags" %>
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <html>
5 <head>
6
7 <title>Login Page</title>
8 </head>
9
10 <body>
11 <p><a href="register.jsp">用户注册</a>|用户登录</p>
12 <s:form action="loginAction" theme="simple">
13 <table>
14 <tr>
15 <td style="text-align:right">
16 账号
17 </td>
18 <td>
19 <s:textfield name="name" label="账号" />
20
21 </td>
22 </tr>
23 <tr>
24 <td style="text-align:right">
25 密码
26 </td>
27 <td>
28 <s:password name="pwd" label="密码" />
29 </td>
30 </tr>
31 <tr>
32 <td style="text-align:right">
33 验证码
34 </td>
35 <td>
36 <s:textfield name="inputCertCode" label="验证码" cssStyle="width:100px"/>
37 <img src="other/makeCertPic.jsp">
38 </td>
39 </tr>
40 <tr>
41 <td style="text-align:right">
42 <s:submit value="登录" />
43 </td>
44 <td style="text-align:left">
45 <s:reset value="取消"/>
46 </td>
47 </tr>
48 </table>
49 </s:form>
50 <s:fielderror cssStyle="color:red"/>
51 </body>
52 </html>
53
注册页register.jsp代码如下:
1 <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
2 <%@ taglib prefix="s" uri="/struts-tags"%>
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <html>
5 <head>
6
7 <title>Register Page</title>
8 </head>
9
10 <body>
11 <p><a href="login.jsp">用户登录</a>|用户注册</p>
12 <s:form action="registerAction" theme="simple">
13 <table>
14 <tr>
15 <td style="text-align:right">
16 请输入账号
17 </td>
18 <td>
19 <s:textfield name="user.name" label="账号" />
20
21 </td>
22 </tr>
23 <tr>
24 <td style="text-align:right">
25 请输入密码
26 </td>
27 <td>
28 <s:password name="user.pwd" label="密码" />
29 </td>
30 </tr>
31 <tr>
32 <td style="text-align:right">
33 请再次输入密码
34 </td>
35 <td>
36 <s:password name="repwd" label="重复密码" />
37 </td>
38 </tr>
39 <tr>
40 <td style="text-align:right">
41 请输入验证码
42 </td>
43 <td>
44 <s:textfield name="inputCertCode" label="验证码" cssStyle="width:100px"/>
45 <img src="other/makeCertPic.jsp">
46 </td>
47 </tr>
48 <tr>
49 <td style="text-align:right">
50 <s:submit value="注册" />
51 </td>
52 <td style="text-align:left">
53 <s:reset value="取消"/>
54 </td>
55 </tr>
56 </table>
57 </s:form>
58 <s:fielderror cssStyle="color:red"/>
59 </body>
60 </html>
61
8、在JSP页中所用到的验证码的生成页面makeCertPic.jsp(我们把它放在WebRoot的other目录下):
1 <%@page contentType="image/jpeg" pageEncoding="gbk"%>
2 <jsp:useBean id="image" scope="page" class="com.rong.other.makeCertPic" />
3 <%
4 String str = image.getCertPic(0,0,response.getOutputStream());
5 // 将验证码保存到Session中
6 session.setAttribute("certCode", str);
7 %>
其中,它调用了名为makeCertPic的Bean ,这个类主要用来生成彩色的验证图片,其代码如下:
1 package com.rong.other;
2 import java.awt.Color;
3 import java.awt.Font;
4 import java.awt.Graphics;
5 import java.awt.image.BufferedImage;
6 import java.io.IOException;
7 import java.io.OutputStream;
8 import java.util.Random;
9 import javax.imageio.ImageIO;
10 /**
11 * 生成验证码图片
12 */
13 public class makeCertPic {
14 //验证码图片中可以出现的字符集,可根据需要修改
15 private char mapTable[]={
16 'a','b','c','d','e','f',
17 'g','h','i','j','k','l',
18 'm','n','o','p','q','r',
19 's','t','u','v','w','x',
20 'y','z','0','1','2','3',
21 '4','5','6','7','8','9'};
22 /**
23 * 功能:生成彩色验证码图片
24 * 参数width为生成的图片的宽度,参数height为生成的图片的高度,参数os为页面的输出流
25 */
26 public String getCertPic(int width, int height, OutputStream os) {
27 if(width<=0)width=60;
28 if(height<=0)height=20;
29 BufferedImage image = new BufferedImage(width, height,
30 BufferedImage.TYPE_INT_RGB);
31 // 获取图形上下文
32 Graphics g = image.getGraphics();
33 // 设定背景色
34 g.setColor(new Color(0xDCDCDC));
35 g.fillRect(0, 0, width, height);
36 //画边框
37 g.setColor(Color.black);
38 g.drawRect(0,0,width-1,height-1);
39 // 取随机产生的认证码
40 String strEnsure = "";
41 // 4代表4位验证码,如果要生成更多位的认证码,则加大数值
42 for(int i=0; i<4; ++i) {
43 strEnsure += mapTable[(int)(mapTable.length*Math.random())];
44 }
45 // 将认证码显示到图象中,如果要生成更多位的认证码,增加drawString语句
46 g.setColor(Color.black);
47 g.setFont(new Font("Atlantic Inline",Font.PLAIN,18));
48 String str = strEnsure.substring(0,1);
49 g.drawString(str,8,17);
50 str = strEnsure.substring(1,2);
51 g.drawString(str,20,15);
52 str = strEnsure.substring(2,3);
53 g.drawString(str,35,18);
54 str = strEnsure.substring(3,4);
55 g.drawString(str,45,15);
56 // 随机产生10个干扰点
57 Random rand = new Random();
58 for (int i=0;i<10;i++) {
59 int x = rand.nextInt(width);
60 int y = rand.nextInt(height);
61 g.drawOval(x,y,1,1);
62 }
63 // 释放图形上下文
64 g.dispose();
65 try {
66 // 输出图象到页面
67 ImageIO.write(image, "JPEG", os);
68 } catch (IOException e) {
69 return "";
70 }
71 return strEnsure;
72 }
73 }
74
9、此时,我们很有必要来配置一下struts.xml其全部代码如下:
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE struts PUBLIC
3 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
4 "http://struts.apache.org/dtds/struts-2.0.dtd">
5
6 <struts>
7
8 <package name="com.rong.action" extends="struts-default">
9 <!-- 用户登录 -->
10 <action name="loginAction" class="com.rong.action.LoginAction">
11 <result name="success" type="redirect">/back/index.jsp</result>
12 <result name="input">/login.jsp</result>
13 </action>
14 <!-- 用户注册 -->
15 <action name="registerAction" class="com.rong.action.RegisterAction">
16 <result name="success" type="redirect">/login.jsp</result>
17 <result name="input">/register.jsp</result>
18 </action>
19 </package>
20 </struts>
10、Action层设计:两个非常关键的类,其中LoginAction.java的代码如下:
1 package com.rong.action;
2
3 import java.util.Map;
4 import com.opensymphony.xwork2.ActionContext;
5 import com.opensymphony.xwork2.ActionSupport;
6 import com.rong.DAO.UserDao;
7 import com.rong.DAO.UserDaoImpl;
8 import com.rong.ORM.User;
9
10 public class LoginAction extends ActionSupport {
11
12
13 private UserDao userDao = new UserDaoImpl(); //操纵数据库DAO类(Hibernate实现),通过Struts.xml注入值
14
15 private int id;
16 private String name; //用户名(值由struts注入)
17 private String pwd; //密码(值由struts注入)
18
19 private String inputCertCode; //验证码
20
21 public int getId() {
22 return id;
23 }
24 public void setId(int id) {
25 this.id = id;
26 }
27 public String getName() {
28 return name;
29 }
30 public void setName(String name) {
31 this.name = name;
32 }
33 public String getPwd() {
34 return pwd;
35 }
36 public void setPwd(String pwd) {
37 this.pwd = pwd;
38 }
39
40 public String getInputCertCode() {
41 return inputCertCode;
42 }
43 public void setInputCertCode(String inputCertCode) {
44 this.inputCertCode = inputCertCode;
45 }
46 @Override
47 public String execute() throws Exception {
48 int state = userDao.isExist(name,pwd);
49 System.out.println("state="+state);
50 if(state == -1){
51 this.addFieldError("name", "用户名不正确,请先注册!");
52 return INPUT;
53 }else if(state == -2){
54 this.addFieldError("pwd", "密码不正确,请重新输入密码!");
55 return INPUT;
56 }else if(state > 0){
57 System.out.println("[测试]登录成功!用户ID="+state);
58 this.setId(state);
59 return SUCCESS;
60 }else{
61 this.addFieldError("name", "登录失败,请与管理员联系!");
62 return INPUT;
63 }
64 }
65
66 public void validate() {
67 //验证码验证
68 if(null == inputCertCode || "".equals(inputCertCode)){
69 this.addFieldError("inputCertCode", "验证码不能为空!");
70 }else{
71 Map session = ActionContext.getContext().getSession();
72 String certCode = session.get("certCode").toString();
73 if( ! certCode.equals(this.inputCertCode)){
74 this.addFieldError("inputCertCode", "验证码不正确!");
75 }
76 }
77
78 }
79
80
81
82
83 }
84
RegisterAction.java的代码如下:
1 package com.rong.action;
2
3 import java.util.Map;
4
5 import com.opensymphony.xwork2.ActionContext;
6 import com.opensymphony.xwork2.ActionSupport;
7 import com.rong.DAO.UserDao;
8 import com.rong.DAO.UserDaoImpl;
9 import com.rong.ORM.User;
10
11 public class RegisterAction extends ActionSupport {
12
13 private UserDao userDao = new UserDaoImpl();
14
15 private User user; //注册提交的用户对象
16
17 private String repwd; //重复密码
18
19 private String inputCertCode; //验证码
20
21 public User getUser() {
22 return user;
23 }
24
25 public void setUser(User user) {
26 this.user = user;
27 }
28
29 public String getRepwd() {
30 return repwd;
31 }
32
33 public void setRepwd(String repwd) {
34 this.repwd = repwd;
35 }
36
37 public String getInputCertCode() {
38 return inputCertCode;
39 }
40
41 public void setInputCertCode(String inputCertCode) {
42 this.inputCertCode = inputCertCode;
43 }
44
45 @Override
46 public String execute() throws Exception {
47 User user = new User();
48 userDao.add(user); //保存注册的user对象
49 return SUCCESS;
50 }
51
52 @Override
53 public void validate() {
54 //验证码验证
55 if(null == inputCertCode || "".equals(inputCertCode)){
56 this.addFieldError("inputCertCode", "验证码不能为空!");
57 }else{
58 Map session = ActionContext.getContext().getSession();
59 String certCode = session.get("certCode").toString();
60 if( ! certCode.equals(this.inputCertCode)){
61 this.addFieldError("inputCertCode", "验证码不正确!");
62 }
63 }
64
65 }
66
67 }
68
11、不要忘记配置校验框架,与上面两个Action同一个目录下。LoginAction-validation.xml代码如下:
1 <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
2 "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
3
4 <validators>
5 <!-- 用户名验证 -->
6 <field name="name">
7 <field-validator type="requiredstring">
8 <param name="trim">true</param>
9 <message>用户名不能为空!</message>
10 </field-validator>
11 <field-validator type="regex">
12 <param name="expression"><![CDATA[(\w{4,8})]]></param>
13 <message>账号必须是长度为4-8的数字或字母!</message>
14 </field-validator>
15 </field>
16 <!-- 密码验证 -->
17 <field name="pwd">
18 <field-validator type="requiredstring">
19 <param name="trim">true</param>
20 <message>密码不能为空!</message>
21 </field-validator>
22 <field-validator type="regex">
23 <param name="expression"><![CDATA[(\w{4,8})]]></param>
24 <message>密码必须长度为4-8的数字或字母!</message>
25 </field-validator>
26 </field>
27
28 </validators>
RegisterAction-validation.xml代码如下:
1 <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
2 "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
3
4 <validators>
5
6 <!-- 用户名验证 -->
7 <field name="user.name">
8 <field-validator type="requiredstring">
9 <param name="trim">true</param>
10 <message>用户名不能为空!</message>
11 </field-validator>
12 <field-validator type="regex">
13 <param name="expression"><![CDATA[(\w{4,8})]]></param>
14 <message>账号必须是长度为4-8的数字或字母!</message>
15 </field-validator>
16 </field>
17
18 <!-- 密码验证 -->
19 <field name="user.pwd">
20 <field-validator type="requiredstring">
21 <param name="trim">true</param>
22 <message>密码不能为空!</message>
23 </field-validator>
24 <field-validator type="regex">
25 <param name="expression"><![CDATA[(\w{4,8})]]></param>
26 <message>密码必须长度为4-8的数字或字母!</message>
27 </field-validator>
28 </field>
29
30 <field name="repwd">
31 <field-validator type="requiredstring" short-circuit="true">
32 <param name="trim">true</param>
33 <message>重复密码不能为空!</message>
34 </field-validator>
35 <field-validator type="fieldexpression">
36 <param name="expression"><![CDATA[(repwd==user.pwd)]]></param>
37 <message>两次输入的密码要一致!</message>
38 </field-validator>
39 </field>
40
41 </validators>
一切已经ok!!!