strut2知识点收拾

strut2知识点整理
   本文以struts2.3.16.1为例。
一、运行jar包
   A.asm-3.3.jar
   B.asm-commons-3.3.jar
   C.commons-fileupload-1.3.1.jar(文件上传必须插件)
   D.commons-io-2.2.jar(文件上传必须插件)
   E.commons-lang3-3.1.jar
   F.freemarker-2.3.19.jar
   G.javassist-3.11.0.GA.jar
   H.ognl-3.0.6.jar
   I.struts2-convention-plugin-2.3.16.1.jar(使用Annotation必须有些插件)
   J.struts2-core-2.3.16.1.jar
   K.xwork-core-2.3.16.1.jar

   web.xml添加如下配置
    
     <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>
          org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
     </filter>
     <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>/*</url-pattern>
     </filter-mapping>
     


二、OGNL(对象图导航语言)
    记录如下几种页面从Action中取值的情况。
    1、访问static属性:
<s:property value="@com.bean.StaticClass@STR"/><br>

    2、访问static方法:
       
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>

       
<s:property   value="@com.bean.StaticClass@static_method()"/><br>

    3、访问math函数:
<s:property value="@@max(2,3)"/><br>

    4、访问List:
<s:property value="list"/><br>

    5、访问List某个元素:
<s:property value="list[1]"/><br>

    6、访问List元素某个属性的集合:
<s:property value="list.{property}"/><br>

    7、访问List元素某个属性的集合中的特定值:
<s:property value="lsit[0].property"/>

    8、访问set:
<s:property value="set"/><br>

    访问set中某个元素(不能访问到,set无序):
<s:property value="set[1]"/><br>

    9、访问Map:
<s:property value="map"/><br>

    10、访问Map某个元素:
<s:property value="map.key"/><br>

    11、访问Map所有的key:
<s:property value="map.keys"/><br>

    12、访问Map所有的value:
<s:property value="map.values"/><br>


三、类型转换
    Struts2类型转换,对于8个基本类型和Date,String,由系统自动转换,对于用户自定义的对象,需要用户自定转换。
    1、自定义转换类继承DefaultTypeConverter或者StrutsTypeConverter,建议用后者。
    2、在Action所在文件夹建xxx-conversion.properties,例如Action为SampleAction,则   属性文件为SampleAction-convertion.properties。
    3、假设SampleAction中有自定义对象User user,则属性文件内容为:
       user=com.xxx.xxx.SampleAction-convertion.propeties
    4、如果是全局类型转换,则属性名称为xwork-convertion.properties,且些文件要放置在src目录下。

四、防止表单重复提交
    1、重定向。result返回类型为redirect,如果采用dispatch,地址栏URL不变,会导致数据的重复插入。
    2、通过session token。
    原理:客户端请求页面,服务器会通会Token标签生成一个随机数,且将该随机数放置在session中,然后将该随机数发向客户端。如果第一次提交,服务器会与客户端比较,相同,则认为第一次提交,并且更新服务器的随机数值;如果再次提交,两个随机数值不一致,则认为是重复提交。
    a.在<form>表单中加
<s:token></s:token>

    b.在action配置中加入:
     
<result name="invalid.token" location="error.jsp">
      <interceptor-ref name="token"/>


五、文件上传
    struts2通过拦截器FileUploadInterceptor处理文件上传。它会先将文件上传至临时目录,在Action中定义的file变量会指向临时目录文件,再由用户转向指定的文件目录,方法执行完毕后删除临时文件。相关配置变量:struts.multipart.savedir指定临时保存目录,如果该目录没有指定,则会保存在javax.servlet.context.tempdir目录下。其它相关配置可以在struts-default.properties寻找。
    1.JSP页面Form表单:
method="post" enctype="multitype/form-data"

    2.Action中定义相关变量。
    
 
      private File file;
      private String fileFileName;
      private fileContentType;
      

      如果页面有多个文件上传,则action定义如下
     
      private List<File> file;
      private List<String> fileFileName;
      private List<String> fileContentType;
      


六、文件下载
    struts2文件下载通过拦截器StreamResult处理。
    1.JSP页面直接用
<a href="download.action">文件下载</a>

    2.Action配置。参数“contentDisposition”必须要加上"attachment",如果不加,则默认为内联,浏览器默认会打开文件。
     
      @Action(value="downloadAction",results=            
      {@Result(name="success",type="stream",
      params={"inputName","downloadFile",
      "contentDisposition","attachment;filename=\"document.pdf\""})})
      

    3.Action中实现方法
    
 
     public InputStream getDownloadFile(){
         ServletActionContext.getServletContext().
                              getResourceAsStream("文件路径名");
     }
     


七、Struts2 Ajax
    Struts2在JSP页面采用ajax方式调用时,Action不需要配置返回值,直接返回null。
    1、返回XML代码
      
       HttpServletResponse response = ServletActionContext.getResponse();
       response.setContentType("text/xml;charset=utf-8");
       response.setHeader("cache-control","no-cache");
       PrintWriter out = response.getWriter();
       OutputFormat format = OutputFormat.creatPrettyPrint();
       format.setEncoding("utf-8");
       XmlWriter writer = new XmlWriter(out,format);
       writer.writer(document);
       out.flush();
       out.close();
       return null;
       

    2、返回JSON
      
       HttpServletResponse response = ServletActionContext.getResponse();
       response.setContentType("application/json;charset=utf-8");
       response.setHeader("cache-control","no-cache");
       PrintWriter out = response.getWriter();
       out.writer(document);
       out.flush();
       out.close();
       return null;
       


八、struts2处理JSON的另一种方式
    通过struts2插件处理。插件为struts2-json-plugin-2.2.1.jar
    1.struts.xml中,package必须要继承"json-default"(json-default已经继承了struts-default)。
    2.Action配置返回result时,type="json"
    3.在Action中定义成员变量,生成get,set方法。
    4.在配置result时,其中有个参数excludeProperties,可以排除某些指定的属性生成json。

九、struts拦截器
    struts2中有两种拦截器,一种可以用来拦截所有的请求,暂且叫对象拦截器吧,另一种可以用来拦截指定的方法。
    对象拦截器:
    1.拦截器实现Interceptor或者继承AbstractInterceptor。
    2.在struts.xml中配置拦截器信息
     
      <interceptors>
         <interceptor name="interceptor1" 
              class="com.interceptor.Interceptor1"></interceptor>
      </interceptors>
      

    3.在Action中引用配置的拦截器
     
interceptorRefs={@InterceptorRef("interceptor1")}

    方法拦截器:
    1.拦截器实现MethodFilterInterceptor.
    2.在struts.xml中配置拦截器信息
     
      <interceptor name="methodInterceptor"     
                   class="com.interceptor.MethodInterceptor">
          <param name="includeMethods">login</param>
    	  <param name="excludeMethods">login</param>
      </interceptor>
      

    3.在Action中引用配置的拦截器
     
interceptorRefs={@InterceptorRef("methodInterceptor")}

    4.对于includeMethods和excludeMethods两个参数。
      a.如果includeMethods指定要拦截的方法,则只会拦截指定的方法。
      b.如果excludeMethods指定了不需要拦截的方法,则不会拦截指定的方法。
      c.如果同一个方法同时出现在上面的两个参数中,则includeMethods优先级大于excludeMethos.

十、其它
   1.struts action中可以直接定义属性,也可以定义对象,或者实现model driven来获取页面对应的属性值。
   2.session获取。
     a.ServletActionContext.getRequest().getSession()
     b.ActionContext.getContext().getSession().返回map<String,String>.这样返回与上面一致,此方法脱离了容器获取值,对单元测试时有效。
   3.form表单提交动态绑定方法。需要将属性strtus.enable.DynamicMethodInvocation=true
     如:login.action!login(执行的方法名)