Struts 2 笔记

MVC的处理流程

  1. 浏览器向Servlet(Control)发送请求。
  2. Control仅仅是一个调度器。接受到请求后,调用Model的方法来处理用户的请求
  3. 处理结束后, Servlet会将结果数据放入“指定银行”中。

转发到指定试图页面(JSP),在试图页面上取出结果数据,并以合适的格式显示出来。
      

     request.setAttribute(”aaa” , list)  Request.getAttribute(“aaa”)


 

在上面的流程中,有如下的操作时每次都要做的,而且是通用的:

  1. 通过request.getParameter来得到请求参数。
  2. 将请求参数进行类型转换。
  3. 对请求参数进行输入校验。
  4. 文件上传
……

框架: 当我们做了N个项目时,你会发现这些项目中。总有些代码在多个项目中时重复的,而且具有通用性质。

      于是就考虑把N个项目中通用的,重复性的代码“抽取”出来做成自己的库。
      ——这就是框架。

为什么选择开源框架?


  1. 开源框架经过很多的市场检验,稳定性,性能都有较好的保障。
  2. 开源框架本身都出自于经验丰富的开发团队,因此质量也有较好保证。


MVC框架:


     Struts 2
     Spring MVC
     JSF(Sun推荐的官方MVC规范,有Renference Implemention,MyFace)

/****************************
*.jar    — N个*.class
*.war   — 一个web应用包
*.ear    — 一个企业应用包,包含N个jar和N个war
****************************/

 

Struts 2的历史:


    2001,Struts 1 (全世界第一个MVC框架)
            ↓
          Apache
            ↓
   开源的其他的MVC框架。WebWork (XWork + Web前端) , OpenSymphony(OS)
            ↓
    2007,WebWork 更名为Struts 2 / shale
            ↓
    2011,OpenSymphony关闭了。

 

Struts 2 解压之后,得到4个文件夹

  apps : 包括5个Web应用包。
          Struts2-blank.war  — Struts 2的空应用。
          Struts2-rest-showcase.war  — Strust 2关于REST技术的小例子。
          Struts2-showcase.war  — Struts 2 技术的所有小例子。
  docs : API文档 相关的Guide。
  lib  : Struts 2自己的JAR包,以及它编译和运行所需要第三方的JAR包。
  src  : Struts 2的源码。

---------------------------------------------安装Struts 2-------------------------------------------------
   Struts 2.3.1.2
 (1)拷jar包;apps下的Struts2-blank.war
 (2)修改web.xml文件。加载Struts 2的核心Filter。
      让Filter过滤所有的用户请求。
 (3)在classes目录下增加一个Struts 2的配置文件:struts.xml。
      (开发时把struts.xml放在目录下即可)

Struts 2的开发步骤
 (1)先定义一个能转发请求的页面。也可是超链接,也可以是表单。
 (2)开发Action类。
      Struts 2对Action并没有过多的要求,只要求:
      A。推荐实现Action接口,或继承ActionSuppor。
         ActionSuppor本身实现Action接口。
      B。为每个请求参数都提供Field,并为之提供相应的Setter和Getter方法。
      C。该Action应该有无参数的构造器
 (3)配置Action类
       <Action…/>元素有如下常用的属性:
         - name:指定该Action处理哪一些请求。
         - class:指定Action对应的处理类。
         - method:指定使用Action的哪一个方法来处理用户请求。默认值为execute
      
         并为之处理返回的字符串,指定相应的物理试图。
/************************
POJO (Plain Old Java Object)-尽量使用POJO编程

尽量使用特定框架、特定规范相关的API。
************************/

 当用了Struts 2之后。

 

(1)浏览器发送请求:abc.action。.action后缀可以保留。也可以省略。
(2)浏览器发送的请求被StrutsPrepareAndExecuteFilter拦截。
     --因为在web.xml中指定StrutsPrepareAndExecuteFilter来过滤所有的请求。
(3)StrutsPrepareAndExecuteFilter会去创建Action的实例。
      假如我们请求abc.action。StrutsPrepareAndExecuteFilter会去搜索struts.xml文件
      中name为abc的Action配置,根据class属性“使用反射”来创建Action实例。
(4)调用

Map<String,String> paramMap = request.getParameterMap();  //获取所有的请求参数名。   
       for(String paramName :paramMap.keySet())
        {
          //得到请求参数对应的Setter方法.
           Action类.getMethod("set"+paramName的首字母大写);
           String paramValue = paramMap.get(paramName);
           
           //以Action实例为调用者,调用Setter方法,把请求参数值作为参数值传入。
           setter.invoke(actionInst , paramValue);
         }


(5)再次通过反射来调用method属性所指定的方法。
     返回一个字符串。
(6)根据struts.xml文件中的<result.../>元素中的name以及物理试图资源,
     跳转到实际的视图资源。

 

如何action中访问Servlet API

 

