Struts框架之手工编写代码方式实现校验

刷新验证

struts2的验证功能主要是使用ActionSupport类,实现了了以下接口:Action(提供execute()方法), Validateable(验证), ValidationAware(返回出错方法), TextProvider(读取属性文件), LocaleProvider(读取国际化资源), Serializable。对于Struts验证功能有两种方式手工编写代码和基于XML配置方式实现,本文先研究手工编写方式。

一、手工编写代码实现对action中所有与execute()签名相同方法输入校验
1、对Action继承ActionSupport并覆写方法validate(),校验其用户名称不能为空,代码如下:

package com.struts.service;


import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
import com.struts.controller.Login;

@SuppressWarnings("serial")
public class LoginService extends ActionSupport{ 
	private Login login;

	public Login getLogin() {
		return login;
	}

	public void setLogin(Login login) {
		this.login = login;
	}
	
	/**
	 * 对前台传递的数值进行校验
	 */
	@Override
	public void validate(){
		if(this.login.getUsername() == null ||"".equals(login.getUsername())){
			this.addFieldError("login.username", "用户名不能为空!");
		}
	}
	public String execute(){
		if(login!=null){
			System.out.println(login.getUsername());
			System.out.println(login.getPassword());
			System.out.println(login.getBirthday());
		}
		return Action.SUCCESS;
	}
}
2、创建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>用户登录</title>
</head>
<body>
	<!-- 使用debug标签可以调试 -->
	<s:debug></s:debug><br/>
	<!-- 使用struts的标签 可以封装到实体bean中 -->
	<form action="login.action" method="post">
		<s:textfield name="login.username" label="用户名"></s:textfield><br/>
		<s:password name="login.password" label="密码"></s:password><br/>
		<s:textfield name="login.birthday" label="出生日期"></s:textfield><br/>
		<s:submit value="登录"/>
	</form>
</body>
</html>

3、当点击”登录“时,如果没有进行刷新验证,则需要在struts配置文件中配置名为input的result标签,配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!-- 开发者模式 -->
	<constant name="struts.devMode" value="true"/>
    <!-- 登录所实现的包 -->
	<package name="login" namespace="/" extends="struts-default">
		<interceptors>
			<!--自定义拦截器 -->
			<interceptor name="myInterceptor" class="com.struts.interceptor.MyInterceptor"/>
			<interceptor-stack name="myInterceptorStack">
				<interceptor-ref name="myInterceptor"/>
				<interceptor-ref name="defaultStack"/>
			</interceptor-stack>
		</interceptors>
		<!-- 配置默认的拦截器栈,这样包下的action都会经过此拦截器,不需要每个action都配置-->
		<default-interceptor-ref name="myInterceptorStack"/>
		<action name="login" class="com.struts.service.LoginService">
			<result name="success">/ok.jsp</result>
			<result name="input">/login.jsp</result>
			<!-- <interceptor-ref name="myInterceptor"/>自定义的拦截器,没有下面配置的defaultStack则前台页面的属性不会自动封装导致传递值内容为空
			<interceptor-ref name="defaultStack"/>默认的拦截器栈 -->
		</action>
	</package>
</struts>

4、当按照上述配置完成后,如果没有输入用户名,则在页面上提示显示如下:


常量的使用

1、使用struts常量:<constant name="struts.ui.theme" value="simple"/>,避免struts2标签的冗余。但是会造成<s:textfield/>中的label显示出来,因此,修改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>用户登录</title>
</head>
<body>
        <!-- 使用debug标签可以调试 -->
       <s:debug></s:debug><br/>
       <form action="login.action" method="post">
		用户名:<s:textfield name="login.username"></s:textfield><br/>
		密码:<s:password name="login.password"></s:password><br/>
		出生日期:<s:textfield name="login.birthday"></s:textfield><br/>
		<s:submit value="登录"/>
	</form> 
</body>
</html>

2、使用常量后,用户名为空后页面上不再提示错误信息,但是根据debug信息,可以发现错误信息


因此,我们可以使用EL表达式来获取错误信息。此外在页面上还要解开对EL表达式的限制:<%@page isELIgnored="false" %>

