`
jslfl
  • 浏览: 313175 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

struts1 初始化

阅读更多
好久不用这了,现在项目用到,回忆下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
分享到:
评论

相关推荐

    探讨Struts的初始化方法

    探讨Struts的初始化方法

    Struts1与Struts2本质区别

    1 在Action实现类方面的对比:Struts 1要求Action类继承一个抽象基类;Struts 1的一个具体问题是使用抽象类编程而不是接口。Struts 2 Action类可以实现一...Struts 2 Action可以通过初始化、设置属性、调用方法来测试。

    struts1面试题

    struts1面试题对于采用Struts框架的Web应用,在Web应用启动时就会加载并初始化控制器ActionServlet ActionServlet从struts-config.xml文件中读取配置信息,把它们存放到ActionMappings对象中。

    Struts2中实现web应用的初始化实例详解

    Struts2中实现web应用的初始化实例详解 在JavsSE中,main方法为应用提供了入口,而在Android中,我们可以使用Application对于整个应用的生命周期进行管理,那么在基于Struts2的JavaEE应用中,如何实现类似的功能呢。...

    Struts2.3.8 Spring 3.2 Hibernate4.1.9 集成,初始化、定时器示例

    1,实现最新版本的Struts2.3.8 Spring 3.2 Hibernate4.1.9 集成 2,网站启动初始化,定时器执行代码 3,实现CRUD示例

    精通Java EE项目案例--基于Eclipse Spring Struts Hibernate (例子中的初始化SQL)

    这是这本书中所有的数据库初始化语句,这样,整本书的教程都已经上传完了,祝你学习愉快!

    Struts2.3.8 Spring3.2 Hibernate4.1.9 集成,初始化、定时器示例方法1(修正版)

    2,网站启动初始化,定时器执行代码 3,实现CRUD示例 此代码是对 http://download.csdn.net/detail/net_lover/4954763 的修正,不要再下载 http://download.csdn.net/detail/net_lover/4954763 的资源了。

    struts2技术内幕+struts2权威指南

    《Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的...运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象

    struts的form不能初始化java.util.Date类型

    NULL 博文链接:https://maserkinger.iteye.com/blog/719937

    struts2 技术内幕——深入解析struts2架构设计

    《Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的...运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。

    Struts2 技术内幕-深入解析Struts2架构设计与实现原理

    内容简介 出版日期: 2012年1月10日 《Struts2技术内幕:深入解析Struts2架构...运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。

    Struts2执行流程

    Struts2执行流程 1. web.xml 部署描述符 ...每个过滤器访问一个FilterConfig对象从中获取初始化参数,一个引用到ServletContext可以被使用,例如,在过滤器任务需要时装载资源.过滤器的配置在Web应用程序的部署描述符中.

    struts2源码

    struts2源代码及API帮助文档。...跟读struts2源码的时候注意两条主线:一条是初始化;另外一条是监听http请求。学习初始化过程是如何获取配置构造容器,其中的巧妙构思和设计模式的运用非常值得学习。

    struts1 源码

    struts1 的初始化和处理流程源码 1.initInternal(),处理资源绑定,返回一个MessageResources类实例 2.initOther(),初始化其它的全局描述符。 。、、、、、、

    Struts2技术内幕.pdf

    本书由国内极为资深的Struts2技术专家(网名:downpour)亲自执笔,iteye兼...运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。

    uploadify3与struts2结合实现有进度条文件上传实例

    3 上传大文件问题 若文件太大可以设置以下步骤:1)初始化参数successTimeout处配置时间长点;2) 修改struts xml 添加struts multipart maxSize的配置;3) 修改服务器端可上传文件大小的限制 在文件 usr local ...

    Struts源代码阅读.CHM

    Struts 初始化 initInternal()方法: initOther()方法 initServlet()方法 getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this) ModuleConfig moduleConfig = ...

    Struts2的工作原理和流程

    1 客户端初始化一个指向Servlet容器的请求; 2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh ...

Global site tag (gtag.js) - Google Analytics