总有些时候,需要访问Servler API
                      比如我们需要把数据存入Session、Application。
更甚至于我们要添加Cookie:response.addCookie();

Struts 2提供两种方式访问Servlet API:
            伪访问:借助于ActionContext
                          ActionContext,提供getSession      --模拟访问Http Session
                                                          getApplication  --模拟访问Application
            真访问:(比如要添加Cookie)。借助于ServletActionContext。
                          ServletActionContext提供如下的静态方法:
                                      static PageContext getPageContext()
                                      static HttpServletRequest getRequest()
                                      static HttpServletResponse getResponse() 
                                      static ServletContext getServletContext()
 

常量配置

 

   Struts 2常量,也叫Struts 2属性。
                                     --控制整个Struts 2的应用特性。

   一个常量名,指定一个常量值。


   配置方式有3种:
                        - 在web.xml中:每个要4行。
                                   <!-- 通过Filter配置初始化参数,就可以配置Struts 2的常量 -->
                                    <init-param>
                                           <param-name>常量名</param-name>
                                           <param-value>常量值</param-value>
                                   </init-param>
     - 在struts.xml文件配置。
                                 <constant name="常量名" value="常量值"/>
     - 额外增加一个struts.properties配置文件
                                 常量名=常量值 --每行配置一个常量。

  Struts 2支持的常量:
     
     struts.i18n.encoding                        -- 文件字符编码。
     struts.multipart.saveDir                   -- 设置文件上传到临时目录
     struts.multipart.maxSize                 -- 设置每次请求上传的文件总大小。
     struts.anction.extension                  -- 设置action默认的后缀。该常量的值为action。
     struts.serve.static.borwserCache   -- 控制浏览器是否缓存静态内容。
     struts.devMode                              -- 设置struts开发模式。
     struts.i18n.reload                           -- 是否为每次请求都重新加载资源。
     struts.configuration.xml.reload      -- 是否每次struts.xml修改之后,应用自动加载。
     struts.custom.i18n.resources        -- 加载国际化资源文件。

 

/*****************************
        Action接口与ActionSuppor

  Action接口中定义了5个字符串常量,和一个exuecute抽象方法。


include 其他配置文件
      企业开发  --  模块化开发
             - 开发阶段 : 每个人都要维护自己的配置文件。
             - 销售阶段 : 软件做成模块化:
                          A - B模块:免费的;
                          C - E模块:20W;
                          C - E; F - G: 50W.

 

struts.xml'配置包:

 

每个package元素定义了一个包配置。定义package元素时可以指定如下几个属性:
  - name:这是一个必填属性,该属性指定该包的名字,改名字是该包被其他包引用的Key
  - extends:该属性是一个可选属性,该属性指定该包继承其他包。继承其他包,可以继承其他包中的Action定义、拦截器定义等。
  - namespace:该属性是一个可选属性,该属性定义该包的命名空间。
  - abstract:该属性是一个可选属性,它指定该包是否是一个抽象包,抽象包Action定义。

 

struts 2开发步骤:

 

   (1)编写一个能发送请求的页面:表单或是超级链接.
   (2)编写一个Action类:
            1.推荐实现Action接口或是继承ActionSupport。
            2.为每个请求参数,包括需要传到下一个页面显示的数据提供Field。
               并提供Setter和Getter方法。
            3.要有无参数构造器。
   (3)在struts.xml文件配置Action。

 

struts.xml配置:


     
    1.常量配置
   
    2.包配置和命名空间配置。
      这种设计主要是为了企业应用的模块化开发。把多个配置文件以include的方式包含进来。
   
    3.处理结果的配置。

      Action中处理用户请求的方法:① 该方法不能有形参声明
                                                        ② 返回值是String

 

     传统的MVC:


        (1)Servlet(控制器)调用Model处理完用户请求之后
        (2)requst.getRequestDispatcher("/abc.jsp").forward(request,response);
                 这种方式下,坏处:
                   1.  跳转代码,已经写死,跳转到某一物理视图。(硬编码与物理视图耦合)
                   2. 在未来的日子里,软件可能要跳转到其他页面(甚至不再使用JSP视图),如果是硬编码耦合,必然需要手动修改代码。
 
      Struts 2的做法:
        (1)Action调用Model处理完用户请求之后。
        (2)只是返回一个String类型的逻辑视图名。
        (3)然后在struts.xml文件通过<result.../>元素定义了“逻辑视图名”于物理视图之间的对应关系。这样就把原来的硬编码耦合,提取到XML中进行管理。

         逻辑视图名与物理视图的关系,是通过<result.../>元素来管理。
        

 <result name="" type="">
               <param> </param>
               <param> </param>
                ...
         </result>



         
        
         支持如下属性:
          - name:指定逻辑视图名。默认是success。
          - type:指定你使用的物理视图类型。默认值就是dispatcher。
         
          如果有如下result配置:
      

       <result name="逻辑视图名"type="视图类型">
              <param name="location">物理视图的位置</param>
              <!--是否解析OGNL表达式的值-->
              <param name="arse">true</param>
          </result>



          就可以简化为如下写法:
          

<result name="逻辑视图名"type="视图类型">物理视图的位置</result>



       
          在struts-default.xml文件中的struts-default抽象包中:

<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />

/************************

 

 forward与redirect的区别?

 

   forward :依然是一次请求,地址栏URL没有变化。请求参数和请求属性都不会丢失。
   redirect:重新发送一次新的请求,(就跟直接在地址栏输入新URL,并回车的效果是一样的)
                   地址栏URL会改变。请求参数和请求属性会全部丢失。

************************/

 

