struts_hibernate登陆范例
开发工具:MyEclipse 6.0 ,Tomcat 5.5 ,JDK 1.5 ,MySQL 5.0 ;开发准备:下载Struts 2.0和Hibernate 3.2,大家可Struts和Hibernate的官方网站下载这两个框架。我们先来总览一下开发完成后的包—类图:
首先NEW一个Web Project ,名为"LoginSystem" ,在 lib 目录下加入Struts 2.0的Jar包和Hibernate 3.2的Jar包,然后按下面的步骤来:
1、在 src 目录下建 "hibernate.cfg.xml" 全部代码如下:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.username">root</property> <property name="connection.url"> jdbc:mysql://localhost:3306/testmysql </property> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="myeclipse.connection.profile"> mysql </property> <property name="connection.password">root</property> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="show_sql">true</property> <!-- POJO类映射配置 --> <mapping resource="com/rong/ORM/User.hbm.xml" /> </session-factory> </hibernate-configuration>
2、建立实体类 "User.java" 及其映射文件 "User.hbm.xml" 两者都放在 "com.rong.ORM" 包下。其中"User.java"的代码如下:
package com.rong.ORM; public class User { private int id; //主键ID private String name; //用户名 private String pwd; //密码 /* * Getter方法与Setter方法 */ public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
User.hbm.xml的代码如下:
<?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> <class name="com.rong.ORM.User" table="tb_user"> <id name="id"> <generator class="native"/> </id> <property name="name" type="java.lang.String" length="20"/> <property name="pwd" type="java.lang.String" length="20"/> </class> </hibernate-mapping>
3、建立"ExportDB.java"工具类,我们执行如下代码,就能轻松将User类导入数据库转变成数据库中的表。不过,前提是我们已经在MySQL中建立了一个名为"LoginSystem"的数据库。
package tool; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; public class ExportDB { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Configuration cfg = new Configuration().configure(); SchemaExport export = new SchemaExport(cfg); export.create(true, true); } }
4、建立获取SessionFactory和管理Session的HibernateUtil.java类:
package com.rong.hibernate; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; 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(); } } }
5、DAO层设计:在"com.rong.DAO" 包下建立两个类,一个是接口,一个是实现类,其中UserDao.java代码如下:
package com.rong.DAO; import java.util.List; import com.rong.ORM.User; public interface UserDao { /** * 增加用户 * @param user 要增加的用户 */ public void add(User user); /** * 登录验证 * @param name * @param password * @return -1:不存在用户名 ; -2:密码不正确 ; >0:登录成功(即返回该记录ID) */ public int isExist(String name,String password); }
UserDaoImpl.java的代码如下
package com.rong.DAO; import java.util.Iterator; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import com.rong.ORM.User; import com.rong.hibernate.HibernateUtil; public class UserDaoImpl implements UserDao { HibernateUtil util = new HibernateUtil(); /** * 增加用户 * @param user 要增加的用户 */ public void add(User user){ Session session = util.getSession(); Transaction ts = null; try{ ts = session.beginTransaction(); session.save(user); ts.commit(); }catch(Exception e){ System.out.println("UserDaoImpl.add()方法发生异常:"); e.printStackTrace(); }finally{ util.closeSession(session); } } /** * 登录验证 * @param name * @param password * @return -1:不存在用户名 ; -2:密码不正确 ; >0:登录成功(即返回该记录ID) */ public int isExist(String name,String password){ //int state = 0 ; //初始化状态变量 Session session = util.getSession(); try{ Query query = session.createQuery("from User u where u.name = ?"); query.setString(0, name); List list = query.list(); if(null == list || 0 == list.size()){ return -1 ; //用户名不存在 } Query query2 = session.createQuery("from User u where u.name = ? and u.pwd = ?"); query2.setString(0, name); query2.setString(1, password); List list2 = query.list(); if(null == list2){ return -2 ; //密码不正确 } Iterator it = list.iterator(); User user = (User)it.next(); return user.getId(); //验证成功,取ID值 }catch(Exception e){ System.out.println("UserDaoImpl.isExist()方法发生异常:"); e.printStackTrace(); return 0; //异常时返回0 }finally{ util.closeSession(session); } } }
6、在web.xml中配置Struts 2.0支持:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 用过滤器配置Struts2支持 --> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.FilterDispatcher </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
7、登录页面login.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>Login Page</title> </head> <body> <p><a href="register.jsp">用户注册</a>|用户登录</p> <s:form action="loginAction" theme="simple"> <table> <tr> <td style="text-align:right"> 账号 </td> <td> <s:textfield name="name" label="账号" /> </td> </tr> <tr> <td style="text-align:right"> 密码 </td> <td> <s:password name="pwd" label="密码" /> </td> </tr> <tr> <td style="text-align:right"> 验证码 </td> <td> <s:textfield name="inputCertCode" label="验证码" cssStyle="width:100px"/> <img src="makeCertPic.jsp"> </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>
注册页register.jsp代码如下
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Register Page</title> </head> <body> <p><a href="login.jsp">用户登录</a>|用户注册</p> <s:form action="registerAction" theme="simple" method="post"> <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.pwd" 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="makeCertPic.jsp"> </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>
8、在JSP页中所用到的验证码的生成页面makeCertPic.jsp(我们把它放在WebRoot的other目录下):
<%@page contentType="image/jpeg" pageEncoding="gbk"%> <jsp:useBean id="image" scope="page" class="com.rong.other.makeCertPic" /> <% String str = image.getCertPic(0,0,response.getOutputStream()); // 将验证码保存到Session中 session.setAttribute("certCode", str); %>
其中,它调用了名为makeCertPic的Bean ,这个类主要用来生成彩色的验证图片,其代码如下:
package com.rong.other; 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; /** * 生成验证码图片 */ 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'}; /** * 功能:生成彩色验证码图片 * 参数width为生成的图片的宽度,参数height为生成的图片的高度,参数os为页面的输出流 */ 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 ""; } return strEnsure; } }
9、此时,我们很有必要来配置一下struts.xml其全部代码如下
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="com.rong.action" extends="struts-default"> <!-- 用户登录 --> <action name="loginAction" class="com.rong.action.LoginAction"> <result name="success" type="redirect">/back/index.jsp</result> <result name="input">/login.jsp</result> </action> <!-- 用户注册 --> <action name="registerAction" class="com.rong.action.RegisterAction"> <result name="success" type="redirect">/login.jsp</result> <result name="input">/register.jsp</result> </action> </package> </struts>
10、Action层设计:两个非常关键的类,其中LoginAction.java的代码如下:
package com.rong.action; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.rong.DAO.UserDao; import com.rong.DAO.UserDaoImpl; import com.rong.ORM.User; public class LoginAction extends ActionSupport { private UserDao userDao = new UserDaoImpl(); //操纵数据库DAO类(Hibernate实现),通过Struts.xml注入值 private int id; private String name; //用户名(值由struts注入) private String pwd; //密码(值由struts注入) private String inputCertCode; //验证码 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String getInputCertCode() { return inputCertCode; } public void setInputCertCode(String inputCertCode) { this.inputCertCode = inputCertCode; } @Override public String execute() throws Exception { int state = userDao.isExist(name,pwd); System.out.println("state="+state); if(state == -1){ this.addFieldError("name", "用户名不正确,请先注册!"); return INPUT; }else if(state == -2){ this.addFieldError("pwd", "密码不正确,请重新输入密码!"); return INPUT; }else if(state > 0){ System.out.println("[测试]登录成功!用户ID="+state); this.setId(state); return SUCCESS; }else{ this.addFieldError("name", "登录失败,请与管理员联系!"); return INPUT; } } public void validate() { //验证码验证 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", "验证码不正确!"); } } } }
RegisterAction.java的代码如下:
package com.rong.action; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.rong.DAO.UserDao; import com.rong.DAO.UserDaoImpl; import com.rong.ORM.User; public class RegisterAction extends ActionSupport { private UserDao userDao = new UserDaoImpl(); private User user; //注册提交的用户对象 private String repwd; //重复密码 private String 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; } @Override public String execute() throws Exception { userDao.add(user); //保存注册的user对象 return SUCCESS; } /* @Override public void validate() { //验证码验证 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", "验证码不正确!"); } } }*/ }
11、不要忘记配置校验框架,与上面两个Action同一个目录下。LoginAction-validation.xml代码如下:
<!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="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="pwd"> <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-validation.xml代码如下:
<!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.pwd"> <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.pwd)]]></param> <message>两次输入的密码要一致!</message> </field-validator> </field> </validators>
到这里,我们的项目也差不多完成了,大家自己也尝试一下,开发出自己的J2EE系统。