zoukankan      html  css  js  c++  java
  • 第十三部分_XWork对输入校验的支持,类型转换与输入校验总结

    当我们使用Struts2表单时,它是一种增强型的表单,自带了错误信息输出的功能,不需要指定它的fielderror等其他的信息,并且其错误信息出现在对应输入框的上面。

    如下实例:

    首先,login2.jsp:

    <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="/struts-tags" prefix="s" %><%--pay attention to uri --%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'login2.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    
      </head>
      
      <body>
       	<s:form action="login.action" method="Get">
       		<s:textfield name="username" label="username"></s:textfield>r<br/>
       		<s:password name="password" label="password"></s:password>
       		<s:submit value="submit"></s:submit>
       	</s:form>
      </body>
    </html>
    

    然后是LoginAction.java:

    package com.test.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class LoginAction extends ActionSupport
    {
    	private String username;
    	
    	private String password;
    
    	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 String execute() throws Exception
    	{
    		return "success";
    	}
    	
    	@Override
    	public void validate()
    	{
    		if(null == username || -1 != username.indexOf(("hello")))
    		{
    			this.addFieldError("username", "username invalid");
    		}
    		
    		if(null == password || password.length() < 4)
    		{
    			this.addFieldError("password", "password invalid");
    		}
    	}
    }
    

    struts.xml文件相关部分配置如下:

    <action name="login" class="com.test.action.LoginAction">
    				<result name="success">/result.jsp</result>
    				<result name="input">/login2.jsp</result>
    			</action>
    

    一个输出样例:

    下面给出利用校验框架进行校验的实例:

    register.jsp如下:

    <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
    <%@ taglib uri="/struts-tags" prefix="s" %>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'register.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    
      </head>
      
      <body>
      
      	<table align="center" width="40%" border="0">
        		<tr>
        			<td> 
        				 <s:actionerror cssStyle="color:red"/><%--actionerror中增加的所有信息显示到页面上 --%> 
        				 __________________________________________________
        				 <s:fielderror cssStyle="color:blue"></s:fielderror>
        			</td>
        		</tr>
        </table>
       
        <form action="register.action" method="post">
        
        	<table align="center" width="40%" border=1">
        		<tr>
        			<td> 
        				username: 
        			</td>
        				
        			<td>
        				<input type="text" name="username" size="20">
        			</td>
        		</tr>
        		
        		
        		<tr>
        			<td>
        				password:
        			</td>
        				
        			<td>
        				<input type="password" name="password" size="20">
        			</td>
        		</tr>
        		
        		
        		<tr>
        			<td>
        				re-password:
        			</td>
        				
        			<td>
        				<input type="password" name="repassword" size="20">
        			</td>
        		</tr>
        	
        	
        		<tr>
        			<td>
        				age:
        			</td>
        				
        			<td>
        				<input type="text" name="age" size="20">
        			</td>
        		</tr>
        	
        	
        		<tr>
        			<td>
        				birthday:
        			</td>
        				
        			<td>
        				<input type="text" name="birthday" size="20">
        			</td>
        		</tr>
        		
        		
        		<tr>
        			<td>
        				graduation:
        			</td>
        				
        			<td>
        				<input type="text" name="graduation" size="20">
        			</td>
        		</tr>
        		
        		<tr>
        			<td>
        				<input type="submit" value="submit"/>
        			</td>
        				
        			<td>
        				<input type="reset" value="reset"/>
        			</td>
        		</tr>
        	</table>
    
        
        </form>
        
    
        
      </body>
    </html>
    

    RegisterAction.java如下:

    package com.test.action;
    
    import java.util.Calendar;
    import java.util.Date;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class RegisterAction extends ActionSupport
    {
    	private String username;
    	
    	private String password;
    	
    	private String repassword;
    	
    	private int age;
    	
    	private Date birthday;
    	
    	private Date graduation;
    
    	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 String getRepassword()
    	{
    		return repassword;
    	}
    
    	public void setRepassword(String repassword)
    	{
    		this.repassword = repassword;
    	}
    
    	public int getAge()
    	{
    		return age;
    	}
    
    	public void setAge(int age)
    	{
    		this.age = age;
    	}
    
    	public Date getBirthday()
    	{
    		return birthday;
    	}
    
    	public void setBirthday(Date birthday)
    	{
    		this.birthday = birthday;
    	}
    
    	public Date getGraduation()
    	{
    		return graduation;
    	}
    
    	public void setGraduation(Date graduation)
    	{
    		this.graduation = graduation;
    	}
    
    	@Override
    	public String execute() throws Exception
    	{
    		System.out.println("execute invoked");
    		return SUCCESS;
    	}	
    }

    success.jsp如下:

    <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'success.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
    
      </head>
      
      <body>
        
        <table align="center" width="40%" border=1">
        		<tr>
        			<td>
        				username:
        			</td>
        				
        			<td>
        				${requestScope.username }
        			</td>
        		</tr>
        		
        		
        		<tr>
        			<td>
        				password:
        			</td>
        				
        			<td>
        				${requestScope.password }
        			</td>
        		</tr>
        
        		<tr>
        			<td>
        				age:
        			</td>
        				
        			<td>
        				${requestScope.age }
        			</td>
        		</tr>
        	
        	
        		<tr>
        			<td>
        				birthday:
        			</td>
        				
        			<td>
        				${requestScope.birthday }
        			</td>
        		</tr>
        		
        		
        		<tr>
        			<td>
        				graduation:
        			</td>
        				
        			<td>
        				${requestScope.graduation }
        			</td>
        		</tr>
        	</table>
     
        
      </body>
    </html>
    

    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="struts2" extends="struts-default">
    		
    			<action name="helloworld" class="com.test.action.HelloWorld">
    				<result name="success">/helloworld.jsp</result>
    			</action>
    			
    			<action name="login" class="com.test.action.LoginAction">
    				<result name="success">/result.jsp</result>
    				<result name="input">/login2.jsp</result>
    			</action>
    			
    			<action name="converterAction" class="com.test.action.PointAction" method="test">
    				<result name="success">/output.jsp</result>
    			</action>
    			
    			<action name="register" class="com.test.action.RegisterAction">
    				<result name="success">/success.jsp</result>
    				<result name="input">/register.jsp</result>
    			</action>
    		</package>
    	
    	
    	</struts>
    

    下面就是重头戏了,在和RegisterAction同包目录下建立RegisterAction-validation.xml文件,文件内容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!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="username">
    	
    		<field-validator type="requiredstring">
    			<param name="trim">true</param>
    			<message>username invalid</message>
    		</field-validator>
    	
    		<field-validator type="stringlength">
    			<param name="minLength">6</param>
    			<param name="maxLength">10</param>
    			<message>useranme should be between ${minLength} and ${maxLength}</message>
    		</field-validator>
    	
    	</field>
    	
    	
    	<field name="password">
    	
    		<field-validator type="requiredstring">
    			<param name="trim">true</param>
    			<message>password invalid</message>
    		</field-validator>
    	
    		<field-validator type="stringlength">
    			<param name="minLength">6</param>
    			<param name="maxLength">10</param>
    			<message>password should be between ${minLength} and ${maxLength}</message>
    		</field-validator>
    	
    	</field>
    	
    	
    	
    	<field name="repassword">
    	
    		<field-validator type="requiredstring">
    			<param name="trim">true</param>
    			<message>repassword invalid</message>
    		</field-validator>
    	
    		<field-validator type="stringlength">
    			<param name="minLength">6</param>
    			<param name="maxLength">10</param>
    			<message>repassword should be between ${minLength} and ${maxLength}</message>
    		</field-validator>
    	
    	</field>
    	
    	
    	
    	<field name="age">
    	
    		<field-validator type="required">
    			<message>age invalid</message>
    		</field-validator>
    	
    		<field-validator type="int">
    			<param name="min">1</param>
    			<param name="max">150</param>
    			<message>age should be between ${min} and ${max}</message>
    		</field-validator>
    	
    	</field>
    	
    	
    	
    	<field name="birthday">
    	
    		<field-validator type="required">
    			<message>birthday invalid</message>
    		</field-validator>
    	
    		<field-validator type="date">
    			<param name="min">2000-01-10</param>
    			<param name="max">2003-11-11</param>
    			<message>birthday should be between ${min} and ${max}</message>
    		</field-validator>
    	
    	</field>
    	
    	
    	
    	
    	<field name="graduation">
    	
    		<field-validator type="required">
    			<message>graduation invalid</message>
    		</field-validator>
    	
    		<field-validator type="int">
    			<param name="min">2005-01-10</param>
    			<param name="max">2008-11-11</param>
    			<message>graduation should be between ${min} and ${max}</message>
    		</field-validator>
    	
    	</field>
    
    </validators>
    

    注意的一点是这里的field-validator的type有"requiredstring"、"stringlength",param的name有minLength、trim、max等,我们是如何知道这些的呢?答案是:找到xwork-2.1.2.jar下的包com.opensymphony.xwork2.validator.validators,里面有一个配置文件叫做default.xml,打开看看你就明白了:

    根据这里的name就是我们校验的type,在该包下面找到对应的处理类,查看其get和set方法,我们就可以获悉param中的name的取值有哪些(getX,setX的后缀部分,因为这里利用的是反射的机制进行处理,因此处理类的属性可以和name的取值不同,但是方法名的后缀一定要相同)。

    此外,还有一种方式是校验器优先,他不同与我们上面的属性优先的方式:

    <!--校验器优先校验规则 -->
    
    	<validator type="requiredstring">
    		<param name="fieldName">username</param>
    		<message>username invalid</message>	
    	</validator>
    	
    	<validator type="stringlength">
    		<param name="fieldName">username</param>
    		<param name="minLength">6</param>
    		<param name="maxLength">10</param>
    		<message>username should be between ${minLength} and ${maxLength}</message>	
    	</validator>
    

    两者采用哪种方式均可,没有孰优孰劣之分。

    还有一种无所谓优劣之分的Action的实现方式:我们上面的使用的一直是一种叫做属性驱动Action的东东,其实还有一种模型驱动Action,他在属性值比较多的时候很有用,比如我们可以写一个RegisterAction2.java来代替RegisterAction.java(需要实现ModelDriven<T>这个泛型接口,并且实现其中的方法getModel()):

    package com.test.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    import com.test.bean.User;
    
    public class RegisterAction2 extends ActionSupport implements ModelDriven<User>
    {
    	private User user = new User();
    	
    	public User getModel()
    	{
    		return user;
    	}
    	
    	@Override
    	public String execute() throws Exception
    	{
    		return SUCCESS;
    	}
    }
    

    然后,在com.test.bean中建立User.java:

    package com.test.bean;
    
    import java.util.Date;
    
    public class User
    {
    private String username;
    	
    	private String password;
    	
    	private String repassword;
    	
    	private int age;
    	
    	private Date birthday;
    	
    	private Date graduation;
    
    	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 String getRepassword()
    	{
    		return repassword;
    	}
    
    	public void setRepassword(String repassword)
    	{
    		this.repassword = repassword;
    	}
    
    	public int getAge()
    	{
    		return age;
    	}
    
    	public void setAge(int age)
    	{
    		this.age = age;
    	}
    
    	public Date getBirthday()
    	{
    		return birthday;
    	}
    
    	public void setBirthday(Date birthday)
    	{
    		this.birthday = birthday;
    	}
    
    	public Date getGraduation()
    	{
    		return graduation;
    	}
    
    	public void setGraduation(Date graduation)
    	{
    		this.graduation = graduation;
    	}
    }
    

    多提一点:为了防止并发带来的问题,与Servlet不同的是Action对象是多实例的,一个请求对应一个Action对象。

    还有一个问题,就是基于用户界面友好性的要求,用户输入的信息应该保存起来,即让用户知道哪里错了,又让用户能在原有的基础上进行修改,如何做到这一点呢?可以利用struts2标签库:不仅内置了错误信息输出功能,而且有一个保留输入的提交信息这样的功能(当然处于安全性的考虑,密码没有保留)。因此对register.jsp做出如下修改即可:

    <body>
      	<s:form action="register">
      		<s:textfield name="username" label="username"></s:textfield>
      		<s:password name="password" label="password"></s:password>
      		<s:password name="repassword" label="repassword"></s:password>
      		<s:textfield name="age" label="age"></s:textfield>
      		<s:textfield name="birthday" label="birthday"></s:textfield>
      		<s:textfield name="graduation" label="graduation"></s:textfield>
      		
      		<s:submit value="submit"></s:submit>
      	</s:form>
      </body>
    

    当然,前提是要引入标签库:<%@ taglib uri="/struts-tags" prefix="s" %> 

    最后,如果即使用编码的方式进行校验,同时又用校验框架进行校验,结果会如何?校验流程如下:

    1. 首先执行类型转换
    2. 执行对应的校验框架(XML)
    3. 执行特定方法对应的validate验证(test,validateTest)
    4. 执行validate()方法

    如果在以上所有过程当中,发现了任何错误,都不再去执行execute方法或指定的特定方法(test),页面转向了struts.xml中input这个result所对应的页面。

  • 相关阅读:
    Delphi通过调用COM对象实现更改桌面壁纸
    Delphi之TDrawGrid绘制
    Delphi中的消息截获(六种方法:Hook,SubClass,Override WndProc,Message Handler,RTTI,Form1.WindowProc:=@myfun)good
    从一般管理原则看微软的重组
    Delphi使用Windows API函数AnimateWindow实现窗体特效
    Delphi下URL汉字编码解码的两个函数
    Delphi2007下CIS的clHttp使用
    Delphi使用XmlHttp获取时间
    提升进程权限为DEBUG权限
    VS 2012 单元测试简单配置
  • 原文地址:https://www.cnblogs.com/Code-Rush/p/4663898.html
Copyright © 2011-2022 走看看