实现目标:

      1.使用验证框架对用户注冊信息进行验证
      2.验证username、password、邮箱不能为空
      3.验证username、password长度
      4.验证邮件地址格式

详细实现

一、Struts2应用的基础配置

      这里不做具体阐述,具体为web.xml、相关jar包的配置

二、将页面显示的文本内容放到资源文件里

      1.查看用户注冊程序中的全部页面,找到全部能够显示的文本内容,将它们分离出来放到资源文件里。
      2.与相关的Action类同名,以.preperties为扩展名,与Action类位于同一个包中,仅仅能由该Action訪问

RegisterAction_zh_CN.properties

#register.jsp页面所需的字符串资源
title=用户注冊
username=用户名
password=密码
sex=性别
sex.male=男
sex.female=女
email=邮件地址
pwdQuestion=密码问题
pwdAnswer=密码答案
submit=注冊
reset=重置 #success.jsp页面所需的字符串资源
success=注冊成功
success.info=${user.username},恭喜你注冊成功 #error.jsp页面所需的字符串资源
failure=注冊失败
failure.info=注冊失败,原因是:${exception}<br>请<a href="{0}">又一次注冊</a>
error.username.exist=用户名已经存在 error.username.length=${getText("username")}长度必须在${minLength}到${maxLength}个字符之间
error.password.length=${getText("password")}长度必须在${minLength}到${maxLength}个字符之间
error.email.invalid=${getText("email")}格式不正确 error.username.required=${getText("username")}不能为空
error.password.required=${getText("password")}不能为空
error.email.required=${getText("mail")}不能为空
      最后两段代码是加入的错误消息,使用OGNL表达式作为消息文本的參数

三、编写验证文件

      RegisterAction-validation.xml,相同,与相关Action类位于同一个包
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"> <validators>
<!-- 针对user.username字段的验证规则 -->
<field name="user.username">
<!-- 使用requiredstring验证器。确保user.username字段值不为null,也不为“” -->
<field-validator type="requiredstring">
<message key="error.username.required"/>
</field-validator> <!-- 使用stringlength验证器。确保user.username字段值的字符长在4到12之间 -->
<field-validator type="stringlength">
<!-- 向stringlength验证器实例传递minLength和maxLength參数 -->
<param name="minLength">4</param>
<param name="maxLength">12</param>
<message key="error.username.length"/>
</field-validator>
</field> <!-- 针对user.password字段的验证规则 -->
<field name="user.password">
<field-validator type="requiredstring">
<message key="error.password.required"/>
</field-validator> <field-validator type="stringlength">
<param name="minLength">4</param>
<param name="maxLength">12</param>
<message key="error.password.length"/>
</field-validator>
</field> <!-- 针对user.email字段的验证规则 -->
<field name="user.email">
<field-validator type="requiredstring">
<message key="error.email.required"/>
</field-validator>
<field-validator type="email">
<message key="error.email.invalid"/>
</field-validator>
</field>
</validators>

1).在编写验证文件时要注意。DTD的声明,我一開始对着教材上的DTD版本号输入,运行的时候发现提示了一个错误例如以下:

The file cannot be validated as the XML definition "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd" that is specified as describing the syntax of the file cannot be located.

后来在网上找到了解决方式,替换成上面正确的版本号就能够了。

四、其它相关Action类、页面的编写等

RegisterAction
package register.action;

import java.sql.SQLException;
import java.util.Date; import register.dao.UserDao;
import register.entity.User;
import register.exceptions.UsernameExistException; import com.opensymphony.xwork2.ActionSupport; public class RegisterAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
private User user;
private UserDao userdao;
public RegisterAction(){
userdao=new UserDao();
}
@Override
public String doDefault()throws Exception{
return INPUT;
}
@Override
public String execute() throws SQLException, UsernameExistException{ user.setRegDate(new Date());
try{
userdao.register(user);
}catch(UsernameExistException e){
addFieldError("user.username",getText("error.username.exist"));
return INPUT;
}
return SUCCESS;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
} }

用户实体类:User

package register.entity;

import java.io.Serializable;
import java.util.Date; public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String username;
private String password;
private Boolean sex;
private String email;
private String pwdQuestion;
private String pwdAnswer;
private Date regDate;
private Date lastLoginDate;
private String lastLoginIp;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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 Boolean getSex() {
return sex;
}
public void setSex(Boolean sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPwdQuestion() {
return pwdQuestion;
}
public void setPwdQuestion(String pwdQuestion) {
this.pwdQuestion = pwdQuestion;
}
public String getPwdAnswer() {
return pwdAnswer;
}
public void setPwdAnswer(String pwdAnswer) {
this.pwdAnswer = pwdAnswer;
}
public Date getRegDate() {
return regDate;
}
public void setRegDate(Date regDate) {
this.regDate = regDate;
}
public Date getLastLoginDate() {
return lastLoginDate;
}
public void setLastLoginDate(Date lastLoginDate) {
this.lastLoginDate = lastLoginDate;
}
public String getLastLoginIp() {
return lastLoginIp;
}
public void setLastLoginIp(String lastLoginIp) {
this.lastLoginIp = lastLoginIp;
} }

