一、如何在每次请求前进行统一的预处理:
1) 在struts-config.xml加入:
配置<controller processorClass="包名。类名" />
2) 派生requestProcessor类,并且覆盖其processPreprocess方法,下面是一个对IP做过滤的例子。
package classmate;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.RequestProcessor;
import org.apache.struts.config.ForwardConfig;
import org.apache.commons.logging.Log;
public class MyRequestProcessor extends RequestProcessor {
//派生requestProcessor类,并且覆盖其processPreprocess方法
public MyRequestProcessor() {}
protected boolean processPreprocess( HttpServletRequest request,
HttpServletResponse response ){
boolean continueProcessing = true;
String remoteHost = request.getRemoteHost( );
log.info( "Request from host: " + remoteHost );
// Make sure the host is from one that you expect
if (( remoteHost == null || !remoteHost.startsWith( "127."))){
// Not the localhost, so don't allow the host to access the site
continueProcessing = false;
try{
response.sendRedirect( "/S02_Extend/error.jsp");
}catch( Exception ex ){
log.error("Problem sending redirect from processPreprocess()") ;
}
}
return continueProcessing;
}
}
二、动态acitonform:
使用Dynaforms,我们应该更改customerForm在struts-config.xml中信息来使用org.apache.struts.action.DynaActionForm.。
1) 使用DynaActionForm,你可以利用form-property xml标签,它允许你在struts-config.xml中定义formbean的属性元素。以我们的例子来说,struts-config.xml中将是如下这个样子:
<form-bean name="dynaCustomerForm"
type="org.apache.struts.action.DynaActionForm">
<form-property name="lastName" type="java.lang.String"/>
<form-property name="firstName" type="java.lang.String"/>
<form-property type="java.lang.String" name="street"/>
<form-property name="city" type="java.lang.String"/>
<form-property name="state" type="java.lang.String"/>
<form-property name="postalCode" type="java.lang.String"/>
</form-bean>
2)对于原来的action进行稍微的改动应为:你现在已经不在向execute()中传递formbean(没有get set方法),所以 你应该把form转型到DynaActionForm,然后利用方法get(filename)来取得client端数据新的action代码如下:
文件类名:article1.AddDynaCustomerAction
----------------------------------------------------------------------------------------------------------------------
package article1;
import org.apache.struts.action.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
public class AddDynaCustomerAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException{
DynaActionForm custForm = (DynaActionForm) form; //定义动态acitonform
System.out.println("lastName = " + custForm.get("lastName"));
System.out.println("firstName = " + custForm.get("firstName"));
System.out.println("street = " + custForm.get("street"));
System.out.println("city = " + custForm.get("city"));
System.out.println("state = " + custForm.get("state"));
System.out.println("postalCode = " + custForm.get("postalCode"));
System.out.println("phone = " + custForm.get("phone"));
return mapping.findForward("success");
}
}
3)从上边的代码可以看出,似乎”屏蔽“了actionform,然而我们也“丢失”了一些其他的,譬如:严整输入合法性的问题。有两种方法可以恢复校验功能:一是创建一个DynaActionForm的子类,然后在子类中实现validate()方法。如下代码:
article1.DynaCustomerForm
package article1;
import org.apache.struts.action.*;
import javax.servlet.http.HttpServletRequest;
public class DynaCustomerForm extends DynaActionForm {
protected boolean nullOrBlank (String str) {
return ((str == null) || (str.length() == 0));
}
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (nullOrBlank((String)this.get("lastName"))) {
errors.add("lastName",
new ActionError("article1.lastName.missing"));
}
if (nullOrBlank((String)this.get("firstName"))) {
errors.add("firstName",
new ActionError("article1.firstName.missing"));
}
if (nullOrBlank((String)this.get("street"))) {
errors.add("street",
new ActionError("article1.street.missing"));
}
if (nullOrBlank((String)this.get("city"))) {
errors.add("city", new ActionError("article1.city.missing"));
}
if (nullOrBlank((String)this.get("state"))) {
errors.add("state",
new ActionError("article1.state.missing"));
}
if (nullOrBlank((String)this.get("postalCode"))) {
errors.add("postalCode",
new ActionError("article1.postalCode.missing"));
}
if (nullOrBlank((String)this.get("phone"))) {
errors.add("phone", new ActionError("article1.phone.missing"));
}
return errors;
}
}
如果是这样,我们就要更改struts-config.xml来使用DynaActionForm的子类,这样的效果似乎是又回到了先前的样子(为每一个表单写DynaActionForm)
三、Struts数据验证
1、 静态actionform验证:
1)struts-config增加红字部分:
<action path="/login" type="classmate.LoginAction" name="需要验证的actionform名称" scope="request" validate="true" input="/error.jsp" />
并且添加资源文件路径在最后一行:
<message-resources parameter="classmate.MyResource"/>
2)在对应的actionform里重载valide()方法:
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();//ActionMessages的子类
if ((name == null) || (name.equals(""))){
errors.add(ActionErrors.GLOBAL_MESSAGE,
new ActionMessage("error.name.required"));//见下资源文件
}
if((psw == null) || (psw.equals(""))){
errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("error.psw.required"));//显示出错信息
}
return errors;
}
3)资源文件添加错误描述:
《MyResource.properties》
# 这是一个简单属性文件,用于学习测试目的.
title.login = 登录界面
title.welcome = 欢迎,
title.failure = 抱歉,登录失败!
label.login = 请输入用户名和密码
label.deny = 您无权访问本页面!
item.submit = 提交
item.reset = 重置
item.user = 用户
item.password = 密码
link.relative = 友情链接
link.loginAgain = 重新登录
error.name.required = 用户名不能为空
error.psw.required = 密码不能为空
4)在调用的反映页面需要位置插入出错提示标签: <html:errors/>
2、 动态的可以适合多个同类性质页面的validator验证框架:
1) 修改struts-config四大主题:
A:动态页面宣布:
<form-bean name="registForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="name" type="java.lang.String"/>
<form-property name="psw1" type="java.lang.String"/>
<form-property name="psw2" type="java.lang.String"/>
</form-bean>
B:打开需要验证的所有ACTION标签的validate标志:
<action path="/login" type="classmate.LoginAction" name="formBean1" scope="request" validate="true" input="/error.jsp"/>
<action path="/registSubmit" type="classmate.RegistAction" name="registForm" scope="request" validate="true" input="/error.jsp"/>
C:资源文件引入<message-resources parameter="classmate.MyResource"/>
D:插入验证插件:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
<set-property property="stopOnFirstError" value="false"/>
</plug-in>
2)、配置对应的验证文件内容:
validator-rules.xml直接引入,不需要变动,有特殊要求修改validation.xml 比如要对registForm验证,在validation.xml 加入
<form name="registForm">
<field
property="name" //对页面html标识ID的指定
depends="required,maxlength">//指定了验证项目:非空验证,最大长度验证
<arg0 key="label.username"/> //key对应了资源文件的标签,显示错误来指定出错的地方
<arg1 key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>20</var-value>
</var>//var是对详细的指定
</field>
<field
property="psw1"
depends="required,validwhen,maxlength">
<arg0 key="label.password"/>
<arg1 key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>20</var-value>
</var>
<var>
<var-name>test</var-name>
<var-value>((psw2 ==*this*) and (*this* != null))</var-value>
</var>
</field>
</form>
3)创建资源文件在相应目录下,({0}代表第一个验证参数名{1}代表第二个验证参数名)
error.name.required = <li>用户名不能为空</li>
error.psw.required = <li>密码不能为空</li>
errors.required={0}不能为空
errors.minlength={0} 不能少于 {1} 个字符.
errors.maxlength={0} 不能多于 {1} 个字符.
errors.validwhen={0}不匹配
4)在页面显示错误提示插入出错提示标签: <html:errors/>