常见的结果类型:


     chain      - Action处理完用户请求之后,转发到下一个Action继续处理。形成“链”式处理。
     redirect   - 直接“重定向”到新的URL
                      会生成一次新的请求,原有的请求参数,请求属性都会丢失。
                       与默认的dispatcher“转发”对应的。
     dispatcher - 默认值。
                        转发到JSP页面。
     plainText  - 直接显示视图页面的源代码。
                        一般不会太大的用处。只要用于显示源代码。
     steam      - 直接生成“二进制”流作为响应。

全局result与局部result:
   result元素放在Action,就是局部result。
   result元素放在global-results,就是全局result。


尽量少用全局result--只有在多个Action都具有某一通用性质的result时,才考虑使用全局result。

/****************************
Struts的配置文件,包括:
   struts-default.xml   ----struts2的核心包使用该配置文件。
   struts-plugin.xml    ----struts2的插件包使用该配置文件。
   struts.xml           ----strust2应用使用该配置文件。
   struts-abc.xml       ----这种其他的配置文件,必须用include才会加载。

****************************/

动态结果:
    在定义的物理视图资源时,可以直接使用OGNL表达式。所以在这个物理视图资源可以动态的改变。


动态方法调用(DMI Dyna Methdo Invocation):
    用处不是特别大!大致了解就行了。
   
    功能:可以提交请求时,直接提交给Action的指定方法。

    就是在页面指定请求地址为:action名字!方法名
          --表明将请求提交给指定的Action的指定方法进行处理。

如: JSP页面的Form
    

 <form action=”LoginRegistAction!regist.action”>
    .....
     </form>
     Struts.xml     
    <action name=”login” class=”advance.LoginRegistAction” method=”login”>
        <result.../>
    </action>


 


为什么少用动态方法调用:
         - 动态方法调用的安全性不高。
         - 其实完全可以通过在Action元素中指定method属性来代替动态方法调用的功能。

 

===========================Struts 2的国际化===============================
     

 程序国际化:
           程序可以根据机器所在的国家、语言环境,自动显示当前国家、语言的内容。
 
      国际化的本质:查找、替换。
    
      国际化的步骤:
          (1)为不同国家、语言环境提供相应的资源包。
               如果你的国际化语言资源包中有非西欧字符,要使用nativeascii命令处理该文件。
          (2)在程序中输出国际化信息的key。
     Struts 2的国际化:
      1.支持模块化加载。
      2.Strust 2支持自动加载国际化资源。

1.JSP页面的国际化:
    A。需要手动加载国际化消息。
       使用<s:i18n name="">
    B。在页面上使用<s:text .../>根据key来输出国际化消息。
       如果是表单标签,直接使用key来指定国际化消息。

2.Action的国际化:
    A。自动加载国际化消息。
       让国际化消息的baseName与Action的类名相同,并且放在同一个目录下。
    B。在Action类中调用getText()方法来加载国际化消息。

3.包范围的国际化:
    A。自动加载国际化消息。
       让国际化消息的baseName为package(不是与包名相同),并且放在该包的目录下。
       --可以让该包下的所有Action共享同一个国际化资源文件。
    B。在Action类中调用getText()方法来加载国际化消息。

4.全局国际化资源文件。
    A。通过一个常量:struts.custom.i18n.resources来加载国际化资源文件。
    B。全局国际化资源文件,既可被Action访问,也可以被JSP页面访问。

    全局国际化资源文件的方式尽量少用!这样不利于项目后期的升级和维护。
/****************************************************
Action接口与ActionSupport实现类:

    ActionSupport实现类实现了Action接口。
    而且增加了输入校验支持、国际化支持等功能。
*****************************************************/

struts 2默认根据浏览器的语言环境设置来选择自己的语言、国家的环境。


      struts 2还提供了机制,让用户来选择自己的语言、国家的环境。
       A。根据request_locale来确定的。

 