对注冊用户的数据库操作.UserDao

package register.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import register.entity.User;
import register.exceptions.UsernameExistException; public class UserDao {
public UserDao(){
String driverClass="com.mysql.jdbc.Driver"; try{
Class.forName(driverClass);
}catch(ClassNotFoundException ce){
ce.printStackTrace();
}
}
public Connection getConnection() throws SQLException{
String url="jdbc:mysql://localhost:3307/user";
String user="tankcat_2";
String pw="wxt222$$$";
return DriverManager.getConnection(url,user,pw);
} public User register(User user) throws SQLException, UsernameExistException{
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try{
conn=getConnection();
String sql="select * from reg_user where username = ? ";
pstmt=conn.prepareStatement(sql);
pstmt.setString(1, user.getUsername());
rs=pstmt.executeQuery();
if(rs.next()){
throw new UsernameExistException();
}
sql="insert into reg_user(username,password,sex,email,pwd_question,pwd_answer,reg_date) values(?,? ,? ,?,? ,?,?)";
pstmt=conn.prepareStatement(sql);
pstmt.setString(1, user.getUsername());
pstmt.setString(2, user.getPassword());
pstmt.setBoolean(3, user.getSex());
pstmt.setString(4, user.getEmail());
pstmt.setString(5, user.getPwdQuestion());
pstmt.setString(6,user.getPwdAnswer());
pstmt.setTimestamp(7, new java.sql.Timestamp(user.getRegDate().getTime()));
pstmt.execute();
rs=pstmt.executeQuery("select last_insert_id()");
if(rs.next()){
user.setId(rs.getInt(1));
}else{
return null;
}
}catch(SQLException se){
throw se;
}finally{
closeResultSet(rs);
closePreparedStatement(pstmt);
closeConnection(conn);
}
return user;
}
private void closeResultSet(ResultSet rs) {
// TODO Auto-generated method stub
if(rs!=null){
try{
rs.close();
}catch(SQLException se){
se.printStackTrace();
}
rs=null;
}
}
private void closePreparedStatement(PreparedStatement pstmt) {
// TODO Auto-generated method stub
if(pstmt!=null){
try{
pstmt.close();
}catch(SQLException se){
se.printStackTrace();
}
pstmt=null;
} }
private void closeConnection(Connection conn) {
// TODO Auto-generated method stub
if(conn!=null){
try{
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
conn=null;
}
}
}

struts.xml文件的配置

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

>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" /> <package name="default" extends="struts-default">
<action name="register" class="register.action.RegisterAction">
<exception-mapping result="error" exception="java.lang.Exception"/>
<result name="input">/register.jsp</result>
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
</action> </package>
</struts>

register.jsp注冊页面的编写

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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=UTF-8">
<title><s:text name="title"/></title>
</head>
<body> <hr color="#ededed"/>
<s:fielderror/>
<s:form action="register.action">
<s:textfield name="user.username" key="username"/>
<s:password name="user.password" key="password"/>
<s:radio name="user.sex" value="true"
list="#{true:getText('sex.male'),false:getText('sex.female')}" key="sex"/>
<s:textfield name="user.email" key="email"/>
<s:textfield name="user.pwdQuestion" key="pwdQuestion"/>
<s:textfield name="user.pwdAnswer" key="pwdAnswer"/>
<s:submit key="submit"/>
<s:reset key="reset"/>
</s:form>
</body>
</html>

succes.jsp注冊成功页面的编写

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!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=UTF-8">
<title>欢迎界面</title>
</head>
<body>
<s:property value="user.username"/>。欢迎
</body>
</html>

error.jsp注冊失败页面的编写

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
//String path = request.getContextPath();
//String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
//得到Web应用程序的上下文路径
String path=request.getContextPath();
//构建Web应用程序上下文路径的完整URL
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="failure"/></title>
</head>
<body>
<s:text name="failure.info">
<s:param><%=basePath %>register!default.action</s:param>
</s:text>
</body>
</html>

该Struts2应用程序的文件夹结构例如以下图:

    

測试截图:

      1.启动Tomcatserver。在地址栏中输入http://localhost:8080/struts2-RegisterValidate/register!default.action,出现下列显示内容:
       
      显然。这不是我们想要的结果,当用户訪问注冊页面而不是提交注冊表单时,是不须要进行验证的。出现以上的原因是,在调用Register。

Action的doDefault方法之前。验证框架被调用了。

      因为调用验证框架的拦截器是validation。而不是workflow。因此我们能够为validation拦截器配置排除方法,更改例如以下:
<action	name="register" class="register.action.RegisterAction">
<exception-mapping result="error" exception="java.lang.Exception"/>
<interceptor-ref name="defaultStack">
<param name="validation.excludeMethods">default</param>
</interceptor-ref>
<result name="input">/register.jsp</result>
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
</action>

重新启动Tomcat,再次測试用户注冊程序。此时一切执行正常

      

      

      
      
      



struts2学习笔记(三)—— 在用户注冊程序中使用验证框架的更多相关文章

  1. Struts2学习笔记三:深入Action

    一:Action中获取参数值 在Servlet中,我们通过doGet()/doPost()方法中的参数,获取request/response对象,然后提取参数值: 处理请求结束后,有数据需要携带返回客 ...

  2. Struts2学习笔记(三)——Action详解

    Action是用于处理请求操作的,它是由StrutsPrepareAndExceuteFilter分发过来的. 1.Action的创建方式 1) POJO类(PlainOldJavaObjects简单 ...

  3. Struts2学习笔记三 访问servlet

    结果跳转方式 转发 <!-- 转发 --> <action name="Demo1Action" class="cn.itheima.a_result. ...

  4. struts2学习笔记三

    一.国际化概念(了解) 1.什么是国际化 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 2.什么需要国际 ...

  5. Struts2学习笔记(三):result配置的各项视图转发类型

    Struts 1: <action path="/user" type="org.sunny.user.action.UserAction" ...> ...

  6. C语言学习笔记(一)_hello world程序中涉及的c语言元素

    #include <stdio.h> //使用printf函数之前必须include<stdio.h> int main() { int i; //声明一个变量 printf( ...

  7. YII用户注冊和用户登录(三)之模型中规则制定和分析

    3 模型中规则制定和分析 YII模型主要分为两类,一个数据模型,处理和数据库相关的增删改查.继承CActiveRecord.还有一个是表单模型,继承CFormModel.不与数据库进行交互.操作与数据 ...

  8. 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记

    回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...

  9. Struts2 学习笔记(概述)

    Struts2 学习笔记 2015年3月7日11:02:55 MVC思想 Strust2的MVC对应关系如下: 在MVC三个模块当中,struts2对应关系如下: Model: 负责封装应用的状态,并 ...

随机推荐

  1. SpringBoot学习(六)

    1.pom 文件 <?xml version="1.0" encoding="utf-8"?> <dependencies> <d ...

  2. javascript类型系统

    前面的话 除了对象之外,数组Array类型可能是javascript中最常用的类型了.而且,javascript中的数组与其他多数语言中的数组有着相当大的区别.本文将介绍javascript中的数组A ...

  3. 【BZOJ 4332】 4332: JSOI2012 分零食 (FFT+快速幂)

    4332: JSOI2012 分零食 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 119  Solved: 66 Description 这里是欢乐 ...

  4. 【UOJ #206】【APIO 2016】Gap

    http://uoj.ac/problem/206 对于T=1,直接从两端往中间跳可以遍历所有的点. 对于T=2,先求出最小值a和最大值b,由鸽巢原理,答案一定不小于\(\frac{b-a}{N-1} ...

  5. luoguP4457 [BJOI2018]治疗之雨 概率期望 + 高斯消元

    应该是最后一道紫色的概率了....然而颜色啥也代表不了.... 首先看懂题意: 你现在有$p$点体力,你的体力上限为$n$ 在一轮中, 1.如果你的体力没有满,你有$\frac{1}{m + 1}$的 ...

  6. 二维数组sort排序

    和副本任务完全无关的奇怪感慨: 完全搞不懂我为什么会在搞图论的时候学这种奇怪东西,需要的时候不会,不需要的时候又莫名增加了奇怪的技能点. 之前的假期规划在十多天的放飞自我中彻底泡汤,简单的图论都一点不 ...

  7. BZOJ 2938 [Poi2000]病毒(AC自动机)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2938 [题目大意] 给出一些病毒串,问是否存在不包含任何病毒串的无限长的字符串 [题解 ...

  8. 【次短路径/SPFA】BZOJ1726-[Usaco2006 Nov]Roadblocks第二短路

    [题目大意] 求无向图点1到n的次短路. [思路] 一年多前写过一次堆优化Dijkstra的,方法就是一边跑Dijsktra一边就把次短路径保存下来.和一般Dijkstra不同的是把vis数组去掉了, ...

  9. 【KM】BZOJ1937 [Shoi2004]Mst 最小生成树

    这道题拖了好久因为懒,结果1A了,惊讶∑( 口 || [题目大意] 给定一张n个顶点m条边的有权无向图.现要修改各边边权,使得给出n-1条边是这张图的最小生成树,代价为变化量的绝对值.求最小代价之和. ...

  10. ms08-067漏洞的复现

    MS08-067漏洞重现 (1):MS08-067远程溢出漏洞描述 MS08-067漏洞的全称为“Windows Server服务RPC请求缓冲区溢出漏洞”,如果用户在受影响的系统上收到特制的 RPC ...