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的視圖中。

發佈了26 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章