struts 2的异常处理:

   传统的Web编程的异常模式:
  

  try{
       
        //业务代码
      }
        //异常1
       catch(XxxException ex){
         forward("/a.jsp");
      }
       //异常2
       catch(YyyException ex){
         forward("/b.jsp");
      }
       //异常3
       catch(ZzzException ex){
         forward("/c.jsp");
      }


 

      对于Action的处理方法而言,处理结果可能出现如下的情况:
         1.正常执行结束,会返回一个String类型的逻辑视图。
           对于String类型的逻辑视图,使用
           使用<result name="逻辑视图名">物理视图资源</result>
         2.遇到异常,返回一个异常对象。
           <exception-mapping exception="异常类" result="逻辑视图名"/>
     
     Struts 2的异常配置的本质:
         为不同的异常类,“起一个”逻辑视图名。
    
     Struts 2设计的处理方法完全不需要处理任何异常,他可以声明抛出任意的异常。

     如果希望在错误页面上,显示异常提示:
         <s:property value="exception.getMessage()"/>


Java领域的MVC框架
 
     -  Struts 2主要实现了控制器。(StrutsPrepareAndExecuteFilter+Action)
     -  提供了大量的标签库,可以简化View的开发。

 

==============================OGNL表达式=======================================


OGNL(Object Graph Navigation Language)

    回顾JSP 2 EL - 做数据访问的工具,并不是编程语言。
                   所以它必然很简单。


    EL 开始就提供了11个内置对象。P142

    pageContext
    pageScope
    requestScope
    sessionScope
    applicationScope
    param
    paramValues
    header
    headerValues
    cookie
    initParam
 
    ${requestScope.abc.xyz.def} 当请求参数多个值时:XxxValue。   "."相当于的。


    OGNL

       既然要访问数据,必须要有个东西装数据,
       OGNL的装数据的东西叫“Stack Context  (OGNL Context)”,
       --可以理解它相当于一个Map。
 
       1.它里面的每一个对象,都应该有个名字,根据名字来访问。
          #对象名

       假如OGNL Context中 有3个对象:foo、bar、test
      
       #bar.abc  - 访问bar对象的getAbc()返回值。
       #test.xyz.abc.def - 访问test对象的getXyz().getAbc().getDef()

       2.OGNL Context中有个根(root)对象。如果我们要访问(root)对象的属性,可以省略对象名

       假如OGNL Context中有3个对象:foo、bar、test,但bar是根对象。
       abc.xyz.def - 访问bar.getAbc().getXyz().getDef()。

 

       3.OGNL可以直接创建List对象:{ele1,ele2,ele3,ele4......}
       4.OGNL可以直接创建List对象:#{key1:value1,key2:value2,key3:value3,key4:value4......}
       5.OGNL还可以直接获取“自集合”
         person.cats.{? #this.age > 2}  --获取person所养的cat中age大于两岁的cat。
         person.cats.{^ #this.age > 2}  --获取person所养的cat中age大于两岁的第一个cat。
         person.cats.{$ #this.age > 2}  --获取person所养的cat中age大于两岁的最后一个cat。


       6.OGNL还支持直接调用静态方法:
       (struts.ognl.allowStaticMethodAccess常量设为true)
         类名@静态Field
         类名@静态方法(参数值)


Struts 2控制标签:

      if/elseif/else    - 判断语句
      iterator          - 迭代集合
      append/merge      - 把两个或以上的集合合并成一个集合
      generator         - 按耨中规则把字符串分割成一个新的集合。
      subset            - 截取子集合。

Struts 2数据标签:

      set               - 定义一个变量。可以将变量放入指定的scope中。
      property          - 输出指定表达式的值,如果指定了value属性,就输出value属性对应的值。
                          如果没有指定value的值,就输出ValueStack栈顶的值。
      bean              - 创建一个Bean对象。var指定对象的名(Stack Context中)。name指定实现类。      
      debug             - 帮忙调试。可以开发者观察ValueStack以及Stack Context中的数据。
      i18n              - 为指定页面加载国际化资源文件,name指定国际化资源包的baseName。。
      text              - 输出表达式的值。也通过name指定国际化消息的key。
      action            - 可以直接在页面上调用指定的Action
                          可以直接把Action的处理结果包含在本页面上。
                          name和namespace确定调用哪一个Aciotn。
                          var:指定将被调用Action放在Stack Context(官方式胡扯的。)
                          executeResult:指定被调Action的处理结果完全包含当前页面中。
                          ignoreContextParams:控制当前页面请求参数,是否传入被调的Action。
 
                       功能是比较有用的 - 假如我们进入一个添加用户的页面:
                          用户名:□□□□□□
                          密码:  □□□□□□
                          性别:  下拉菜单      <s:action var="genders" name="listGender"/>
                          学历:  下拉菜单    - 来自系统数据库中的数据。
                          籍贯:  下拉菜单      <s:action var="jiguans" name="listJiguans"/>
                        
     dete               - 对日期进行格式化输出。
                          name:指定要格式化输出的日期。
                          format:指定格式字符串。
     include            - 用于包含指定的JSP页面。
     param              - 用于设置参数。
     push               - 把表达式的值,放入ValueStack的栈顶。
                          当我们的对象所在对象图“很深”时,
                          可以将该对象“推入”ValueStack栈顶。


  UI标签:

    主题与模板

    当我们在页面上使用的s:textfield标签,他生成两列布局,并提供了label标签。 
    --因为struts 2为所有的标签都提供了一个模板。

    每个标签所表现的效果 -- 有它对应的模板所决定的。
   
    如果为所有的标签都提供了模板,这一系列的模板组成了主题。

    Struts 2默认提供了3个主题:
     simple      :没有额外的附加行为的主题。
                   只生成最核心的Html元素。(比如两列布局,Label全部没有)
     xhtml       :默认主题。
                   1.两列布局。
                   2.生成label。
                   3.输出错误提示。
                   4.客户端校验支持。
     css_xhtml   :就是在xhtml增加一些样式。

    如果有需要,我们也可以针对自己的羡慕开发自定义主题。

    如何设置主题?
    
      1. 为我们的标签设置theme属性。子标签默认使用父标签所设置的主题。
      2. 通过page\request\session\application范围内的theme来设置主题。
      3. 也可直接常量struts.ui.theme来设置主题

   这些UI都可以指定CSSClass、CSSStyle来指定CSS样式。
   还可以指定大量的onXxx属性,用于绑定JavaScript函数。

 表单标签:
     checkbox           - 生成单个复选框。
     head               - 引入一些辅助的css样式单和js脚本。
     file               - 生成一个文件上传域。
     form               - 生成一个表单域。
     hidden             - 生成一个隐藏域。
     label
     password           - 生成一个密码框。
     reset              - 生成重置按钮。
     submit             - 生成提交按钮。
     textarea           - 生成一个多行文本域
     textfield          - 生成一个单行文本框
    
     可以与action合用。
     checkboxlist        - 生成多个复选框。
     radio               - 生成多个单选框。
     select              - 生成下拉菜单。
     optgroup            - 生成下拉菜单子菜单。
    
     combobox            - 生成一个文本框与列表框的组合(不能用中划线"-")
     updownselect        - 生成菜单,可下移。
     optiontranferselect - 生成菜单,两个updownselect的组合。
     doubleselect        - 两个列表框,而且有级联效果(form中的action必须有值)。

     token              - 防止刷新
       默认情况下,如果没有进行防止刷新控制,每次刷新都会添加一条相同的记录。
      (1)需要在表单添加<s:token/>
      (2)在相应的配置文件中增加一个拦截器<interceptor-ref name="token"/>
           以及默认的拦截器 <interceptor-ref name="defaultStack"/>如果拦截器检测到用户刷新,
           会返回一个invalid.token的逻辑逻辑视图名
      (3)给invalid.token的逻辑逻辑视图名指定一个物理视图。

 非表单标签:
    actionerror/actionmessage  - 它们体现的struts 2的信息机制。
          当我们需要把action中的一段文本,传入下个页面时,
          就可以借助Struts 2的信息机制。

        1)Action中可以通过addActionError()或addActionMessage()来添加消息。
        2)接下来皆可以在下一个页面上使用<s:actionerror/>或<s:actionmessage/>输出消息。

    fielderror  - 输出类型转换失败、输入校验失败后的错误提示。


文件上传:

 

   传统的文件上传:
       (1)需要将form的enctype设置为multipart/form-data。此处会将整个表单
            以二进制流的形式上传。
       (2)接下来就无法用request.getParameter()来获取请求参数。
       (3)需要提供一个文件上传组件(SmartUpload、Common-FileUpload)
       (4)Servlet通过文件上传组件来获取请求参数,获取上传的文件。
            得到上传文件后,以IO流的方式把文件写入磁盘。

   Servlet 3.0以后:
     只要增加@MuitiparConfig来修饰Servlet。
     接下来就可以用request.getParameter()来获取普通请求参数。
                 用request.getPart()获取上传文件。

     得到上传文件后,以IO流的方式把文件写入磁盘。


  Struts 2的更简单:

   <1> 每个文件上传域,需要在Action中提供3个Field进行封装。
      1.与文件上传域的name同名的,类型为File的field。
      2.名为 文件上传域的name + FileName,类型为String的field。
      3.名为 文件上传域的name + ContentType,类型为String的field。
   <2> 使用IO流控制将文件写入服务器的物理磁盘。

 文件的过滤:

   A。只允许上传指定类型的文件。
   B。只允许上传指定大小的文件。

 文件过滤的方式有两种:

   1)在Action通过代码进行控制。
      File类型的File可以获取上传文件的大小。(long)
      String类型xxxContentType可以获取上传文件的类型。
      通过判断上传文件的大小、类型,即可对上传文件进行过滤。

   2)使用fileUpload拦截器进行过滤。
      只要进行简单配置即可。
       1.启用fileUpload的拦截器。当文件过滤失败时,Struts 2会返回input逻辑视图名。
       2.需要为input逻辑视图名配置一个物理视图。
         需要配置:
         allowedTypes:该参数指定允许上传文件类型,多个文件类型之间以英文逗号","隔开。
         maximumSize: 该参数指定允许上传文件大小,单位是字节。
       3.更改错误提示:
         要通过如下两个国际化消息的key:
         struts.messages.error.content.type.not.allowed=您上传的文件类型只能是图片文件!请重新选择!
         struts.messages.error.content.type.too.large=您上传的文件太大,请重新选择!


