信息恢复,未来是属于我的

今天是Struts的最后一部分,总的来说,并不是很难,因为这是把我们之前学习的内容简单的更新了下而已,但是从我自己的角度来看,我觉得Struts本身确实存在了很多的开发问题,老师讲解的时候也着重说了这些,从所有的学习来看,这段时间的学习应该是最轻松的,从开始学习一个个小的知识点,再到树立正确的开发思想,这段时间确实比较辛苦,而一但做了第一个项目之后,就发现许多的知识都能熟练了,看来MLDN的课程安排的确实非常的合理,因为从Struts的使用上就可以发现,我只要再用两天就能把Struts搞到精通的状态了,所以我觉得以后的学习也没问题。


今天所讲的知识点
A Struts的ForwardAction
B Struts的Token
C Struts的动态Form
D Struts的验证框架


我对知识点的分析
A Struts的ForwardAction
有的时候您只是想要从一个页面或资源转换到另一个资源,在MVC/Model 2的架构中,直接使用页面或资源的路径来跳转并不是一个好的主意,这会使得控制器没有机会处理相关的请求事宜,总是由Action调用JSP是个好习惯。 您仍应该通过控制器,使用ForwardAction可以帮您完成这个事情,当控制器使用ForwardAction的perform()方法时,它会使用属性parameter所设定的路径进行forward的动作,一个设定ForwardAction的例子如下:
代码:
        <action
             path="/Welcome"
             type="org.apache.struts.actions.ForwardAction"
             parameter="/pages/Welcome.jsp"/>
ForwardAction是唯一可以不使用ActionForm的Action,用来完成跳转,也只能完成跳转,这样做遵循了MVC的规范,并且隐藏了目标地址。
ForwardAction只需要在struts-config.xml中配置就可以了,而不需要真正的创建Action类和ActionForm类。
<action path="/forward"
type="org.apache.struts.actions.ForwardAction" parameter="/insert.jsp"></action>
其中parameter表示自动跳出的路径
修改跳转路径:
原来
<a href="index.jsp">插入功能</a>
修改为:
<a href="forward.do">插入功能</a>

B Struts的Token
struts如何解决重复提交问题?使用Token指令牌:
☆就是在进入表单页面之前,先通过<a href="mytoken.do"></a>进入一个Action,在该Action中设置一个Token指令   (this.saveToken(request)),然后再进入表单页面,在表单页面的Action中先检查Token指令是否被设置 (this.isTokenValidat(request)),是则再执行打印,打印完之后记得还要取消Token指令牌设置 (this.resetToken(request))。

