zoukankan      html  css  js  c++  java
  • struts复习大纲

    一、struts概述

    1、Struts实现MVC设计模式
    (1)Struts实质上就是在JSPModel2的基础山实现一个MVC框架。
         1)模型:由业务实现业务逻辑的JavaBean或EJB组件构成
         2)控制器:由ActionServlet和Action来实现
         3)视图:由一组JSP文件构成
    (2)Struts的结构:
     
    2、Struts的工作流程
    (1)Web应用启动时加载并初始化ActionServlet,ActionServlet从struts-config.xml中读取配置信息,把它们存放到各种配置对象中。
    (2)当ActionServlet接收到一个客户请求时,检索和用户请求匹配的ActionMapping实例,如果不存在,就返回用户请求路径无效的信息。
    (3)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中。
    (4)根据配置信息决定是否需要表单验证。如果需要验证,就调用ActionForm的validate()。
    (5)ActionForm的validate()方法
      ①如果返回null或返回一个不包含ActionMessage的ActionErrors对象,就表示表单验证成功。
      ②如果返回一个包含一个或多个ActionMessage的ActionErrors对象,就表示表单验证失败,此时ActionServlet将直接把请求转发给包含用户提交表单的JSP组件。在这种情况下,不会再创建Action对象并调用Action的execute()方法。
    (6)ActionServlet根据ActionMapping实例包含的映射信息决定将请求转发给哪个Action。如果相应的Action实例不存在,就先创建这个实例,然后调用Action的execute()方法。
    (7)Action的execute()方法返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指向的JSP组件。
    (8)ActionForward对象指向的JSP组件生成动态网页,返回给客户。

    二、Struts 1.2 构成

    1、struts运行需要的jar包
    (1)commons-digester.jar 用于解析配置文件
    (2)commons-fileupload.jar 用于实现文件上传(进行了进一步的封装)
    (3)commons-logging.jar 用于日志处理
    (4)commons-beanutils.jar 用于POJO的属性赋值、拷贝等
    (5)commons-validator.jar 用于表单验证
    2、 struts标记库文件(tld)
    (1)struts-bean.tld
    (2)struts-html.tld
    (3)struts-logic.tld
    (4)struts-nested.tld
    (5)struts-tiles.tld
    3、配置文件struts-config.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
    <struts-config>
      <data-sources />
        <form-beans>
         <form-bean name="xxx" type="ActionForm的类全名">
         <form-bean name="LoginForm" type="basic.LoginForm">
      </form-beans>
      <global-exceptions />
      <global-forwards />
      
    <action-mappings >
    <action path="action的路径,在form的action中写的那个路径"  type="Action的类全名" name="form的名字" scope="request|session(默认值)">
            <forward name="在自定义的Action中使用的findForward方法的参数" path="跳转页面的路径" redirect="false"(重定向,默认false)/>
    </action>
      </action-mappings>
      <message-resources parameter="资源文件的名字(不加后缀)" />
    </struts-config>

    4、资源文件
      <message-resources parameter="ApplicationResources" >
      </message-resources>
    使用资源文件的步骤:
    (1)确认资源文件的jar导入
    (2)引入标记库 <%@tagliburi="/WEB-INF/struts-bean.tld" prefix="bean" %>
    (3) 使用:
    ApplicationResources.properties文件以“消息key、消息文本”格式存放数据
    eg.
    ApplicationResources.properties中:
    jsp.user=username
    test.jsp中:
    <bean:message key="jsp.user"/>
    注意:ApplicationResources.properties文件不支持中文,如果想在页面中展示中文只能把中文转为unicode码,命令:native2ascii 原文件名 目标文件名。

    国际化:按照浏览器所要求的语言选择资源文件。前面相同,后缀不同。
    eg. 
     <message-resources parameter="ApplicationResources" >
     </message-resources>
     资源文件名为:ApplicationResources_zh.properties(中文)
                   ApplicationResources_en.properties(英文)
     也可以加上国家名
       ApplicationResources_zh_CN.properties(中文)
       ApplicationResources_en_US.properties(英文)
    注意:资源文件的选择:首先查找和浏览器语言匹配的资源文件,如果找不到则找和服务器的语言地区相匹配资源文件,如果还是找不到就查找默认不带语言后缀的资源文件。

    三、Struts1.2核心控制流程
    1、主要组件:
    (1)ActionServlet组件:充当Struts框架的中央控制器
    (2)RequestProcessor组件:充当每个子应用模块的请求处理器
    (3)Action组件:负责处理一项具体的业务。
    2、ActionServlet
    (1)Struts的启动通常从加载ActionServlet开始(如果没有其他Servlet的加载优先级比它高)。ActionServlet在应用一加载时即会被实例化并调用其init方法。
    (2)init方法所做的主要工作有: 
      ①加载struts配置文件,并创建用于封装配置信息的ModuleConfig对象 
      ②加载资源文件,并创建用于封装资源文件的MessageResources对象。
    另外,如果有相应配置的话,init方法还将初始化数据源和PlugIn
     注意:
      1)如果web.xml有多模块配置,将创建多个ModuleConfig对象和MessageResources对象分别用于封装各个模块的struts配置文件和资源文件。 
    eg.  多模块:
      <init-param>
          <param-name>config</param-name>
          <param-value>/WEB-INF/struts-config.xml</param-value>
      </init-param>
        <!-- config后面的/ma表示模块名,访问ma模块里的配置文件的action中的url路径位:应用路径/模块名/url.do  -->
       <init-param>
          <param-name>config/ma</param-name>
          <param-value>/WEB-INF/ma/struts-config.xml</param-value>
       </init-param>
     <init-param>
          <param-name>config/mb</param-name>
          <param-value>/WEB-INF/mb/struts-config.xml</param-value>
         </init-param>
    或者
      <init-param>
        <param-name>config</param-name>
        <param-value>/WEB-INF/struts-config.xml</param-value>
      </init-param>
      <init-param>
        <param-name>config/catalog</param-name>
        <param-value>/WEB-INF/ma-struts-config.xml</param-value>
      </init-param>
      <init-param>
        <param-name>config/authorize</param-name>
        <param-value>/WEB-INF/mb-struts-config.xml</param-value>
      </init-param>
      2)针对各个模块所创建的ModuleConfig对象和MessageResources对象将存储在ServletContext中,对应的属性名中有该模块名称的相应标识。 
    (3)ActionServlet的process()方法的主要工作有:
    1)根据请求信息获知所请求的模块名称,从ServletContext中获得与请求模块对应的的
    ModuleConfig对象,并存储到request中。 
    2)根据模块信息获得相应的RequestProcessor对象,一个模块对应一个RequestProcessor
    对象,RequestProcessor对象将关联与所属模块对应的ModuleConfig对象。 
    3)调用RequestProcessor对象的process方法,将request和response作为参数传递给它。 3、RequestProcessor类
    (1)Struts框架只允许应用中存在一个ActionServlet类,但每个应用程序模块都有各自的RequestProcessor类实例。
    (2)RequestProcessor对象的process方法的主要工作:
    1)调用自己的 processPreprocess(request, response)方法,该方法不进行任何操作,用于
    子类重写扩展其功能。 
    2)获得与请求地址所匹配的ActionMapping对象,AcionMapping对象用于封装一个特
    定acion的配置信息。 
    3)根据ActionMapping中的配置信息获得ActionForm对象(该对象将缓存到request
    或session中),并将表单数据填充到ActionForm中,然后根据ActionMapping的配置决
    定是否验证ActionForm,如果验证,将调用ActionForm的validate方法,若其返回的
    ActionErros对象中包含ActionMessage对象则表示验证失败,将转向action配置信息input
    属性所指示的地址。 
    4)如果ActionForm无需验证或验证通过将创建并缓存与请求地址匹配的Action对象,
    将ActionMapping对象、ActionForm对象、request和response作为参数调用其execute
    方法。 
    5)根据Action对象的execute方法返回的ActionForward对象,将请求转发或重定向到
    该ActionForward所封装的地址。
     
    4、Action类
    (1)Action类是用户请求和业务逻辑之间的桥梁
    (2)ActionServlet对所有的请求作集中的统一处理,每个不同的Action类具体处理不同的请求。
    (3)每个Action类都需要实现execute()方法,RequestProcessor类创建一个Action实例后,就会调用其execute()方法。
    (4)struts-config.xml:
    <action-mappings> 
      <action path=”/ 路径,当请求时×××.do时 FC就调用该Action的execute方法” type=”Action类的名称(包名.类名)”name=”该Action关联的ActionForm的名称” 
      <!--如果有,则FC在调用execute方法之前要获得ActionForm对象(第一次调用该Action时创建,然后从request或者session)并且用请求参数对其填充,然后将(ActionForm对象)作为参数调用execute方法 -->
        attribute=” 缓存ActionForm对象的名称(key),不写key就是name的值” scope=” 缓存ActionForm的范围(request|session)默认是session” validate=”是否要验证true|false” 
      <!--如果是true,则FC在填充ActionForm之后,调用Action的execute之前,会验证该ActionForm对象(一种是调用validate方法,另外一种是使用validation框架)--> 
        input=”” 和validate=”true” 联用,表示验证失败后,FC把请求转向的地址  parameter=”” 是一个附加的属性,对于不同的Action可能有不同的意义 
      <!--封装该Action可能转发(重定向)的地址信息-->
      <forward name=”” 该forward的名称(用于mapping.findForward方法) path=”” 地址必须以“/”开头 redirect=”” 表示是否重定向/>
       … … … 
      </ action > 
    </action-mappings>

    5、内置的Struts Action类
    (1)目的
      1)减少Action类的数目
      2)便于代码的维护
    (2)DispatchAction
      1)特点:
     ①DispatchAction 类是Action 类的子类;
     ②共享同一个Action 的路径;
     ③共享一个ActionForm,多个不同action path,可以在同一个类中。

     2)DispatchAction 的写法:
      public class MyDispatchAction extends DispatchAction{ActionForward login(ActionForm form,HttpServletRequest request,HttpServletResponse response,ActionMapping mapping)throws Exception {
        return mapping.findForward(“sucess”);
        }
      }
    注意:不要覆盖execute()方法

    3)DispatchAction 的配置文件:
      <action path="/dispatch" type=" MyDispatchAction " parameter="method">
        <forward name="sucess" path="/ message.jsp "/>
      </action>
    注意:parameter 属性是和表单中隐藏域的名字相对应的

    4)DispatchAction 页面:
      <form action=“${pageContext.request.contextPath}/dispatch.do" method="post">
        <input type="hidden" name="method"  value=“login"/>
        <!--、使用隐藏域为struts 传递要调用的自定义Action 中方法的名字,通过与strutsconfig.xml 中action 标签的parameter 属性相对应来获取隐藏域的value。-->
        <input type="submit" value="submit"/>
    </form>
    <a href="${pageContext.request.contextPath}/dispatch.do?method=login">Login</a>

    (3)MappingDispatchAction
     1)特点:
    ① MappingDispatchAction 类是DispatchAction 的子类
    ②可以匹配多个action 路径
    ③可以不共享同一个ActionForm
    2)MappingDispatchAction 的写法
    public class MyMappingDispatchAction extends MappingDispatchAction{
    ActionForward login(ActionForm form,HttpServletRequest request,
    HttpServletResponse response,ActionMapping mapping) throws Exception{
    return mapping.findForward(“success")
    }
    }
    3)MappingDispatchAction 的配置文件
    <action path="/mapping/login" type=" MyMappingDispatchAction " 
    parameter=“login">
    <forward name=“success" path="/message.jsp"/>
    </action>
    注意:parameter 属性是指定调用方法的名字
    4)MappingDispatchAction 页面
    <form action=“${pageContext.request.contextPath}/mapping/login.do" method="post">
    <input type="submit" value="submit"/>
    </form>
    注意:在JSP 页面中不需要再使用隐藏域来传递参数了,在form 中的action 就可以
    直接使用xxx.do 匹配了。
    (4)LookupDispatchAction
      1)特点:
     ①LookupDispatchAction 类也是DispatchAction 类的子类。
     ②解决一个表单的多个同名提交按钮的问题。
     ③通过使用资源文件,用submit 按钮的value 来作为资源文件中的key 所对应的值,通
    过这个值来找到对应的key,再使用这个key 来获得指定Map 中所对应的值,这个值就
    是要调用的方法名。
    注意:在继承LookupDispatchAction 时,要覆盖getKeyMethodMap()方法,并定义Map,
    向Map 中放入指定的键值对。
    2)LookupDispatchAction 的写法
    public class TestLookupDispatchAction extends LookupDispatchAction {
    public ActionForward login(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)throws Exception{
    return mapping.findForward("success");
    }
    public ActionForward register(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)throws Exception{
    return mapping.findForward("register");
    }
    public Map getKeyMethodMap() {
    Map map = new HashMap();
    //key 为资源文件的key 值,value 为action 中的方法名。
    map.put("submit.login", "login");
    map.put("submit.register", "register");
    return map;
    }
    }
    3)LookupDispatchAction 资源文件
    MessageResource.properties文件中? 
    submit.login=login
    submit.register=register
    4)LookupDispatchAction 的配置文件:
       <form-beans >
       <form-bean name="lookupForm" type="form.LookupForm" />
    </form-beans>
    <action-mappings>
         <action path="/lookup" name="lookupForm"
    type="action.TestLookupDispatchAction" parameter="submit">
    <forward name="success" path="/jsp/success.jsp"/>
    <forward name="register" path="/jsp/register.jsp"/>
    </action>
    </action-mappings>
    <message-resources parameter="MessageResource" />
    5)LookupDispatchAction 页面:
    <html:form action="/lookup"  styleId="lookupForm" 
    styleClass="lookupForm">
     userName:<html:text property="name" /><br>
     password:<html:password property="pwd" redisplay="false" />
     <br>  <br>
     <html:submit property="submit">
     <bean:message key="submit.login" />
     </html:submit>
     <html:submit property="submit">
     <bean:message key="submit.register" />
     </html:submit>
    </html:form>
    注意:页面中的property="submit"与struts-config.xml中action的parameter元素值相同

    四、ActionForm
    1、为什么使用form?
    (1)用户提交的数据封装成对象
    (2)表单数据的缓存。
    (3)表单信息验证(服务器端验证)
    2、ActionForm的生命周期
    (1)ActionForm Bean有两种存在范围:request和session
    1)如果存在于request范围,它仅在当前的请求/响应生命周期中有效
    2)如果存在于session范围,同一个ActionForm实例在整个Http会话中有效
    注意:在struts配置文件中,<action>元素的scope属性用来设置ActionForm的范围,
    默认值为session。
     
    3、配置ActionForm
    (1)action和form的关系是:一对多
    (2)struts-config.xml
    <form-beans> 
    <form-bean name="userForm" type="form.UserForm"/> 
    … … … 
    </form-beans> 
    (3)在某一个Action的配置中可以写: 
    <action path="/add" type="action.AddUserAction" name="userForm"/>
    4、Form验证
    (1)验证:
    1)表单级验证:(不访问数据库)
    ①JavaScript做的是客户端验证,可以减少服务器端的负担,但不够安全
    ②在服务器端的Form验证避免跳过客户端的校验
    2)业务逻辑验证:
    由Action负责完成
    (2)validator()方法
    1)调用的条件:
    ①Form继承ActionForm,并且为ActionForm配置了Action映射,即<form-bean>元素的name属性和<action>元素的name属性匹配。
    ②<action>元素的validate属性为true
    2)validate()方法
    该方法返回ActionErrors对象,如果返回的ActionErrors对象为null,或者
    不包含任何ActionMessage对象,就表示没有错误,数据验证通过。如果ActionErrors中包含ActionMessage对象,就表示发生了验证错误。
    3)validate()方法主要负责检查数据的格式和语法,而不负责数据是否符合业务逻辑。
    (3)Validator框架(验证框架)
    1)validate()方法验证的局限性:
    ①必须通过程序代码来实现验证逻辑,如果验证逻辑发生变化,必须重新编写和编译
    程序代码
    ②当系统中有多个ActionForm Bean,并且它们包含一些相同的验证逻辑时,开发人员必须对每个ActionForm Bean进行重复编程,完成相同的验证逻辑,这会降低代码的可重用性。
    2)主要依赖的jar文件:
     ①jakart-oro.jar:提供了一组处理文本的类,具有文本替换、过滤和分割等功能
     ②commons-validator.jar:提供了一个简单、可扩展的验证框架,包含了通用的验证方
    法和验证规则。
    3)条件:
     ①validator-rules.xml validation.xml 
    ②struts-config.xml 写plug-in 
    <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
            <set-property property="pathnames" 
             value="/WEB-INF/validator-rules.xml,
                      /WEB-INF/validation.xml"/>
      </plug-in>
    ③Form必须继承ValidatorForm(ActionForm子类)
    4)validator-rules.xml中规定了常见的验证需求。一般不需要改变。
    5)validation.xml是form验证的配置文件。
    <form-validation>
    <formset>
    <form name="需要验证的form的名,如果有attribute属性重命名,此处
    使用重命名。"> 
    <field property="name" depends="required"> 
    <!--property属性表示要验证的form对象的属性名--> 
    <!--depends属性表示要适用的验证逻辑(required是validator-rules.xml中规
    定的验证方式。)
    如果depends属性包含多个验证规则,则用“,”隔开。
    如果调用depends属性指定的验证规则时验证失败,就不会再调用下
    一个规则。--> 
    <arg0 key="form.username" /> 
    <!-- validator-rules.xml中的每一个验证逻辑 都对应res文件中的key(key所对应的值是出错信息) 但是出错信息有占位符({0},{1},{2},…), arg0表示填充出错信息中,{0}占位符的信息… 
    注意:实际填充的是key所指字符串在res文件中所对应的值--> 
    </field> 
    </form> 
    </formset> 
    </form-validation>
    切记:Validator框架不能用于验证标准的ActionForm类。如果要使用Validator框架,
    应该采用ActionForm类的两个子类:DynaValidatorForm(支持动态ActionForm)和ValidatorForm(支持标准ActionForm)。
    5、动态ActionForm
    (1)ActionForm 的缺点:表单的改动会触发FormBean 的大量改动(应用程序停器,而且
    FromBean 维护量大)。
    (2)动态FormBean 是指,Struts 已提供给我们DynaActionForm(是ActionForm 的子类),我们只需通过配置文件进行配置。
    (3)DynaActionForm的写法:
    ①struts-config.xml
    <form-bean name="dynaActionForm" 
    type="org.apache.struts.action.DynaActionForm">
         <form-property name="name" type="java.lang.String" />
         <form-property name="age" type="java.lang.Integer"/>
    </form-bean>
    注意:Type 表示属性类型,注意若为基本类型时要用其包装类。
    <action path="/dyna" name="dynaActionForm" 
      type="action.TestDynaActionFormAction" scope="request">
    <forward name="success" 
    path="/jsp/testDynaActionForm_success.jsp"></forward>
     </action>
    ②TestDynaActionForm.jsp
        <h1> 测试DynaActionForm</h1>
        <hr>
        <form action="dyna.do" method="post">
         姓名:<input type="text" name="name"/> <br>
         年龄:<input type="text" name="age" /> <br>
         <input type="submit" value="保存"> <br>
      </form>
    ③TestDynaActionFormAction.java
    public class TestDynaActionFormAction extends Action {
    @Override
    public ActionForward execute(ActionMapping mapping, 
    ActionForm form,HttpServletRequest request, 
    HttpServletResponse response) throws Exception {
    DynaActionForm daf = (DynaActionForm) form;
    String name = (String)daf.get("name");//取daf中的值
    Integer age = (Integer)daf.get("age");
    System.out.println("name:" + name + " <===> age:" + age);
    return mapping.findForward("success");
    }
    }
    ④testDynaActionForm_success.jsp(取DynaActionForm的值)
    <center>
        <h1>测试动态ActionForm</h1>
        <hr>
        姓名:${dynaActionForm.map.name } <br>
        年龄:${dynaActionForm.map.age }<br>
    </center>
    (3)访问动态ActionForm 与访问普通ActionForm 的最大区别:属性的访问方式不同。
    1)普通ActionForm—— getter setter 方法。
    2)动态ActionForm—— DynaActionForm 把所有属性保存在Map 中。
    public Object get(String name)
    public void set(String name, Object value)
    注意:DynaActionForm 的校验不太方便。需要继承DynaActionForm,但是写了代码又不能满足动态的功能了。

    五、异常处理:
    1、处理流程:
    (1)Action ? throw Exception
    (2)Action Servlet ? ExceptionHandler
    (3)ExceptionHandler 处理Exception ExceptionHandler 会读配置文件
    ActionMessage -> request Attribute
    ActionForward
    (4)ActionServlet ActionForward
    2、配置struts 的异常处理
    全局的异常处理
    <global-exceptions>
    <exception key="error" path="xxx/xxx" type="xxx.xxx.Xxxx">
    </global-exceptions>
    <action path="xxx/xxx" type="xxx.xxx.Xxxx">
    ....
    <exception key="xxx" path="xxx/xxx" type="xxx.xxx.Xxxx">
    </action>
    在exception 标签中的key,也就是在出现异常时会封装在ActionErrors 中,也就是可以在页面中使用。
    ActionError(String key, Object value0),可以通过在构造ActionError 时,指定不同的key 值来对异常进行分类,并且在html:error 标签的自己构造ActionErrors 并使用下面的方法发送void saveErrors(HttpServletRequest request,ActionErrors errors)这个方法用以把封装了异常的ActionErrors 的key 存储到request 中。

    六、Struts标签库
    1、html标签库
    (1)<html:form> 对应html 中的<form>,使用<html:form>会将表单中的属性自动封装成Form,他的action属性可以直接写struts 的配置文件中的path
    (2)<html:text>、<html:password>、<html:textarea>、<html:hidden>、<html:submit>
    <html:reset>、<html:checkbox>、<html:radio>、<html:select>、<html:option>
    以上者写标签的使用是和html 中的form 相对应的。
    (3)<html:options>这个标签用来表示一组选择项
    <%
    java.util.ArrayList list=new java.util.ArrayList();
    list.add(new org.apache.struts.util.LabelValueBean("show value","value"));
    list.add(new org.apache.struts.util.LabelValueBean("show value1","value1"));
    pageContext.setAttribute("vlauelist" list);
    %>
    <html:form action="xxx.do">
    <html:select property="test">
    <html:options collection="valuelist" property="value" labelProperty="label"/>
    </html:select>
    </html:form>
    2、Bean标签库
    (1)bean 标签库,是用来访为JavaBean 的属性或者是为Bean 的属性赋值,创建JavaBean,类似于JSP 中的jsp:useBean 动作的功能。
    (2)bean 标签库中的标签中大部分都有以下的属性:
    1)id="xxx" 指定Bean 的名字标识,Bean 在被读出后将引用保存在以这个id 命名的对象中,也就是在JSP 中使用的变量的引用。
    2)name="xxxx"指定要读取Bean 的名字
    3)property="xxxx"
    4)scope="page|request|session|application"
    (3)资源读取标签
    1)<bean:resource>读取资源文件
    2)<bean:cookie>使用这个标签可以对Cookie 进行操作
    3)<bean:header>读取header 信息
    eg.
    <bean:resource id="indexpage" name="index.jsp"/>
    <bean:write name="indexpage"/>
    <bean:head id="head" name="user-agent"/>
    <bean:write name="head"/>
    <bean:cookie id="testcookie" name="/taglib/bean-cookie" value="emptyValue"/>
    <%
    if(testcookie.getValue.equals("emptyValue")){
    javax.servlet.http.Cookie cook=
    new javax.servlet.http.Cookie("/taglib/beancookie","taglib cookie");
    cook.setComment("test");
    cook.setMaxAge(3600);
    response.addCookie(cook);
    }
    %>
    (4)将资源写到页面的标签
    1)<bean:write>将Bean 的属性加入到输出流中
    <bean:write name="xxx"/>name 属性是要加入的资源,也就是先前在其他资源标签中的
    id 属性定义的名字
    2)<bean:define>定义变量
    eg.
    <bean:define id="test" value="test in Struts">
    <bean:write name="test"/>
    3)<bean:message>读取消息,可以根据key 读取消息。
    eg.
    <bean:message key="org.test">

    七、Struts的Token(令牌)机制
    1、Struts 使用Token 机制,来防止恶意的破坏和重复提交问题,也就是点击后退后在再提
    交,这是Struts 无法发现的,在form 中生成一个token 码,在session 中也保存有一个同样
    的token 码,当表单提交后,判断两个token 码向等后,就会改变session 中的这个token 码,
    当然在用回退后,form 的token 码是不会变的,在提交,还会判断两个token 码是否相等,
    如果不等就会抛出异常,证明这是过时的垃圾数据。
    2、方法:
    (1)void saveToken(HttpServletRequest request)方法用于将在客户端生成的token 码,保存在session 中。
    (2)void resetToken(HttpServletRequest request)方法用于重置token 码,生成新的token 码。
    (3)boolean isTokenValid(HttpServletRequest request,boolean reset)判断token 码是否相等,并且是否重置token 码。reset 是设定是否重置token 码,一般设为true。
    3、设置token 码
    public ActionForward toadd(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)throws Exception{
    saveToken(request);
    return mapping.findForward("next");
    }
    4、验证token 码
    public ActionForward add(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)throws Exception{
    if(isTokenValid(request, true)){
    request.setAttribute("message", "contratulation!");
    } else {
    request.setAttribute("message", "sorry");
    }
    return mapping.findForward("next");
    }
    注意:在使用Struts 的Token 时需要讲JSP 页面的<form/>标签改成<html:form/>标签

    八、Tiles框架
    1、Tiles 是一个框架,他实现了页面的复合视图,页面代码中不仅有数据,也有页面的布局格式。
    2、要在基于Struts 应用中使用Tiles 框架,就要在struts-config.xml 中配置
    <plugin className="org.apache.struts.tiles.TilesPlugin">
    <set-property property="definintions-config" 
    value="/WEB-INF/tiles-defs.xml">
    <!--定义tiles 布局文件tiles-defs.xml-->
    </plugin>
    3、 tiles 的布局配置文件tiles-defs.xml
    <tiles-definitions>
    <!-- 页面基本布局-->
    <definition name="pms_base" path="/common/pms_layout.jsp">
    <put name="title" value="pms title" />
    <put name="header" value="/common/header.jsp" />
    <put name="body" value="some body page" />
    <put name="footer" value="/common/footer.jsp" />
    </definition>
    <!-- 其他页面定义-->
    <definition name="add" extends="pms_base">
    <put name="title" value="add" />
    <put name="body" value="/person_add.jsp" />
    </definition>
    </tiles-definitions>
    4、在struts-config.xml 中要把forward 的配置更改一下
    <action path="/person/toadd" type="alan.pms.action.PersonAction"
    name="personForm" scope="request" parameter="toAdd">
    <forward name="add" path="add"/>
    </action>
    这样就会使页面加上header.jsp 和footer.jsp 显示在配置好的页面中
    5、在页面中使用tiles 标签时, 要引入标签库, 
    <%@taglib uri="/WEB-INF/tiles.tld"  prefix="tiles"%>
    <tiles:insert page="xxx.jsp">
    <tiles:put name="header" value="header.jsp">
    <tiles:put name="footer" value="footer.jsp">
    </tiles:insert>
    在struts-config.xml 中要把forward 的配置更改一下
    <action path="/person/toadd" type="alan.pms.action.PersonAction"
    name="personForm" scope="request" parameter="toAdd">
    <forward name="add" path="add"/>
    </action>

    练习题:
    1、在Struts框架中,简述Struts是怎样实现MVC模型的。
    答:Struts提供了下面这些组件使用MVC开发应用程序: 
       Model:Struts没有提供model类。这个商业逻辑必须由Web应用程序的开发者以JavaBean
    或EJB的形式提供; 
       View:Struts提供了ActionForm创建Form Bean, 用于在controller和view间传输数据; 
       此外,Struts提供了自定义JSP标签库,辅助开发者用JSP创建交互式的以表单为基础的应
    用程序; 
       应用程序资源文件保留了一些文本常量和错误消息,可转变为其它语言,可用于JSP中。 
       Controller:Struts提供了一个action serlvet,接收JSP输入字段形成ActionForm然后调用一个action class。


    2、Struts中ActionForm和Action属于MVC的哪一层,为什么?ActionForm的功能有哪些
    答:ActionForm的功能:
    封装表单数据
    提供数据验证方法
    提供把属性重新设置位默认值的方法

    3、请简单画出Struts技术构建MVC的流程图。
    答:见本次串讲的一个图
  • 相关阅读:
    一、ThinkPHP的介绍
    一、ThinkPHP的介绍
    perl 爬虫两个技巧
    perl 爬虫两个技巧
    perl 爬取上市公司业绩预告
    perl lwp get uft-8和gbk
    perl lwp get uft-8和gbk
    perl 爬取同花顺数据
    perl 爬取同花顺数据
    php 接口示例
  • 原文地址:https://www.cnblogs.com/shipeng22022/p/4614153.html
Copyright © 2011-2022 走看看