文件下载:


     
    可能有人疑问:直接把文件放在Web应用的根路径下,即可实现下载。
    但实际上可能存在如下问题:
     1.当文件名有中文字符时,就无法下载了。
     2.直接放在Web应用的根路径下,将导致所有人可以自由下载该资源,毫无安全性可言。


    为了解决上面两个问题,此时就需要通过Struts 2的文件下载进行控制。

    实现文件下载的Action,关键只有一条:
    要提供一个返回值为InputStream的getter方法。
       --该方法代表文件下载的入口,它就是要让客户下载的文件的输入流。
  
    借助于Struts 2的文件下载之后,
       --所有的文件下载都需要经过Struts 2的Action处理。
    因此Action就可以对是否允许用户下载进行控制。


Struts 2 的一个常见的错误:

    在迭代的时候,var命名别名是要注意避免冲突。


Struts 2类型转换:

  1.struts 2内置了强大的基于OGNL的转换机制。

  2.struts 2允许开发者开发自定义类型的转换器。

  3.如果转换失败。struts 2的conversionError会自动起作用,跳转到input的逻辑视图名。。
    input逻辑视图名 -- 代表上传文件的类型不允许,大小超过指定规定。类型转换失败。输入校验失败。

 

Struts 2内置的转换器:
  boolean和Boolean:完成字符串和布尔值之间的转换。
  char和Character:完成字符串和字符之间的转换。
  int和Integer:完成字符串和整型值之间的转换。
  long和Long:完成字符串和长整型值之间的转换。
  float和Float:完成字符串和单精度浮点型值之间的转换。
  double和Double:完成字符串和双精度浮点型值之间的转换。
  Date:完成字符串和日期类型之间的转换,日期格式使用用户请求所在的Locale的SHORT格式。
  数组:在默认情况下,数组元素是字符串,如果用户提供了自定义类型转换器,也可以是其他复合类型的数组。
  集合:在默认情况下,假定集合元素类型为String,并创建一个新的ArrayList封装所有的字符串。
 
  ================================================================================================
  其中Date转换器很容易失败 -- 原因是因为Struts 2要求日期格式必须符合用户请求所在的Locale的SHORT格式。

