struts2后台ACTION中方法的执行顺序
后台ACTION类:
public class DownloadAction extends ActionSupport {
private String downloadFileName;
private String inputPath;
public DownloadAction(){
System.out.println("DownloadAction^^^^^^^^^^^^^^^^^^");
}
public void setInputPath(String value) {
inputPath = value;
}
public InputStream getInputStream() throws Exception {
String photoName=ActionContext.getContext().getSession().get("photoName").toString();
return ServletActionContext.getServletContext().getResourceAsStream ("\\files\\"+photoName);
}
public String execute() throws Exception {
return SUCCESS;
}
public String getDownloadFileName() {
System.out.println("getDownloadFileName^^^^^^^^^^^^^^^^^^^^^^");
this.downloadFileName=ActionContext.getContext().getSession().get("photoName").toString();
return downloadFileName;
}
public void setDownloadFileName(String downloadFileName) {
this.downloadFileName = downloadFileName;
}
public void validate(){
System.out.println("validate^^^^^^^^^^^^^^^^^^^^^^^^^^");
}
public String download(){
System.out.println("download^^^^^^^^^^^^^^^^^^^^^^");
return SUCCESS;
}
}
struts.xml中action的配置:
<action name="download" class="com.globalzt.struts2.action.DownloadAction" method="download">
<result name="success" type="stream">
<param name="contentType">image/jpg</param>
<param name="inputName">inputStream</param>
<!-- 使用经过转码的文件名作为下载文件名,downloadFileName属性对应action类中的方法 getDownloadFileName() -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
执行顺序:
DownloadAction^^^^^^^^^^^^^^^^^^
validate^^^^^^^^^^^^^^^^^^^^^^^^^^
download^^^^^^^^^^^^^^^^^^^^^^
getDownloadFileName^^^^^^^^^^^^^^^^^^^^^^
由此可见,其执行顺序为:
1.构造函数
2.验证函数
3.目标函数
4.属性的get方法
补充:
如果重写了父类的excute()方法,那么如果指定了触发的ACTION,则不执行该excute()函数。
原文出处:http://code.iteye.com/blog/277677
上图中的“分流”是指根据我们所请求的url把request交给某个指定的action来处理。那么在这个FilterDispatcher中还有一些什么操作呢?在Struts1中我们经常要把一个ActionForm和一个Action相关联,ActionForm中封装了表单的所有值,并且这些都是在ActionServlet中完成的,因此我们在action中可以直接通过ActionForm得到表当中的值,那么Struts2中又是怎么做的呢?我们怎么取得那些值呢?我发现可以这么做:对表单中每一个要获取的值,在action中相应添加这样的一个域,然后再设置相应的set和get方法,即采用javabean风格,貌似这个现在比较流行。比方说在前面的例子中,在sayHello.jsp的表单中有一个文本域,它的name=”name”,在我的action文件HelloWorld.java中有一个域private String name;同时还分别设置了相应的setName和getName方法,现在我把setName方法改为如下:
public void setName(String name) {
System.out.println("name:"+name);
this.name = name;
}
OK,在浏览器中输入http://localhost:8888/Struts/sayHello.jsp,这时我们发现后台打印出了name:CMTobby,CMTobby是我输入的name的值,这说明setName方法被执行了,奇怪啊,我们根本没有显式的调用这个方法啊,它是什么时候调用的呢?现在我们在setName方法里面设置一个断点,然后再在execute方法里面设置一个断点,再次运行我们的程序,结果显示setName方法在execute方法前面执行。
接着,无聊的我又做了一些测试:
1.把setName改为setName1,结果页面输出:Hello null,并且setName1为执行
2.在sayHello.jsp的form之外加了一个文本框,取名address,在HelloWorld中增加相应的域address、setAddress方法和getAddress方法,通过断点测试发现,setAddress方法不会执行。
基于以上测试,我认为在执行action的操作之前,首先会根据请求页面的form表当中所包含的参数来调用action中相应的set****方法,比如说,本例中,form中有name属性,因此会在执行execute之情调用setName方法,而address因为不在form中所以不会调用setAddress方法.
在处理完请求之后如何把用户所请求的值回传到结果页面当中呢?在HelloWorld.jsp中我们用了<s:property value="name" />,嘿嘿,难道又是隐式的调用了getName方法吗?于是我在HelloWorld.java的getName方法处设置了一个断点,再次运行我们的程序,果然getName被隐式的调用了。
此外如果我把<s:property value="name" />中value的值改为别的如name1,这时页面出错,一片空白。我接着又把getName方法改为getName1,这时页面仍然一片空白,因为取不到name属性的值。如果我把<s:property value="name" />改为
<s:property value="name1" />,同时也把getName改为getName1,那么显示就正常了,这个表明框架会根据属性的名字去调用相应的get方法。
上述机制是不是和我们前面所讨论的BeanUtils的copyProperties方法一样,实际上很多ORM框架都采用的这个机制,都是首先得到属性名再调用相应的set或者get方法,而不是直接访问的域。
本文来自CSDN博客:http://blog.csdn.net/CMTobby/archive/2007/07/26/1710368.aspx
后台ACTION类:
public class DownloadAction extends ActionSupport {
private String downloadFileName;
private String inputPath;
public DownloadAction(){
System.out.println("DownloadAction^^^^^^^^^^^^^^^^^^");
}
public void setInputPath(String value) {
inputPath = value;
}
public InputStream getInputStream() throws Exception {
String photoName=ActionContext.getContext().getSession().get("photoName").toString();
return ServletActionContext.getServletContext().getResourceAsStream ("\\files\\"+photoName);
}
public String execute() throws Exception {
return SUCCESS;
}
public String getDownloadFileName() {
System.out.println("getDownloadFileName^^^^^^^^^^^^^^^^^^^^^^");
this.downloadFileName=ActionContext.getContext().getSession().get("photoName").toString();
return downloadFileName;
}
public void setDownloadFileName(String downloadFileName) {
this.downloadFileName = downloadFileName;
}
public void validate(){
System.out.println("validate^^^^^^^^^^^^^^^^^^^^^^^^^^");
}
public String download(){
System.out.println("download^^^^^^^^^^^^^^^^^^^^^^");
return SUCCESS;
}
}
struts.xml中action的配置:
<action name="download" class="com.globalzt.struts2.action.DownloadAction" method="download">
<result name="success" type="stream">
<param name="contentType">image/jpg</param>
<param name="inputName">inputStream</param>
<!-- 使用经过转码的文件名作为下载文件名,downloadFileName属性对应action类中的方法 getDownloadFileName() -->
<param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
执行顺序:
DownloadAction^^^^^^^^^^^^^^^^^^
validate^^^^^^^^^^^^^^^^^^^^^^^^^^
download^^^^^^^^^^^^^^^^^^^^^^
getDownloadFileName^^^^^^^^^^^^^^^^^^^^^^
由此可见,其执行顺序为:
1.构造函数
2.验证函数
3.目标函数
4.属性的get方法
补充:
如果重写了父类的excute()方法,那么如果指定了触发的ACTION,则不执行该excute()函数。
原文出处:http://code.iteye.com/blog/277677
上图中的“分流”是指根据我们所请求的url把request交给某个指定的action来处理。那么在这个FilterDispatcher中还有一些什么操作呢?在Struts1中我们经常要把一个ActionForm和一个Action相关联,ActionForm中封装了表单的所有值,并且这些都是在ActionServlet中完成的,因此我们在action中可以直接通过ActionForm得到表当中的值,那么Struts2中又是怎么做的呢?我们怎么取得那些值呢?我发现可以这么做:对表单中每一个要获取的值,在action中相应添加这样的一个域,然后再设置相应的set和get方法,即采用javabean风格,貌似这个现在比较流行。比方说在前面的例子中,在sayHello.jsp的表单中有一个文本域,它的name=”name”,在我的action文件HelloWorld.java中有一个域private String name;同时还分别设置了相应的setName和getName方法,现在我把setName方法改为如下:
public void setName(String name) {
System.out.println("name:"+name);
this.name = name;
}
OK,在浏览器中输入http://localhost:8888/Struts/sayHello.jsp,这时我们发现后台打印出了name:CMTobby,CMTobby是我输入的name的值,这说明setName方法被执行了,奇怪啊,我们根本没有显式的调用这个方法啊,它是什么时候调用的呢?现在我们在setName方法里面设置一个断点,然后再在execute方法里面设置一个断点,再次运行我们的程序,结果显示setName方法在execute方法前面执行。
接着,无聊的我又做了一些测试:
1.把setName改为setName1,结果页面输出:Hello null,并且setName1为执行
2.在sayHello.jsp的form之外加了一个文本框,取名address,在HelloWorld中增加相应的域address、setAddress方法和getAddress方法,通过断点测试发现,setAddress方法不会执行。
基于以上测试,我认为在执行action的操作之前,首先会根据请求页面的form表当中所包含的参数来调用action中相应的set****方法,比如说,本例中,form中有name属性,因此会在执行execute之情调用setName方法,而address因为不在form中所以不会调用setAddress方法.
在处理完请求之后如何把用户所请求的值回传到结果页面当中呢?在HelloWorld.jsp中我们用了<s:property value="name" />,嘿嘿,难道又是隐式的调用了getName方法吗?于是我在HelloWorld.java的getName方法处设置了一个断点,再次运行我们的程序,果然getName被隐式的调用了。
此外如果我把<s:property value="name" />中value的值改为别的如name1,这时页面出错,一片空白。我接着又把getName方法改为getName1,这时页面仍然一片空白,因为取不到name属性的值。如果我把<s:property value="name" />改为
<s:property value="name1" />,同时也把getName改为getName1,那么显示就正常了,这个表明框架会根据属性的名字去调用相应的get方法。
上述机制是不是和我们前面所讨论的BeanUtils的copyProperties方法一样,实际上很多ORM框架都采用的这个机制,都是首先得到属性名再调用相应的set或者get方法,而不是直接访问的域。
本文来自CSDN博客:http://blog.csdn.net/CMTobby/archive/2007/07/26/1710368.aspx