EL表达式为:${errors.login.username[0]},但是发现使用EL表达式后页面上并没有出现错误信息,但是在Debug中发现存在值。有以下两种解决办法:

①在LoginService的类中调用addFieldError时传入的key值中不能带”.“,譬如说this.addFieldError("username", "用户名不能为空!");则在页面上使用${errors.username[0]}来进行提示。

②使用<s:fielderror fieldName="login.username"/>标签,但是发现样式乱掉了,使用firefox的fiebug显示,发现在使用此标签时,struts2默认增加了ul等标签。简单的一种方法是为此增加样式:

<style type="text/css">
ul.errorMessage {color: #FF3300;}
ul.errorMessage {list-style-type: none;display: inline;margin: 0px;padding: 3px;}
ul.errorMessage li {list-style-type: none;display: inline;}
</style>
另外,对于<s:fielderror>标签中的theme的应用不太熟悉,如果有了解的朋友则指教一番,在此先谢谢了。

二、手工编写代码实现对action中指定方法输入校验

对action中指定方法输入校验:通过validateXxxx()方法进行实现。validateXxxx()方法只会校验方法名为Xxxxx的方法,

1、在LoginService中添加login方法和validateLogin方法:

package com.struts.service;


import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
import com.struts.controller.Login;

@SuppressWarnings("serial")
public class LoginService extends ActionSupport{ 
    private Login login;

    public Login getLogin() {
        return login;
    }

    public void setLogin(Login login) {
        this.login = login;
    }
    
    /**
     * 对前台传递的数值进行校验
     */
    @Override
    public void validate(){
        if(this.login.getUsername() == null ||"".equals(login.getUsername())){
            this.addFieldError("username", "用户名不能为空!");
        }
    }
    //对指定方法进行校验
    public void validateLogin(){
        if(this.login.getUsername() == null ||"".equals(login.getUsername())){
            this.addFieldError("username", "特定方法校验:用户名不能为空!");
        }
    }
    public String execute(){
        if(login!=null){
            System.out.println(login.getUsername());
            System.out.println(login.getPassword());
            System.out.println(login.getBirthday());
        }
        return Action.SUCCESS;
    }
    
    public String login(){
        return Action.SUCCESS;
    }
}

2、编写配置文件,当登录时调用login()方法,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <!-- 开发者模式 -->
    <constant name="struts.devMode" value="true"/>
    <!-- 主题模式为simple,避免使用struts标签造成标签冗余 -->
    <constant name="struts.ui.theme" value="simple"/>
    <!-- 登录所实现的包 -->
    <package name="login" namespace="/" extends="struts-default">
        <interceptors>
            <!--自定义拦截器 -->
            <interceptor name="myInterceptor" class="com.struts.interceptor.MyInterceptor"/>
            <interceptor-stack name="myInterceptorStack">
                <interceptor-ref name="myInterceptor"/>
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>
        </interceptors>
        <!-- 配置默认的拦截器栈,这样包下的action都会经过此拦截器,不需要每个action都配置-->
        <default-interceptor-ref name="myInterceptorStack"/>
        <action name="login" class="com.struts.service.LoginService" method="login">
            <result name="success">/ok.jsp</result>
            <result name="input">/login.jsp</result>
            <!-- <interceptor-ref name="myInterceptor"/>自定义的拦截器,没有下面配置的defaultStack则前台页面的属性不会自动封装导致传递值内容为空
            <interceptor-ref name="defaultStack"/>默认的拦截器栈 -->
        </action>
    </package>
</struts>
如上配置后,页面正确出现错误信息。

输入校验流程

在上述两种输入校验中,我们发现,在对特定方法校验时,validate()方法不起作用了。其实,validate()方法也起作用了,在debug中发现,errors中有两个值:

因此,我们可以看到输入校验的流程为:

首先,类型转换器进行类型转换,并将转换后的值给action中的属性赋值,如果在执行转换过程中出现异常,则会将异常信息添加到fieldErrors中,接下来,通过反射技术调用action中 validateXxxx()方法,如果有错误则存放到fieldErrors中,然后调用validate()方法,出现错误则存放在fieldErrors中。最后,如果fieldErrors中出现错误,则系统自动转发请求至input的视图中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值