自定义类型转换

  在某些时候,出于一些非常极端的场景,程序需要完成如下的转换:
 
  String → 自定义的复合类
 
  这种转换是特定业务要求的,因此只能由自定义转换实现

 (1) 为了实现自定义转换器,需要实现一个TypeConverter接口。但实际上,为了简化开发,推荐继承StrutsTypeConverter基类
            TypeConnverter(接口)
                    ↑
           DefaultTypeConverter
                    ↑
           StrutsTypeConverter
       但实际上,为了简化开发,推荐继承StrutsTypeConverter基类
         
       继承实现StrutsTypeConverter基类时,需要实现如下的两个抽象方法:
          - Object convertFromString(Map context, String[] values,  Class toClass)
            把字符串字符类型的请求参数请求,转换为实际所需的类型。
          - String convertToString(Map context,Object o)
            把实际类型的对象,转换成字符串字符类型

       关键是实现第一个方法。

(2)注册类型转换器。


     局部类型转换:在Action所在的包下,增加Action类名-conversion.properties文件,该文件包含如下内容:
                   属性 = 转换器类名。
                   对Action类名 的 指定属性 使用指定转换器,进行转换。


     全局类型转换:在src目录下,增加xwork-conversion.properties,该文件包含如下内容:
                   类型 = 转换器类名。
                    对所有Action 的 指定类型 的 使用指定转换器,进行转换。
 
     默认的defaulsStack中已经包含了conversionError拦截器。
        当类型转换失败时,conversionError拦截器跳转到input逻辑视图。

    默认的错误提示是:Invalid field value for field {0}.

    如果需要使用自定义的错误提示信息:

     A.全局方式:增加一个全局的国际化资源文件。
                 在该文件中增加key为:xwork.default.invalid.fieldvalue的国际化消息即可。
                 在struts.xml或是jsp页面中配置国际化。
     B.局部方式:专门为指定的Action的、指定属性指定转换失败的错误提示。
                 因此这种方式的错误提示更有针对性,更具体。

                  为指定的Action增加一个Action范围的国际化资源文件。
                  在该文件中增加key为:invalid.fieldvalue.(Action中自定义转换的属性名)的国际化消息即可。

 