Struts的Token的工作原理,Token是一个设置在session范围内的属性,在进入插入或修改等页前先设置指令牌,将产生的值传递到页面,自动在表单中隐藏域保存,当表单提交后,对提交的token值与session中的token值比较,如果相等可以提交,如果不等或没有提交的token值,应该提示错误(不能重复提交)
示例:
进入插入页面前,先在Action中设置指令牌
public ActionForward insertpre(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
UserForm userForm = (UserForm) form;// TODO Auto-generated method stub
// 设置指令牌
this.saveToken(request);
return mapping.findForward("insert");
}
配置插入的跳转路径
<action attribute="userForm" input="/error.jsp" name="userForm"
path="/user" scope="request" parameter="status"
type="org.liky.struts.action.UserAction">
<forward name="list" path="/list.jsp"></forward>
<forward name="forward" path="/forward.jsp"></forward>
<forward name="update" path="/update.jsp"></forward>
<forward name="insert" path="/insert.jsp"></forward>
</action>
页面上如果使用了html:form,则自动会将token值设置为隐藏域
public ActionForward insert(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {

UserForm userForm = (UserForm) form;// TODO Auto-generated method stub

if (this.isTokenValid(request)) {

boolean flag = false;
try {
flag = DAOFactory.getUserDAOInstance().doCreate(
userForm.getUser());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (flag) {
// 当数据插入到数据库后再进行文件保存
// 判断是否有文件
if (!userForm.getUser().getPhoto().equals("no_photo.jpg")) {
// 定义输出流
try {
FileOutputStream os = new FileOutputStream(new File(
this.getServlet().getServletContext()
.getRealPath("/")
+ "upload/"
+ userForm.getUser().getPhoto()));
// 进行文件保存

os.write(userForm.getPhoto().getFileData());
// 关闭
os.close();

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}

request.setAttribute("message", flag ? "插入成功!" : "插入失败!");
request.setAttribute("path", "/user.do?status=list");


// 重置Token
this.resetToken(request);

} else {
//提示不得重复提交
ActionMessages errors = new ActionMessages();
errors.add("sub", new ActionMessage("sub.err"));
this.saveErrors(request, errors);
return mapping.getInputForward();
}

return mapping.findForward("forward");
}

C Struts的动态Form
一、DynaActionForm类的引入
使用ActionForm可以给开发者在处理HTML表单上带来极大的帮助。它简化了代码编写,并提供了自动的数据验证。但是,ActionForm也存在几个非常明显的缺点。

首先,如果ActionForm对应的HTML表单添加或删除属性,ActionForm类就可能需要修改并重新编译;其次,如果HTML表单是动态的,那么ActionForm更是无能为力了;另外,ActionForm增加了一个项目中类的绝对数量。

从Struts1.1开始对这些不足进行了改进,引入了动态ActionForm(DynaActionForm)的概念。动态ActionForm允许用户无须为应用程序的每一个HTML表单创建具体的ActionForm类。Struts框架包中的DynaActionForm类及其子类实现了动态ActionForm。DynaActionForm类扩展了ActionForm类。用户可以直接使用DynaActionForm类,或者扩展该类以覆盖其validate()和reset()方法。

二、配置动态ActionForm
1、
动态ActionForm支持在Struts配置文件struts-config.xml中完成ActionForm的全部配置,无须编写任何额外的Java代码。对DynaActionForm来说,在Struts配置文件struts-config.xml中,<form-bean>元素的type属性设置为DynaActionForm或其子类,并在<form-bean>中包含一系列<form-property>子元素来标记动态表单的属性。
例如:
<form-beanname="loginActionForm"type="org.apache.struts.action.DynaActionForm">
<form-property name="username" type="java.lang.String"/>
<form-property name="password" type="java.lang.String"/>
</form-bean>

<form-bean>元素的type属性指定使用Struts框架包中的DynaActionForm类,用户也可以扩展这个类,实现自定义的动态ActionForm。
<form-property>元素的name属性指定了ActionForm中的属性名,type属性指定了属性类型。其中属性类型必须是标准的Java类,即当属性类型是int、long、float、double、boolean等这些基本数据类型时,要使用它们的包装类,即要使用Integer、Long、Float、Double和Boolean类。
2、
使用动态ActionForm,当需要添加新的属性时,只需要修改配置文件,无须更改源代码,这样便提供了巨大的功能和灵活性。<form-property>元素允许用户为每一个属性指定初始值。Struts框架在应用程序启动时将这些属性设置为这些值。
3、
在默认情况下,DynaActionForm类的reset()方法调用基类ActionForm的reset()方法。如果想要在每次调用reset()方法时,将所有属性设置到初始状态,就需要定义一个扩展DynaActionForm类的子类,覆盖其reset()方法,在reset()方法中将所有属性复位到初始状态。但是,用户不必在子类的reset()方法中编写冗长的属性复位代码,DynaActionForm类的initialize()方法已经为用户做了这些工作,用户要做的只是在reset()方法中调用initialize()方法。Initialize()方法把表单的所有属性恢复为默认值。表单属性的默认值由<form-bean>元素的<form-property>子元素的initial属性指定。如果没有为<form-property>指定initial属性,则属性的默认值应由相应的Java类型自动决定。例如整型将复位为0,布尔型复位到false,字符串等对象复位到null。

示例:
1、建立注册页面
2、动态ActionForm


建立后,在struts-config.xml中配置的ActionForm里,加入了form-property属性,通过该属性设置了所有ActionForm中保存的内容
<form-beans>
<form-bean name="registForm"
type="org.apache.struts.action.DynaActionForm">
<form-property name="password" type="java.lang.String" />
<form-property name="age" type="java.lang.String" />
<form-property name="userid" type="java.lang.String" />
<form-property name="email" type="java.lang.String" />
<form-property name="birthday" type="java.lang.String" />
</form-bean>
</form-beans>


三、在Action中访问动态ActionForm

同普通ActionForm一样,Action类和JSP都可访问动态ActionForm,而访问方法也基本一致。访问动态ActionForm与访问普通ActionForm的最大区别在于对属性的访问方式不同。在标准ActionForm中,针对每个属性都提供了getter和setter方法,来读取和设置属性。而DynaActionForm把所有的属性保存在一个Map对象中,因此访问DynaActionForm中的属性与访问Map对象中的方法类似:
public Object get(String name)
public void set(String name, Object value)

例如,在前面的登录系统的loginAction中访问一个名为loginActionForm的动态ActionForm的方法为:
//从Form Bean中取出表单数据
DynaActionForm loginActionForm = (DynaActionForm)form
String username = (String)loginActionForm.get("username");
String password = (String)loginActionForm.get("password");

示例:在Action中可以通过getString等方法接收参数
获得对象直接用get()
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
DynaActionForm registForm = (DynaActionForm) form;// TODO Auto-generated method stub

String userid = registForm.getString("userid");
System.out.println(userid);


return null;
}


四、动态ActionForm的表单验证
DynaActionForm类的validate()方法没有提供任何默认的验证行为。可以通过定义扩展DynaActionForm类的子类,然后覆盖validate()方法,但是以编程的方式来验证动态ActionForm并不是一个理想的策略。动态ActionForm的验证应该使用Struts的Validator验证插件。Validator插件允许采用特定的配置文件为动态ActionForm配置验证规则,如检查必需的输入域、日期和时间等。

D Struts的验证框架
Struts1.1及以上版本,在提供了动态ActionForm的同时,配合数据验证的需要,还提供了表单输入自动验证的功能,即使用Validator验证框架。

Validator验证框架是通过配置验证规则实现验证功能的,开发人员不需要编写代码,同时也能够最大限度重用同一个验证规则。因此,这种验证方式在目前的Struts应用中得到了广泛的应用。

1、如果要使用验证框架,必须配置一个struts插件,在struts-config.xml中
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/WEB-INF/validator-rules.xml"/>
</plug-in>
2、该类用来处理动态验证功能,处理时需要一个验证规则配置文件,该文件在加入Struts支持时,已经加入了,保存在WEB-INF下,因此将该文件路径配置到pathnames属性中
3、修改动态Form的类型或创建一个动态验证非Form
<form-beans>
<form-bean name="registForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="password" type="java.lang.String" />
<form-property name="age" type="java.lang.String" />
<form-property name="userid" type="java.lang.String" />
<form-property name="email" type="java.lang.String" />
<form-property name="birthday" type="java.lang.String" />
</form-bean>
</form-beans>
4、修改Action中Form的转换类型
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
DynaValidatorForm registForm = (DynaValidatorForm) form;// TODO Auto-generated method stub

String userid = registForm.getString("userid");
System.out.println(userid);


return null;
}
5、配置错误规则及并在资源文件中配置错误提示信息
非空验证:
<formset>
<form name="registForm">
<field property="userid" depends="required">
<arg key="userid.msg"/>
</field>
<field property="password" depends="required">
<arg key="password.msg"/>
</field>
</form>
</formset>
为了防止错误信息重复,配置参数进行错误信息处理
errors.required=<li>{0} is Required!

userid.msg=Userid
password.msg=Password
增加最小长度验证
<formset>
<form name="registForm">
<field property="userid" depends="required,minlength">
<arg0 key="userid.msg"/>
<arg1 key="minlength.msg"/>
<var>
<var-name>minlength</var-name>
<var-value>6</var-value>
</var>
</field>
<field property="password" depends="required">
<arg key="password.msg"/>
</field>
</form>
</formset>
其中var表示设置的要验证的最小长度值,而arg设置的显示的数据参数值
errors.required=<li>{0} is Required!
errors.minlength=<li>{0} can not be less than {1} characters.
errors.email=<li>{0} is an invalid e-mail address.


userid.msg=Userid
password.msg=Password
email.msg=Email

minlength.msg=6
增加email验证
errors.required=<li>{0} is Required!
errors.minlength=<li>{0} can not be less than {1} characters.
errors.email=<li>{0} is an invalid e-mail address.


userid.msg=Userid
password.msg=Password
email.msg=Email

minlength.msg=6

你可能感兴趣的:(框架,mvc,xml,struts,OS)