- 浏览: 321140 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
lst923:
...
java 实现图片裁剪 -
kakarottoz:
多谢博主分享,正好用到!
java 实现图片裁剪 -
Vcb:
http://osgi.jxtech.net 是一个完全基于O ...
OSGi介绍 -
Vcb:
是一个完全基于OSGi的开发平台,有在线演示,免费插件可供下 ...
OSGi介绍 -
mikey_5:
谢谢分享,原来设置: style="word-bre ...
td内容自动换行
好久不用这了,现在项目用到,回忆下struts1的基础
一 实例操作:
>>步骤1,导入相关的struts jar文件
>>步骤2,编写ActionForm 及Action.
|-ActionForm类用来获取http请求的相关参数。
|-Action类用来获取ActionServlet传递过来的参数,并调用相关的逻辑层。最后返回给总控制器ActinonServlet
>>步骤3,编写配置文件。 struts-config.xml及web.xml配置内容如下:
struts.xml:
<struts-config>
<form-beans >
<form-bean name="LoginForm" type="com.asm.LoginForm">
</form-bean>
</form-beans>
<action-mappings>
<action path="/login" type="com.asm.LoginAction" name="LoginForm">
<forward name="loginSuccess" path="/right.jsp"></forward>
<forward name="loginFailure" path="/error.jsp"></forward>
</action>
</action-mappings>
</struts-config>
web.xml:
<servlet>
<servlet-name>action</servlet-name>
<servlet-
class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
>>步骤4,编写相关的jsp文件
>>步骤5,布置到服务器中,测试
二 结合上例总述struts1.x执行流程:
1. 读取配置:初始化ModuleConfig对象。Struts框架总控制器(ActionServlet)是一个Servlet,我们在web.xml文件中配置成启动的Servlet。同时配置了struts-config.xml并在web.xml中指明了此配置的位置。也即是说,读取了struts-config.xml的配置信息。
2. 发送请求:用户提交表单或调用URI向Web应用程序提交一个请求,请求的数据用HTTP协议上传给Web服务器
3. 填充Form:结合上例,当派发的请求为*.do时,web服务器会提交给ActionServlet处理,(Servlet处理模式)。同样,在交由ActionServlet处理时,会读取到<init-param>下的配置struts-config.xml。从此配置文件中找到Action,而<action>中的属性name属性指定了这个Action所关取的ActionForm. ActonForm被实例化并用HTTP请求的数据填充其属性,并且保存在SevletContext(request或session)中,这样它们就可以被Action调用
4. 派发请求:完成Form填充后,ActionServlet会继续把这个请求及这个ActionForm(可以想成一个Bean)一并传给Action中的execute()方法。(可以在此方法中看到一个参数:ActionForm form. 而且在此方法中我们使用了LoginForm loginForm= (LoginForm)form;来进行强制转换,其目的就是为了得到ActionForm的子类的对象,以便后面可以直接获取这个实例所保存的属性)
5. 处理业务:简单的说,就是Action类(具体表现为它的子类)调用逻辑层进行相关处理。处理完成后会返回一个ActionForwad对象。
6. 返回响应:根据上一步返回的ActionForward对象并参照sturst.xml中的<action>下的<forward>来调用对应有jsp(或者是另一个Action)
7. 处理返回响应:根据上一步的找到jsp进行处理,并把处理结果返回给客户端
总结配置文件:
|- <form-beans>下的每个<form-bean>就对应于一个ActionForm子类(用type属性指明所对应的ActionForm)
|- <action-mappings>下的每一个<action>就对于一个Action子类,同样用type属性指明了对应的Action,并让name属性来关联相应的ActionForm
三 分析Action:
Action什么时候初始化?l 当发出该action请求时初始化(而并非在读取配置l时候) 每个Action只会初始化一次,也就意味着所有的请求共享一个action实例 --
>>Action是线程不安全的。 因而也就引了一个安全性编程的问题,怎样实现安全编程:1.注意不要使用实例变量或者类变量共享只是针对某个请求的数据;2.注意资源操作的同步性。 Action的不安全性应用:比如统计此Action被调用的次数
四 ActionMapping:
测试:在Action的execute方法中,我们增加如下代码进行测试:
String name=mapping.getName();
String path=mapping.getPath();
System.out.println("name=" + name +"\tpath" +path);
String [] forwardNames=mapping.findForwards();
for(String forwardName:forwardNames)
{
ActionForward forward=mapping.findForward
(forwardName);
String forwardPath=forward.getPath();
System.out.println("forward:" + forward +"\tforwardPath"+ forwardPath);
}
测试后的结果控制台结果为:
name=LoginForm path/login
forward:ForwardConfig[name=loginSuccess,path=/right.jsp,redirect=false,module=null,extends=null,catalog=null,command=null] forwardPath/right.jsp forward:ForwardConfig[name=loginFailure,path=/error.jsp,redirect=false,module=null,extends=null,catalog=null,command=null] forwardPath/error.jsp
分析:在配置文件中<action>即是一个org.apache.struts.action.ActionMapping类。path属性通过此类对象调用getPath()方法得到。同样name属性可以调用getName()方法得到 。而在此<action>配置下的<forward>也就是一个org.apache.struts.action.ActionForward类。而在上面的测试中,可以通过mapping.findForward()方法来得到一个ActionForward对象。
五 ActionForward
|-在<forward>中有两个常用属性:name作为Action类中返回的值的一个索引,结合path属性可以查找到跳转到的页面。
|-前面已经提到<forward>即是org.apache.struts.action.ActionForward类. 从这个类中我们可以知道还有两个属性:redirect:默认设为false,根据RequestDispatcher.forward 来进行跳转 如果在配置中设为true,则会HttpServletResponse.sendRedirect()来跳转。为了体现此属性:我们设置进行以下测试性配置:
<forward name="loginFailure" path="/error.jsp" redirect="true"></forward>
<forward name="Failure" path="www.qq.com" redirect="false"></forward>
<forward name="Failure" path="http://www.qq.com" redirect="false"></forward>
<forward name="Failure" path="http://www.qq.com" redirect="true"></forward>
结论: 1.设置redirect为true也是可以成功地完成RequestDispatcher.forward的服务器跳转。
2.如果要想用到HttpServletResponse.sendRedirect()这种跳转,除了要设置redirect的属性值为true外,还应为path属性指定一个绝对的路径(比如http://www.qq.com)。
六 ActionForm的工作原理:怎样完成填充ActionForm
1. 检查Action的映射,确定Action中已经配置了对应的ActionForm的映射
2. 根据name属性,查找form bean的配置信息
3. 检查Action 中form bean的使用范围(request|session),(也即是说<action>中的scope属性)确定此范围下,是否存在form bean的实例
4. 不存在这个实例,则重新构建一个实例,并且通过setAttribute()方法保存在scope所指定的作用范围内。存在则不需此步 补充说明:在这一步setAttrubute(“参数名-来自<action>或者是<form-bean>中的name属性值”,“值就是ActionForm子类对象”)。 后面的Action中的execute()方法中的参数ActionForm form也就是这里设置的值。
5. ActionForm bean的reset()方法被调用
6. 调用对应的setter()方法进行相关属性的赋值。实质完成了对ActionForm bean的填充。
7. 如果<action>中设置了validate属性为true(默认为true),会调用相应的validae方法进行校验,能正确校验则控制器将ActionForm作为参数传递给Action中的execute方法执行。
说明:上面提到的reset和validate方法必须经过重写才会有实质性的作用。关于reset()方法的具体用处,可以参照api
测试:在ActionForm中(实质是在它的子类中)增加它的构造方法,reset方法,validate方法及在相关的setXXX方法都使用用System.out.println()打印信息来验证它们的执行顺序
测试:在ActionForm的子类中,对属性的设置取决于setXXX而与其中的属性变量无关。比如,在表单中有一username参数,在提交后,我们通过setUsername来获取它的值。原理是:一旦提交表单,setUsername()方法会根据set后面的Username来关联username所对应的值作为这个方法的参数。可以通过对ActionForm子类中的相关进行修改来验证。
七 总结<action>属性:
说明:此属性位于<action-mappings>下,它实质是对应于org.apache.struts.action.ActionMapping类。因此它的属性都可以在该类的字段中找到。 值得一提的是此<action>如果取名成<action-mapping>将更助于理解。而在<form-beans>下设计的<form-bean>的取名就很合理。
1. path属性:
2. name/attribute属性:它们都是用来关联ActionForm类名。但是实质性起作用(实质性起作用的意思是在Action类的execute()方法中的ActionForm参数所关联的类是此属性所指定的类)的是attribute,而通常情况下我们不设此属性,因为它会自动把name属性的值获取作为它本身的值attribute,也即是说attrubute缺省值为name属性的值3. type属性:Action完整类名
4. scope属性:ActionForm bean的存储范围,我们可以通过以下代码scope的默认属性为session:
/* 验证默认的scope属性。
LoginForm loginRe=null;
LoginForm loginSe=null;
loginRe=(LoginForm) request.getAttribute("LoginForm");
loginSe=(LoginForm) request.getSession().getAttribute("LoginForm");
System.out.println("request得:"+loginRe+"======session得到:"+loginSe); */
5. validate属性:此属性是用来控制是否进行验证。缺省值true,即进行验证。但是我们在ActionForm子类中如果没重写此方法,它会调用ActionForm类本身的方法,而ActionForm类中的此方法只是返回一个null值,这样校验总是通过。因而要想实质性地校验,必须重写此方法。 如果我们不想校验,可以直接设其属性为false,这样即使我们重写了validate方法,也不会调用此方法进行验证。即是说不会执行此方法中的内容。
6. input属性:验证失败时,返回的页面在。此属性只有在validate=true 时有效。
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
System.out.println("validate()");
ActionErrors errors=new ActionErrors();
//注意以下两句:如果注释掉以下两句,校验也无实质性的作用,即顺利通过校验
ActionMessage message=new ActionMessage("errors");
errors.add("errors",message);
return errors;
}
然后,在<action>中增加validate="true" input="/errorInput.jsp"这两个属性。意为:如果该action所引用的ActionForm校验出错,将会返回input属性所指定的页面。 强调说明:要想input起作用,这里validate必须设为true,当然也可以不设,因为validate缺省的就是true.
八 全局跳转:
在<struts-config>元素下有一个<global-forwards>属性。此属性就是用来配置全局跳转的。比如进行如下配置:
<global-forwards>
<forward name="test" path="/test.jsp"></forward>
</global-forwards>
进行此配置,只要在Action的execute方法中返回的是return mapping.findForward("test");这样的形式,便能让页面跳转到test.jsp页面。理解实质:就是把全局下的<forward>配置信息增加到所有的<action>下。 比如这里就是把 <forwardname="test" path="/test.jsp"></forward>增加成:
<action path="/login" type="com.asm.LoginAction" name="LoginForm" >
<forward name="test" path="/test.jsp"></forward>
</action>
九 struts核心类
1. ActionServlet
2. ActionForm
3. Action
4. ActionForward
5. ActionMapping
知道这5个核心类后,我们可以试着来写一个模拟的struts,其中的核心实现就是ActionServlet.
十 struts标签库分析
1. bean (struts-bean.tld) - uri: http://struts.apache.org/tags-bean
|- define标签:Define a scripting variable based on the value(s) of thespecified bean property.
属性分析:结合两个实例,实例1 test.jspà
<%
request.setAttribute("username","jack");
%>
<bean:define id="username1" name="username" >
</bean:define>
usrname1:${username1}
分析:
id:定义这个新的bean的id值以便后面引用(比如后面的EL表达式就是引用的这个id值)name:旧的bean的存储名字(此名字就是request中设定的“username”属性)scope:指定旧的bean的查找范围,默认是PageContext。即是说会在此范围内查找这个bean。 toscope:指定新bean的存储范围,默认也是page。即是只能在当前页面引用。说明:关于以上属性,可以进行分别测试。需要说明的是,不建议指定旧bean的查找范围,因为默认为当前页,而这里如果默认找不到,它会依次向request,session,application查找。但是如果我们要查找指定的范围的旧bean,则可以设定scope属性。
实例2 àtest2.jsp
<%
User user=new User();
user.setUsername("admin");
user.setPassword("123");
request.setAttribute("user",user);
%>
<bean:define id="username" name="user" property="username" >
</bean:define>
<bean:define id="password" name="user" property="password" >
</bean:define>
username:${username}<br>
password:${password}
输出信息:
username:admin
password:123
userbean:com.asm.User@1461c98
分析:
property:有了上面的知识,这里就能很好理解这个属性,上例存储的是一个字串对象。而这里存储的是一个一般的bean对象,如果只凭id,而不设property它将打印出这个类的hash码信息。而用property设定这个bean类的属性,它将返回的是这个设定属性的值。补充:如果在一个define标签中定义两个prperty属性,后定义的将会覆盖前property属性。
User.java内容如下:典型的bean。
package com.asm;
public class User {
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;
}
}
同样这里强调:bean要加package语句,这样后面才可以引用。
|-write标签:Render the value of the specified bean property to the currentJspWriter.
实例 beanwrite.jsp
<%
User user=new User();
user.setUsername("admin");
user.setPassword("123");
request.setAttribute("user",user);
%>
<bean:write name="user" property="username"/><br>
<bean:write name="user" />
输入信息:
admin
com.asm.User@b56559
说明:name仍为关联bean对象名,property意为bean对象的属性
|-message标签:
使用步骤:
(1) 定义资源文件:
com.asm.ApplicationResources.properties
com.asm.ApplicationResources_zh_CN.properties
(2) 在struts-config中添加配置信息:
<message-resources parameter=”com.asm.ApplicationResources” key=”myKey”/>
(3) 页面中使用:
<bean:message bundle=”myKey” key=”username”/>
<bean:message bundle=”myKey” key=”password”/>
说明:配置资源文件,一般写在一个包下。比如上面的写在com.asm包中。而ApplicationRescources为资源文件的基名,后面加的_为具体的国际化国家语言代码。在配置文件中的parameter为基名。Key是为这个资源文件取的一个名字,以便后文件直接引用。在jsp页面中,key为资源文件的键名,以键名它会自动找到键值。 补充说明:最初写这个的时候忘记了在web.xml文件中配置ActionServlet,后来一运行发现“Module 'null' not found.” 这个问题其实在很多时候都会出现,所以出现此问题可以先看看配置文件是否配置了所需的模块 其它标签库的使用可以参照struts带的文档
十一 使用DynaActionForm自动填充Form
1. 在前面我们已经知道,ActionForm是用来获取表单提交过来的信息。而为了具体的处理,我们也会写一个ActionForm的子类作为表单数据的存储bean。 其实,我们也可以把数据填充到struts自带的动态From。这样就可以不必写ActionForm,但是却要为这个DynaActionFrom写好配置文件。
2. 实例演示:
test.jsp页面内容如下:
<form action="test.do" method=post>
username:<input type="text" name="username"><br>
age:<input type="text" name="age"><br>
birthday:<input type="text" name="birthday"><br>
<input type="submit" value="提交">
</form>
web.xml配置内容如下:
<servlet>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<servlet-name>action</servlet-name>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
struts-config.xml配置内容如下:
<struts-config>
<form-beans >
<form-bean name="dyna" type="org.apache.struts.action.DynaActionForm">
<form-property name="username" type="java.lang.String"></form-property>
<form-property name="age" type="java.lang.Integer"> </form-property>
<form-property name="birthday" type="java.sql.Date"> </form-property>
</form-bean>
</form-beans>
<action-mappings>
<action path="/test" type="com.asm.TestAction" name="dyna"></action>
</action-mappings>
</struts-config>
分析此配置:<form-bean>下的type不再是我们自己写的Form,而是struts的DyanActionForm。后面的<form-property>是对这个动态From进行的属性配置。注意的是里面的type属性必须是一个完整的包名,不能是简单类型(比如int类型,也必须写成Integer)。 理解这个配置:把DynaActionForm想成就是我们自己写的ActionForm,而<form-property>用来设定这个bean的属性就行了。
Action内容如下:
package com.asm;
import java.io.PrintWriter;
import java.sql.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
public class TestAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse
response)
throws Exception {
DynaActionForm dynaform=(DynaActionForm) form;
String username=(String) dynaform.get("username");
Date birthday=(Date) dynaform.get("birthday");
Integer age=(Integer) dynaform.get("age");
PrintWriter out=response.getWriter();
out.println(username+"\t"+age+"\t"+birthday);
return null; //这里返回null意为直接在本页面显示,不转向处理
}
}
说明:转成DynaActionForm后对象后,它调用get方法返回的是一个对象Object,由于bean中本身存储的是我们前面在<form-property>中写的对象类型。所以它进行强制转换成我们所写的对象类型。 补充说明:关于它的其它操作,可以参照DynaActionForm类的Api
出自:http://hi.baidu.com/asm_system/blog/item/723799eeaedf5a3fadafd51f.html
一 实例操作:
>>步骤1,导入相关的struts jar文件
>>步骤2,编写ActionForm 及Action.
|-ActionForm类用来获取http请求的相关参数。
|-Action类用来获取ActionServlet传递过来的参数,并调用相关的逻辑层。最后返回给总控制器ActinonServlet
>>步骤3,编写配置文件。 struts-config.xml及web.xml配置内容如下:
struts.xml:
<struts-config>
<form-beans >
<form-bean name="LoginForm" type="com.asm.LoginForm">
</form-bean>
</form-beans>
<action-mappings>
<action path="/login" type="com.asm.LoginAction" name="LoginForm">
<forward name="loginSuccess" path="/right.jsp"></forward>
<forward name="loginFailure" path="/error.jsp"></forward>
</action>
</action-mappings>
</struts-config>
web.xml:
<servlet>
<servlet-name>action</servlet-name>
<servlet-
class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
>>步骤4,编写相关的jsp文件
>>步骤5,布置到服务器中,测试
二 结合上例总述struts1.x执行流程:
1. 读取配置:初始化ModuleConfig对象。Struts框架总控制器(ActionServlet)是一个Servlet,我们在web.xml文件中配置成启动的Servlet。同时配置了struts-config.xml并在web.xml中指明了此配置的位置。也即是说,读取了struts-config.xml的配置信息。
2. 发送请求:用户提交表单或调用URI向Web应用程序提交一个请求,请求的数据用HTTP协议上传给Web服务器
3. 填充Form:结合上例,当派发的请求为*.do时,web服务器会提交给ActionServlet处理,(Servlet处理模式)。同样,在交由ActionServlet处理时,会读取到<init-param>下的配置struts-config.xml。从此配置文件中找到Action,而<action>中的属性name属性指定了这个Action所关取的ActionForm. ActonForm被实例化并用HTTP请求的数据填充其属性,并且保存在SevletContext(request或session)中,这样它们就可以被Action调用
4. 派发请求:完成Form填充后,ActionServlet会继续把这个请求及这个ActionForm(可以想成一个Bean)一并传给Action中的execute()方法。(可以在此方法中看到一个参数:ActionForm form. 而且在此方法中我们使用了LoginForm loginForm= (LoginForm)form;来进行强制转换,其目的就是为了得到ActionForm的子类的对象,以便后面可以直接获取这个实例所保存的属性)
5. 处理业务:简单的说,就是Action类(具体表现为它的子类)调用逻辑层进行相关处理。处理完成后会返回一个ActionForwad对象。
6. 返回响应:根据上一步返回的ActionForward对象并参照sturst.xml中的<action>下的<forward>来调用对应有jsp(或者是另一个Action)
7. 处理返回响应:根据上一步的找到jsp进行处理,并把处理结果返回给客户端
总结配置文件:
|- <form-beans>下的每个<form-bean>就对应于一个ActionForm子类(用type属性指明所对应的ActionForm)
|- <action-mappings>下的每一个<action>就对于一个Action子类,同样用type属性指明了对应的Action,并让name属性来关联相应的ActionForm
三 分析Action:
Action什么时候初始化?l 当发出该action请求时初始化(而并非在读取配置l时候) 每个Action只会初始化一次,也就意味着所有的请求共享一个action实例 --
>>Action是线程不安全的。 因而也就引了一个安全性编程的问题,怎样实现安全编程:1.注意不要使用实例变量或者类变量共享只是针对某个请求的数据;2.注意资源操作的同步性。 Action的不安全性应用:比如统计此Action被调用的次数
四 ActionMapping:
测试:在Action的execute方法中,我们增加如下代码进行测试:
String name=mapping.getName();
String path=mapping.getPath();
System.out.println("name=" + name +"\tpath" +path);
String [] forwardNames=mapping.findForwards();
for(String forwardName:forwardNames)
{
ActionForward forward=mapping.findForward
(forwardName);
String forwardPath=forward.getPath();
System.out.println("forward:" + forward +"\tforwardPath"+ forwardPath);
}
测试后的结果控制台结果为:
name=LoginForm path/login
forward:ForwardConfig[name=loginSuccess,path=/right.jsp,redirect=false,module=null,extends=null,catalog=null,command=null] forwardPath/right.jsp forward:ForwardConfig[name=loginFailure,path=/error.jsp,redirect=false,module=null,extends=null,catalog=null,command=null] forwardPath/error.jsp
分析:在配置文件中<action>即是一个org.apache.struts.action.ActionMapping类。path属性通过此类对象调用getPath()方法得到。同样name属性可以调用getName()方法得到 。而在此<action>配置下的<forward>也就是一个org.apache.struts.action.ActionForward类。而在上面的测试中,可以通过mapping.findForward()方法来得到一个ActionForward对象。
五 ActionForward
|-在<forward>中有两个常用属性:name作为Action类中返回的值的一个索引,结合path属性可以查找到跳转到的页面。
|-前面已经提到<forward>即是org.apache.struts.action.ActionForward类. 从这个类中我们可以知道还有两个属性:redirect:默认设为false,根据RequestDispatcher.forward 来进行跳转 如果在配置中设为true,则会HttpServletResponse.sendRedirect()来跳转。为了体现此属性:我们设置进行以下测试性配置:
<forward name="loginFailure" path="/error.jsp" redirect="true"></forward>
<forward name="Failure" path="www.qq.com" redirect="false"></forward>
<forward name="Failure" path="http://www.qq.com" redirect="false"></forward>
<forward name="Failure" path="http://www.qq.com" redirect="true"></forward>
结论: 1.设置redirect为true也是可以成功地完成RequestDispatcher.forward的服务器跳转。
2.如果要想用到HttpServletResponse.sendRedirect()这种跳转,除了要设置redirect的属性值为true外,还应为path属性指定一个绝对的路径(比如http://www.qq.com)。
六 ActionForm的工作原理:怎样完成填充ActionForm
1. 检查Action的映射,确定Action中已经配置了对应的ActionForm的映射
2. 根据name属性,查找form bean的配置信息
3. 检查Action 中form bean的使用范围(request|session),(也即是说<action>中的scope属性)确定此范围下,是否存在form bean的实例
4. 不存在这个实例,则重新构建一个实例,并且通过setAttribute()方法保存在scope所指定的作用范围内。存在则不需此步 补充说明:在这一步setAttrubute(“参数名-来自<action>或者是<form-bean>中的name属性值”,“值就是ActionForm子类对象”)。 后面的Action中的execute()方法中的参数ActionForm form也就是这里设置的值。
5. ActionForm bean的reset()方法被调用
6. 调用对应的setter()方法进行相关属性的赋值。实质完成了对ActionForm bean的填充。
7. 如果<action>中设置了validate属性为true(默认为true),会调用相应的validae方法进行校验,能正确校验则控制器将ActionForm作为参数传递给Action中的execute方法执行。
说明:上面提到的reset和validate方法必须经过重写才会有实质性的作用。关于reset()方法的具体用处,可以参照api
测试:在ActionForm中(实质是在它的子类中)增加它的构造方法,reset方法,validate方法及在相关的setXXX方法都使用用System.out.println()打印信息来验证它们的执行顺序
测试:在ActionForm的子类中,对属性的设置取决于setXXX而与其中的属性变量无关。比如,在表单中有一username参数,在提交后,我们通过setUsername来获取它的值。原理是:一旦提交表单,setUsername()方法会根据set后面的Username来关联username所对应的值作为这个方法的参数。可以通过对ActionForm子类中的相关进行修改来验证。
七 总结<action>属性:
说明:此属性位于<action-mappings>下,它实质是对应于org.apache.struts.action.ActionMapping类。因此它的属性都可以在该类的字段中找到。 值得一提的是此<action>如果取名成<action-mapping>将更助于理解。而在<form-beans>下设计的<form-bean>的取名就很合理。
1. path属性:
2. name/attribute属性:它们都是用来关联ActionForm类名。但是实质性起作用(实质性起作用的意思是在Action类的execute()方法中的ActionForm参数所关联的类是此属性所指定的类)的是attribute,而通常情况下我们不设此属性,因为它会自动把name属性的值获取作为它本身的值attribute,也即是说attrubute缺省值为name属性的值3. type属性:Action完整类名
4. scope属性:ActionForm bean的存储范围,我们可以通过以下代码scope的默认属性为session:
/* 验证默认的scope属性。
LoginForm loginRe=null;
LoginForm loginSe=null;
loginRe=(LoginForm) request.getAttribute("LoginForm");
loginSe=(LoginForm) request.getSession().getAttribute("LoginForm");
System.out.println("request得:"+loginRe+"======session得到:"+loginSe); */
5. validate属性:此属性是用来控制是否进行验证。缺省值true,即进行验证。但是我们在ActionForm子类中如果没重写此方法,它会调用ActionForm类本身的方法,而ActionForm类中的此方法只是返回一个null值,这样校验总是通过。因而要想实质性地校验,必须重写此方法。 如果我们不想校验,可以直接设其属性为false,这样即使我们重写了validate方法,也不会调用此方法进行验证。即是说不会执行此方法中的内容。
6. input属性:验证失败时,返回的页面在。此属性只有在validate=true 时有效。
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
System.out.println("validate()");
ActionErrors errors=new ActionErrors();
//注意以下两句:如果注释掉以下两句,校验也无实质性的作用,即顺利通过校验
ActionMessage message=new ActionMessage("errors");
errors.add("errors",message);
return errors;
}
然后,在<action>中增加validate="true" input="/errorInput.jsp"这两个属性。意为:如果该action所引用的ActionForm校验出错,将会返回input属性所指定的页面。 强调说明:要想input起作用,这里validate必须设为true,当然也可以不设,因为validate缺省的就是true.
八 全局跳转:
在<struts-config>元素下有一个<global-forwards>属性。此属性就是用来配置全局跳转的。比如进行如下配置:
<global-forwards>
<forward name="test" path="/test.jsp"></forward>
</global-forwards>
进行此配置,只要在Action的execute方法中返回的是return mapping.findForward("test");这样的形式,便能让页面跳转到test.jsp页面。理解实质:就是把全局下的<forward>配置信息增加到所有的<action>下。 比如这里就是把 <forwardname="test" path="/test.jsp"></forward>增加成:
<action path="/login" type="com.asm.LoginAction" name="LoginForm" >
<forward name="test" path="/test.jsp"></forward>
</action>
九 struts核心类
1. ActionServlet
2. ActionForm
3. Action
4. ActionForward
5. ActionMapping
知道这5个核心类后,我们可以试着来写一个模拟的struts,其中的核心实现就是ActionServlet.
十 struts标签库分析
1. bean (struts-bean.tld) - uri: http://struts.apache.org/tags-bean
|- define标签:Define a scripting variable based on the value(s) of thespecified bean property.
属性分析:结合两个实例,实例1 test.jspà
<%
request.setAttribute("username","jack");
%>
<bean:define id="username1" name="username" >
</bean:define>
usrname1:${username1}
分析:
id:定义这个新的bean的id值以便后面引用(比如后面的EL表达式就是引用的这个id值)name:旧的bean的存储名字(此名字就是request中设定的“username”属性)scope:指定旧的bean的查找范围,默认是PageContext。即是说会在此范围内查找这个bean。 toscope:指定新bean的存储范围,默认也是page。即是只能在当前页面引用。说明:关于以上属性,可以进行分别测试。需要说明的是,不建议指定旧bean的查找范围,因为默认为当前页,而这里如果默认找不到,它会依次向request,session,application查找。但是如果我们要查找指定的范围的旧bean,则可以设定scope属性。
实例2 àtest2.jsp
<%
User user=new User();
user.setUsername("admin");
user.setPassword("123");
request.setAttribute("user",user);
%>
<bean:define id="username" name="user" property="username" >
</bean:define>
<bean:define id="password" name="user" property="password" >
</bean:define>
username:${username}<br>
password:${password}
输出信息:
username:admin
password:123
userbean:com.asm.User@1461c98
分析:
property:有了上面的知识,这里就能很好理解这个属性,上例存储的是一个字串对象。而这里存储的是一个一般的bean对象,如果只凭id,而不设property它将打印出这个类的hash码信息。而用property设定这个bean类的属性,它将返回的是这个设定属性的值。补充:如果在一个define标签中定义两个prperty属性,后定义的将会覆盖前property属性。
User.java内容如下:典型的bean。
package com.asm;
public class User {
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;
}
}
同样这里强调:bean要加package语句,这样后面才可以引用。
|-write标签:Render the value of the specified bean property to the currentJspWriter.
实例 beanwrite.jsp
<%
User user=new User();
user.setUsername("admin");
user.setPassword("123");
request.setAttribute("user",user);
%>
<bean:write name="user" property="username"/><br>
<bean:write name="user" />
输入信息:
admin
com.asm.User@b56559
说明:name仍为关联bean对象名,property意为bean对象的属性
|-message标签:
使用步骤:
(1) 定义资源文件:
com.asm.ApplicationResources.properties
com.asm.ApplicationResources_zh_CN.properties
(2) 在struts-config中添加配置信息:
<message-resources parameter=”com.asm.ApplicationResources” key=”myKey”/>
(3) 页面中使用:
<bean:message bundle=”myKey” key=”username”/>
<bean:message bundle=”myKey” key=”password”/>
说明:配置资源文件,一般写在一个包下。比如上面的写在com.asm包中。而ApplicationRescources为资源文件的基名,后面加的_为具体的国际化国家语言代码。在配置文件中的parameter为基名。Key是为这个资源文件取的一个名字,以便后文件直接引用。在jsp页面中,key为资源文件的键名,以键名它会自动找到键值。 补充说明:最初写这个的时候忘记了在web.xml文件中配置ActionServlet,后来一运行发现“Module 'null' not found.” 这个问题其实在很多时候都会出现,所以出现此问题可以先看看配置文件是否配置了所需的模块 其它标签库的使用可以参照struts带的文档
十一 使用DynaActionForm自动填充Form
1. 在前面我们已经知道,ActionForm是用来获取表单提交过来的信息。而为了具体的处理,我们也会写一个ActionForm的子类作为表单数据的存储bean。 其实,我们也可以把数据填充到struts自带的动态From。这样就可以不必写ActionForm,但是却要为这个DynaActionFrom写好配置文件。
2. 实例演示:
test.jsp页面内容如下:
<form action="test.do" method=post>
username:<input type="text" name="username"><br>
age:<input type="text" name="age"><br>
birthday:<input type="text" name="birthday"><br>
<input type="submit" value="提交">
</form>
web.xml配置内容如下:
<servlet>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<servlet-name>action</servlet-name>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
struts-config.xml配置内容如下:
<struts-config>
<form-beans >
<form-bean name="dyna" type="org.apache.struts.action.DynaActionForm">
<form-property name="username" type="java.lang.String"></form-property>
<form-property name="age" type="java.lang.Integer"> </form-property>
<form-property name="birthday" type="java.sql.Date"> </form-property>
</form-bean>
</form-beans>
<action-mappings>
<action path="/test" type="com.asm.TestAction" name="dyna"></action>
</action-mappings>
</struts-config>
分析此配置:<form-bean>下的type不再是我们自己写的Form,而是struts的DyanActionForm。后面的<form-property>是对这个动态From进行的属性配置。注意的是里面的type属性必须是一个完整的包名,不能是简单类型(比如int类型,也必须写成Integer)。 理解这个配置:把DynaActionForm想成就是我们自己写的ActionForm,而<form-property>用来设定这个bean的属性就行了。
Action内容如下:
package com.asm;
import java.io.PrintWriter;
import java.sql.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
public class TestAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse
response)
throws Exception {
DynaActionForm dynaform=(DynaActionForm) form;
String username=(String) dynaform.get("username");
Date birthday=(Date) dynaform.get("birthday");
Integer age=(Integer) dynaform.get("age");
PrintWriter out=response.getWriter();
out.println(username+"\t"+age+"\t"+birthday);
return null; //这里返回null意为直接在本页面显示,不转向处理
}
}
说明:转成DynaActionForm后对象后,它调用get方法返回的是一个对象Object,由于bean中本身存储的是我们前面在<form-property>中写的对象类型。所以它进行强制转换成我们所写的对象类型。 补充说明:关于它的其它操作,可以参照DynaActionForm类的Api
出自:http://hi.baidu.com/asm_system/blog/item/723799eeaedf5a3fadafd51f.html
发表评论
-
hibernate集合映射inverse和cascade详解
2013-05-04 12:14 944网上转载,出处不详 1、到底在哪用cascade=" ... -
js取el中的map值及js replaceAll实现
2013-04-10 15:55 2245<% Map map = new HashMap(); ... -
Struts2返回结果类型
2013-04-03 15:35 966转自:http://blog.csdn.net/sleepin ... -
Hibernate实体注解
2013-04-03 15:29 1099转自:http://blog.csdn.net/sleepin ... -
eclipse jee + tomcat记要
2013-03-08 15:37 2775今天重新下了个eclipse-jee-helios-SR2-w ... -
Hibernate主键生成策略
2013-01-28 15:50 8621) assigned 主键由外部程 ... -
tomcat调整内存大小
2012-11-14 14:15 1006Tomcat6使用安装版本进行安装后,使用内存的调整无法利用修 ... -
jstl与 jsp脚本间的数据传递
2012-11-08 13:34 1046可能这个标题没有确切表达我的意思,直接说用处 后台把一个对象, ... -
spring RMI rmoting远程服务实例
2012-10-25 14:39 1384还没有测试,先留在这儿,转自http://www.walker ... -
hibernate条件查询
2012-08-15 10:43 12291. Criteria criteria = getSessi ... -
一个分号引发的"血案"
2012-08-14 16:29 1196我用hibernate的SQLQuery做查询,sql是拼出来 ... -
struts 文件下载
2012-07-19 11:17 917以下代码是struts1中的action中 一般下载有三种方式 ... -
struts1 forward 请求带参数
2012-07-18 10:40 1804如果action配置中,加了scope="reque ... -
A Different Object With The Same Identifier Value Was Already Associated With Th
2012-07-05 14:38 808getHibernateTemplate().merge(ob ... -
解压版Tomcat服务
2012-06-21 11:47 1372本文来自http://my.oschina.n ... -
Jboss的安装与使用
2012-06-21 11:48 11551、 安装 1.1、软件安 ... -
hibernate延迟加载
2012-06-21 11:47 998hibernate延迟加载问题是开发者使用hibernate时 ... -
tomcat + apache配置
2012-06-21 11:48 1145Apache的HTTPD是目前比较 ... -
jquery验证
2012-06-20 09:13 1286项目中时常会用到一些 ... -
web安全登陆
2012-06-20 09:08 1115首先在客户端向服务器端请求登录页面时,服务器端生成一个随机字符 ...
相关推荐
### Struts框架初始化详解 #### 一、Struts框架简介 Struts是一个开源的MVC(Model-View-Controller)架构实现,用于简化Java Web应用的开发过程。它基于Servlet和JSP技术来构建Web应用程序,能够帮助开发者更加...
以下将详细介绍Struts2的初始使用环境配置步骤。 首先,确保你已经安装了Java Development Kit (JDK)。JDK是开发Java应用的基础,你需要至少JDK 1.6或以上版本来支持Struts2。下载并安装JDK后,设置好系统环境变量`...
- 这告诉Struts在初始化时查找名为`ApplicationResources.properties`的资源包。 6. **控制器逻辑**: - 在Action类中,可以通过`ActionContext`获取当前的`Locale`,并根据它加载对应的资源包。然后,Action可以...
Action可以通过依赖注入的方式初始化,因此可以更容易地模拟出不同的测试场景。 #### 表单处理 - **Struts1**: 使用ActionForm来封装表单数据。ActionForm是一个JavaBean,负责验证和封装用户输入的数据。Struts1...
而 Struts2 Action 可以通过依赖注入进行初始化和测试,提高了测试的便利性。 5. **输入数据的处理**: - Struts1 使用 ActionForm 来捕获用户输入,ActionForm 必须继承基类,有时会造成额外的类定义。Struts2 则...
ActionServlet是Struts1的核心组件,它的生命周期分为初始化、拦截请求和销毁三个阶段。在初始化阶段,`init()`方法执行了一系列关键步骤: 1. `initInternal()`方法初始化内部资源,如国际化设置。它包含了英文和...
10. **生命周期管理**:Struts1框架管理ActionForm实例的生命周期,包括创建、初始化、处理请求、清理资源等步骤,确保了在多线程环境下的正确性。 通过这个"Struts1小demo",你可以实际操作这些概念,了解它们如何...
11. **生命周期管理**:Struts1.x对ActionForm对象的生命周期进行了管理,包括初始化、清理、创建和销毁等步骤,确保了内存的合理使用。 学习Struts1.x需要理解其设计理念,掌握配置文件的编写,熟练运用Action、...
- **Struts2** 提供了更好的测试支持,Action可以通过设置属性、初始化和调用方法进行单元测试,依赖注入使得测试更加简单。 7. **输入数据处理** - **Struts1.x** 使用ActionForm对象捕获用户输入,ActionForm...
2. **web.xml配置**:在Web应用的配置文件web.xml中,我们需要配置Struts1的前端控制器`org.apache.struts.action.ActionServlet`,并设置对应的初始化参数,如ActionServlet的映射路径和struts-config.xml的位置。...
在Struts1框架中,Digester用于解析struts-config.xml配置文件,将XML结构转换为相应的Java对象,初始化并配置Action、Form Beans等组件。 除了这些核心库,Struts1还需要其他JAR文件,如`struts-core.jar`(包含...
然而,有一个常见的问题出现在尝试初始化`java.util.Date`类型的字段时,即“Struts的form不能初始化java.util.Date类型”。这个问题通常是由于日期对象的序列化和反序列化机制导致的,以及Struts默认的数据绑定策略...
另外,`RequestProcessor`是Struts1处理请求的关键类,它负责初始化Action实例,并将请求分发给相应的Action。开发者可以自定义RequestProcessor以扩展其功能。 总的来说,Struts1 API帮助文档覆盖了框架的所有关键...
- **Struts2**: 在Struts2中,可以通过初始化、设置属性和调用方法等方式轻松地测试Action。依赖注入的支持进一步简化了测试过程,使开发者能够更加专注于逻辑验证而非环境配置。 #### 5. 输入数据的处理方式 - **...
1. **配置web.xml**:这是所有Java Web应用的部署描述符,我们需要在这里配置Struts1的初始化参数,包括ActionServlet和struts-config.xml的路径。 2. **编写struts-config.xml**:这是Struts1的配置文件,定义了...
- **Struts 2**:Action的测试更加简单直接,只需要初始化Action对象,设置所需的属性,然后调用`execute`方法即可完成测试。这种方式极大地提高了测试的效率和便利性。 #### 5. 封装请求参数的对比 - **Struts 1*...
然而,Struts2的Action可以通过依赖注入轻松地进行单元测试,Action的属性可以被初始化和设置,使得测试更加方便。 输入捕获机制也是两者之间的一个关键差异。Struts1使用ActionForm对象来收集表单数据,ActionForm...
- 在**Struts2**中,Action类通过初始化、拦截器等机制进行配置和扩展,这使得开发者可以更加灵活地控制请求的处理流程,而无需直接操作Servlet API。 #### ActionForm模式的变化 - **Struts1**采用ActionForm模式...