==============Struts 2 输入校验===============

 

    类型转换和输入校验是“牢牢”结合的。

      String类型请求参数
             ↓
        类型转换(可能失败)→conversionError拦截器跳转到input逻辑视图。
             ↓
        输入校验 (可能与我们业务要求不符合)

        只有通过了① 类型转换、② 输入校验后的数据,才能去调用Action。


    Struts 2 输入校验十分简单

      客户端校验:防止用户的误输入,从而降低服务器的负担。
      服务器校验:它是整个应用最后的安全防线。


   Struts 2的输入校验,完全是模块化进行的。
    需要校验哪个Action,
   1.让Action继承ActionSupport基类。
   2.为该Action增加校验规则文件。--Struts 2会自动加载该校验规则文件。
   3.校验规则文件的文件名应该是Action类名-validation.xml。每个校验器就对应一条校验规则。
   4.当校验失败是,会跳转到input的Result,因此需要配置一个名为input的result元素。
 


   Struts 2内置了大量的校验器

 

   常用的:
    required validator         - 必填
    date validator             - 判断必须在指定日期范围内的。
    double validator           - 判断必须在指定double范围内的。
    int validator              - 判断必须在指定int范围内的。
    expression validator       - 表达式校验器。要求必须满足某一表达式。
    regex validator            - 正则表达式校验器。要求必须满足某一正则表达式。
   
    email validator            - email校验器
    url validator              - url校验器  
                                 (均可用regex validator替代)
   
    stringlength validator     - 字符串长度必须在指定日期范围内的。
  
    错误提示消息的国际化:

      错误提示信息,有两种方式指定:
          A。<message>提示信息</message>  -- 错误提示信息不会国际化。
          B。<message key="消息key">      -- 错误提示信息会国际化。

  
   客户端校验:

      1.表单标签应该用struts 2的s:form来定义表单。
      2.为s:form标签增加validate="true"属性。

  使用客户端校验:有一点需要注意:
     如果依然使用Action范围的国际化资源文件来生成错误提示,表单页面将无法加载国际化资源文件。
     此时就必须使用全局变量的国际化资源。


     (有些校验器规则,在客户端校验不支持。如:fieldexpression)

 

  校验器有两种配置风格:

     1.字段优先的配置风格。(优先使用)
    
     2.校验器优先的配置风格。
          --通过为校验器指定fieldName参数,来确定该校验器要校验哪个字段。


  校验规则文件的搜索顺序:

    假如:
         BaseAction (BaseAction-validation.xml)
             ↑
         UserAction (UserAction-validation.xml)
             ↑
        RegistAction (RegistAction-validation.xml)

        那么RegistAction的校验文件为:BaseAction-validation.xml
                                      UserAction-validation.xml
                                      RegistAction-validation.xml

                                      一共是3份校验规则文件的校验总和。

 


===========================拦截器=============================

 

   Struts 2内置了大量的拦截器,来完成系统的绝大部分通用功能。
             

   配置了这些基本的拦截器之后,

   Struts 2又为我们定义了大量的为特定功能组合的拦截器栈。

   考虑到大部分开发者技术叫差,struts 2又定义了一个默认的拦截器栈(defaultStack/completeStack)
            -- 它不一定是性能最好的,但他是最通用的,最通用的。


拦截器配置中,涉及好如下元素:

  (1)

  <interceptor name="拦截器名字" class="拦截器类">
            <param name="excludeMethods"/>  -- 用于为拦截器参数指定默认值。
       </interceptor>     
      



          -- 配置一个拦截器。

  (2)

     <interceptor-stack name="拦截器栈的名">
            <interceptor-ref name="已有的拦截器"/>
            <interceptor-ref name="已有的拦截器"/>
            <interceptor-ref name="已有的拦截器"/>
            <interceptor-ref name="已有的拦截器">
               <param name="excludeMethods"/>  -- 用于为拦截器参数指定参数值。
            </interceptor-ref>
            ...
        </interceptor-stack>



           -- 配置一个拦截器栈。
           从功能上来看,拦截器栈相当于是大的拦截器。

  (3)<default-interceptor-ref name="已有的拦截器或拦截器栈"/>


         一旦为某一个包指定了默认的拦截器,如果该包中的Action没有显式指定拦截器,则默认的
     拦截器将会起作用。
         如果我们为该包中的Action显式应用了某个拦截器,则默认的拦截器将不会器作用。如果该
     Action需要使用该默认拦截器,则必须手动配置该拦截器的引用。

 

开发自定义拦截器:


      拦截器一般用于一些具有通用性质的、而且横跨多个Action的相同的逻辑。

      (1)开发拦截器实现类,拦截器实现类需要Interceptor接口。
                实现给接口就需要实现它的3个方法。
     
           如果需要为拦截器实现类配置参数,就需要在拦截器中定义一个与参数同名的field
           并为之提供setter和getter方法。
 
      (2)使用<interceptor.../>元素定义拦截器。
               还要用<interceptor-ref.../>使用拦截器。

           当然,可以把我们开发的拦截器添加到默认的拦截器中。

 

