问题陈述:本讲将完成通用论坛系统的BBS的注册功能。用户在用户注册页面填写用户注册信息,单击[确认]按钮后,则提交用户注册信息,这些信息经过Validator框架验证成功后,被提交到数据库,则该用户成了BBS系统注册用户。
一、创建数据库表
create database if not exists ‘bbs’
CREATE TABLE ‘user’ (
‘ username’ varchar(20) NOT NULL,
‘ password’ varchar(20) NOT NULL,
‘sex’ char(2) NOT NULL,
‘email’ varchar(50) NOT NULL,
‘icq’ varchar(20) default NULL,
‘signature’ varchar(300) default NULL,
‘grade’ varchar(20) default NULL,
PRIMARY KEY (‘username’)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
二、创建实体类
package com.ljh.model;
public class User {
private String username;
private String password;
private String sex;
private String email;
private String icq;
private String signature;
private String grade;
public User() { }
/** minimal constructor */
public User(String username, String password, String sex, String email) {
this.username = username;
this.password = password;
this.sex = sex;
this.email = email;
}
/** full constructor */
public User(String username, String password, String sex, String email, String icq, String signature, String grade) {
this.username = username;
this.password = password;
this.sex = sex;
this.email = email;
this.icq = icq;
this.signature = signature;
this.grade = grade;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getIcq() {
return this.icq;
}
public void setIcq(String icq) {
this.icq = icq;
}
public String getSignature() {
return this.signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getGrade() {
return this.grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
三、创建数据访问类
1. 创建数据库连接类
l 在struts-config.xml文件中配置数据源,基内容为:
<data-sources>
<data-source key="bbsDB" type="org.apache.commons.dbcp.BasicDataSource">
<set-property property="driverClassName" value="org.gjt.mm.mysql.Driver" />
<set-property property="url" value="jdbc:mysql://localhost:3306/bbs" />
<set-property property="username" value="root" />
<set-property property="password" value="root" />
</data-source>
</data-sources>
注:必须在工程中引入mysql的jdbc驱动程序
l 编写获取数据库连接的类DB.java
package com.ljh.dao;
import javax.sql.DataSource;
import javax.servlet.ServletContext;
import java.sql.Connection;
import javax.servlet.*;
public class DB {
private DataSource ds;
private Connection conn;
public DB(DataSource ds){
this.ds=ds;
}
public Connection getConn()
{
try{
conn=ds.getConnection();
return conn;
}
catch(Exception e){System.out.println(e);}
return null;
}
public void closeConn(Connection conn)
{
try
{
if(conn!=null)
conn.close();
}
catch(Exception e){}
}
}
2. 创建User表的Dao类UserDao.java
package com.ljh.dao;
import com.ljh.model.*;
import java.sql.*;
public class UserDao {
Connection conn;
DB db;
public UserDao(DB db){
this.db=db;
}
public boolean saveUser(User user){
PreparedStatement stmt=null;
try{
conn=db.getConn();
conn.setAutoCommit(false);
stmt=conn.prepareStatement("insert into user(username,password,sex,email,icq,signature,grade)" +
" values(?,?,?,?,?,?,?)");
stmt.setString(1, user.getUsername());
stmt.setString(2, user.getPassword());
stmt.setString(3, user.getSex());
stmt.setString(4,user.getEmail());
stmt.setString(5, user.getIcq());
stmt.setString(6,user.getSignature());
stmt.setString(7, user.getGrade());
int count= stmt.executeUpdate();
if(count>=1){
conn.commit();
return true;
}
}catch(Exception e){
e.printStackTrace();
try{
conn.rollback();
}catch(SQLException sqlex){
sqlex.printStackTrace(System.out);
}
finally{
try{
stmt.close();
db.closeConn(conn);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
return false;
}
public boolean updateUser(User user){
………;
}
public boolean deleteUser(User user){
………;
}
public User findUser(String usernaem, String password){
………;
}
}
四、创建用户注册页面registration.jsp
1. 页面的代码
<%@ page contentType="text/html;charset=gb2312" language="java"%>
<%@ include file="/common/taglibs.jsp"%>
<html:html>
<head>
<title>
注册用户
</title>
</head>
<link href="images/myStyleClass.css" rel="stylesheet" type="text/css">
<body>
<%@ include file="/common/header.jsp"%>
<ul>
<html:messages id="message">
<li><bean:write name="message"/></li>
</html:messages>
</ul>
<table width="68%" border="0" align="center">
<tr align="center">
<td>
<A href="javascript:history.go(-1);">
返回上一页
</A>
</td>
</tr>
</table>
<html:form action="registration.do">
<table width="72%" border="1" align="center">
<tr>
<td width="21%">
用户名:
</td>
<td width="79%">
<INPUT class=input2 maxLength=20 name=username>
* (由英文字母、数字、汉字和下划线"_"组成)
</td>
</tr>
<tr>
<td>
密码:
</td>
<td>
<INPUT class=input2 type=password maxLength=16 name=password>
*
</td>
</tr>
<tr>
<td>
确认密码:
</td>
<td>
<INPUT class=input2 type=password maxLength=16 name=password2>
*
</td>
</tr>
<tr>
<td>
性别:
</td>
<td>
<INPUT type=radio CHECKED value=男 name=sex>
男
<INPUT type=radio value=女 name=sex>
女
</td>
</tr>
<tr>
<td>
电子邮箱:
</td>
<td>
<INPUT class=input2 maxLength=40 name=email>
*
</td>
</tr>
<tr>
<td>
ICQ:
</td>
<td>
<INPUT class=input2 maxLength=40 name=icq>
</td>
</tr>
<tr>
<td>
签名档:
</td>
<td>
<TEXTAREA class=input2 name=signature rows=10 cols=50></TEXTAREA>
</td>
</tr>
<tr>
<td>
<html:submit property="submit">
确认
</html:submit>
</td>
<td>
<html:reset>重写</html:reset>
</td>
</tr>
</table>
</html:form>
<%@ include file="/common/footer.jsp"%>
</body>
</html:html>
2. 页面的效果图
注:上面的代码中是将所有错误在同一个地方显示,若想实在每个输入控件后面显示错误提示,就必须手动设置标签的属性,如:<html:errors property="XXX">;例如,假如密码校验有问题时,在密码控件的后面加上:<html:errors property="password">即可。
五、创建用户注册模型组件RegistrationForm.java
如果要使用Validator框架,应该采用ActionForm类的两个子类:org.apache.strutes.validator.DynaValidatorForm和org.apache.struts.validator.ValidatorForm。DynaValidatorForm支持在动态的ActionForm中使用Validator框架,ValidatorForm支持在标准ActionForm中使用Validator框架。这里我们使用后使用后者。
package com.ljh.struts.user.form;
import org.apache.struts.validator.ValidatorForm;
public class RegistrationForm extends ValidatorForm {
private String username;
private String password;
private String password2;
private String sex;
private String email;
private String signature;
private String grade;
private String icq;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public String getIcq() {
return icq;
}
public void setIcq(String icq) {
this.icq = icq;
}
public String getPassword2() {
return password2;
}
public void setPassword2(String password2) {
this.password2 = password2;
}
}
六、创建用户注册的控制器组件
package com.ljh.struts.user.action;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.ljh.struts.user.form.RegistrationForm;
import org.apache.struts.action.*;
import javax.sql.DataSource;
import com.ljh.dao.*;
import com.ljh.model.*;
public class RegistrationAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
RegistrationForm registrationForm = (RegistrationForm) form;
String pageForward;
try{
String username=new String(registrationForm.getUsername().getBytes("ISO-8859-1"),"GB2312");
String password=registrationForm.getPassword();
String sex=new String(registrationForm.getSex().getBytes("ISO-8859-1"),"GB2312");
String email=registrationForm.getEmail();
String icq=registrationForm.getIcq();
String signature=new String(registrationForm.getSignature().getBytes("ISO-8859-1"),"GB2312");
String grade=registrationForm.getGrade();
ActionMessages errors=new ActionMessages();
//DataSource ds=this.getDataSource(request);
ServletContext context = servlet.getServletContext();
DataSource ds = (DataSource) context
.getAttribute("bbsDB");
DB db=new DB(ds);
User user=new User();
UserDao userdao=new UserDao(db);
user.setUsername(username);
user.setPassword(password);
user.setSex(sex);
user.setEmail(email);
user.setIcq(icq);
user.setSignature(signature);
user.setGrade(grade);
Boolean flag=userdao.saveUser(user);
if(flag){
pageForward="ToSuccessPage";
}
else
{
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage("error.registration.failed"));
if(!errors.isEmpty()){
saveErrors(request,errors);
db=null;
pageForward="ToErrorPage";
}
}
}
catch(Exception e){}
return mapping.findForward(pageForward);
}
}
七、对用户输入的表单数据进行效验
校验遵守如下规则:
l 用户名、密码、确认密码、性别、电子邮件不能为空
l 电子邮件输入的必须符合电子邮件的格式
l ICQ只能为5-12位的整数
l 密码必须与确认密码一致
1. 创建用于自定义验证规则类CustomValidator.java
package com.ljh.struts;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.util.ValidatorUtils;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.validator.Resources;
public class CustomValidator{
public CustomValidator(){
super();
}
public static boolean validateTwoFields(Object bean,
ValidatorAction va, Field field, ActionMessages errors, HttpServletRequest request) {
String value = ValidatorUtils.getValueAsString(bean, field.getProperty());
String sProperty2 = field.getVarValue("secondProperty");
String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);
if (!GenericValidator.isBlankOrNull(value)) {
try {
if (!value.equals(value2)) {
errors.add( field.getKey(), Resources.getActionMessage(request, va, field));
return false;
}
} catch (Exception e) {
}
}
return true;
}
}
2. 在validator-rules.xml文件中添加下面的代码:
<validator name="twofields" classname="com.ljh.struts.CustomValidator"
method="validateTwoFields"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
javax.servlet.http.HttpServletRequest" msg="errors.twofields" />
3. 在validation.xml文件中配置RegistrationForm的验证规则
在项目的根目录处点击鼠标右键,选择新建“XML(Basic Templates)”,在弹出的窗口中选择“Create XML file from a DTD file”下一步,将文件目录设置到WEB-INF下,文件名取为“validation.xml”下一步;在这里点击“Select XML Catalog entry”选项,并选择KEY名为“-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN”的选项,下一步;此处已经不需要再设置什么,直接点击“Finish”完成validation.xml的建立,通过这样的建立文件,在编辑过程中输入"<"符号后,编辑器就会自动查找与当前结构匹配的Validator标签。
Validation.xml文件的内容为:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
<form-validation>
<formset>
<form name="registrationForm">
<field property="username" depends="required">
<arg0 key="registrationForm.username"/>
</field>
<field property="password" depends="required,mask,twofields">
<arg0 key="registrationForm.password" />
<arg1 name="twofields" key="registrationForm.password2" />
<var>
<var-name>mask</var-name>
<var-value>^[0-9a-zA-Z]*$</var-value>
</var>
<var>
<var-name>secondProperty</var-name>
<var-value>password2</var-value>
</var>
<msg name="mask" key="password.invlidformat"/>
</field>
<field property="password2" depends="required,mask">
<arg0 key="registrationForm.password2" />
<var>
<var-name>mask</var-name>
<var-value>^[0-9a-zA-Z]*$</var-value>
</var>
</field>
<field property="email" depends="required,email">
<arg0 key="registrationForm.email" />
</field>
<field property="icq" depends="mask">
<var>
<var-name>mask</var-name>
<var-value>^/d{5,12}$</var-value>
</var>
<msg name="mask" key="icq.invlidformat" />
</field>
</form>
</formset>
</form-validation>
4. Struts-Config.xml配置文件里添加插件
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
</plug-in>
5. 创建消息资源文件
创建中文临时消息文件ApplicationResources-temp.properties,文件的内容如下:
# Resources for parameter 'com.ljh.struts.ApplicationResources'
image.adrlogo=Powered by Aslan
footer.jsp.author=Copyright@Aslan Studio 2006-2007 All rights reserved
footer.jsp.copyright=Aslan BBS
errors.invalid={0} 无效。
errors.maxlength={0} 不能大于 {1} 个字符。
errors.minlength={0} 不能少于 {1} 个字符。
errors.range={0} 未在 {1} 与 {2} 范围内。
errors.required={0} 为必填项。
errors.byte={0} 必须为byte类型。
errors.date={0} 不是有效日期格式。
errors.double={0} 必须为double类型。
errors.float={0} 必须为float类型。
errors.integer={0} 必须为一数值。
errors.long={0} 必须为long类型。
errors.short={0} 必须为short类型。
errors.creditcard={0} 为无效信用卡号。
errors.email={0} 为无效邮件地址。
errors.phone={0} 为无效电话号码。
errors.zip={0} 为无效邮政编码。
#Validation and error messages for RegistrationForm
registrationForm.username=用户名
registrationForm.password=用户密码
registrationForm.password2=用户确认密码
registrationForm.email=email地址
password.invlidformat=密码只能为数字或字母
icq.invlidformat=ICQ必须为5到8位的数字
errors.twofields={0}必须和{1}一致
6. 对资源文件进行编码转换
创建一个批处理文件,假设为:native.bat,设置其中的内容为:
native2ascii -encoding gb2312 ApplicationResources-temp.properties ApplicationResources.properties
将该文件存放在ApplicationResources-temp.properties所在的目录下。
进入命令窗口,转到native.bat文件所在的目录,运行该命令,即创建了中文资源文件ApplicationResources.properties.
完成上面的代码后,对用户输入的信息进行验证,.验证没有通过并跳回编辑页面,
发现原来用户输入的数据不能保持.全部为空.查了好长时间才发现原来registration.jsp页面中的标签没有用struts标签,改为struts标签,即可保持原来输入的数据。