输入校验


    完全自定义的输入校验
    假设有如下需求,系统要求用户名不能与系统中已有的用户名重名。
                    这种校验要求,它具有一定的业务相关的并不是通用的校验。


    struts 2允许开发者通过重写validete()进行校验。
            -- 只有当我们要进行校验,是特定业务要求的,才考虑该方法。

    推荐采用的校验方式:
     (1)优先考虑使用-validetion.xml校验规则文件来进行输入校验。
     (2)只用对于一些特定业务相关的校验规则,考虑重写validetei()方法来进行校验。

Ajax:
    在后台以“异步”方式发送请求,并以服务器响应局部更新页面。

   
Struts 2的Ajax支持:

 

    无需Dojo的支持
    (1)通过stream类型的ersult实现:      
        1.客户端浏览器通过JavaScript向服务器发送Ajax请求。
        2.

           .A  开发一个Action,
                让该Action返回一个InputSream作为响应。
           .B  配置该Action,指定stream结果类型。
                该结果类型向客户端生成文本响应 -- 这就是Ajax响应。
        3.在浏览器中动态加载、并显示服务器相应。  
  

  (2)通过JSON插件来实现。

       JSON是一种轻量级的数据交换格式。
        {} - 对象。
        [] - 数组。

      (1)添加JOSN插件。复制一个插件JAR包即可。
           它提供了json-default的包,该包继承了struts-default。
           而且在该包中提供一个json类型的Result。

      (2)使用JSON插件之后,关于配置Action时可以指定一个类型为json的result。
           json类型的Result会把整个Action实例转换JSON字符串后 直接所谓服务器响应
           需要注意,让我们包要继承json-default包。

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
水资源是人类社会的宝贵财富,在生活、工农业生产中是不可缺少的。随着世界人口的增长及工农业生产的发展,需水量也在日益增长,水已经变得比以往任何时候都要珍贵。但是,由于人类的生产和生活,导致水体的污染,水质恶化,使有限的水资源更加紧张。长期以来,油类物质(石油类物质和动植物油)一直是水和土壤中的重要污染源。它不仅对人的身体健康带来极大危害,而且使水质恶化,严重破坏水体生态平衡。因此各国都加强了油类物质对水体和土壤的污染的治理。对于水中油含量的检测,我国处于落后阶段,与国际先进水平存在差距,所以难以满足当今技术水平的要求。为了取得具有代表性的正确数据,使分析数据具有与现代测试技术水平相应的准确性和先进性,不断提高分析成果的可比性和应用效果,检测的方法和仪器是非常重要的。只有保证了这两方面才能保证快速和准确地测量出水中油类污染物含量,以达到保护和治理水污染的目的。开展水中油污染检测方法、技术和检测设备的研究,是提高水污染检测的一条重要措施。通过本课题的研究,探索出一套适合我国国情的水质污染现场检测技术和检测设备,具有广泛的应用前景和科学研究价值。 本课题针对我国水体的油污染,探索一套检测油污染的可行方案和方法,利用非分散红外光度法技术,开发研制具有自主知识产权的适合国情的适于野外便携式的测油仪。利用此仪器,可以检测出被测水样中亚甲基、甲基物质和动植物油脂的污染物含量,为我国众多的环境检测站点监测水体的油污染状况提供依据。
### 内容概要 《计算机试卷1》是一份综合性的计算机基础和应用测试卷,涵盖了计算机硬件、软件、操作系统、网络、多媒体技术等多个领域的知识点。试卷包括单选题和操作应用两大类,单选题部分测试学生对计算机基础知识的掌握,操作应用部分则评估学生对计算机应用软件的实际操作能力。 ### 适用人群 本试卷适用于: - 计算机专业或信息技术相关专业的学生,用于课程学习或考试复习。 - 准备计算机等级考试或职业资格认证的人士,作为实战演练材料。 - 对计算机操作有兴趣的自学者,用于提升个人计算机应用技能。 - 计算机基础教育工作者,作为教学资源或出题参考。 ### 使用场景及目标 1. **学习评估**:作为学校或教育机构对学生计算机基础知识和应用技能的评估工具。 2. **自学测试**:供个人自学者检验自己对计算机知识的掌握程度和操作熟练度。 3. **职业发展**:帮助职场人士通过实际操作练习,提升计算机应用能力,增强工作竞争力。 4. **教学资源**:教师可以用于课堂教学,作为教学内容的补充或学生的课后练习。 5. **竞赛准备**:适合准备计算机相关竞赛的学生,作为强化训练和技能检测的材料。 试卷的目标是通过系统性的题目设计,帮助学生全面复习和巩固计算机基础知识,同时通过实际操作题目,提高学生解决实际问题的能力。通过本试卷的学习与练习,学生将能够更加深入地理解计算机的工作原理,掌握常用软件的使用方法,为未来的学术或职业生涯打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值