Struts2的知识整理总结(四)

这次我们主要讲Struts2的拦截器;过滤器;上传;下载;Ognl表达式;值栈等. 其中这些都是比较重要的,希望大家认真学习,好好了解。


Struts2的应用总结(四)


一、Struts2的拦截器

原理

        * 拦截器就是AOP(Aspect-Oriented Programming)的一种实现。

        * 过滤器:过滤从客服端发送到服务器端请求的.

        * 拦截器:拦截对目标Action中的某些方法进行拦截.

        * 拦截器不能拦截JSP.

        * 拦截到Action中某些方法.


拦截器和过滤器的区别

   1)拦截器是基于JAVA反射机制的,而过滤器是基于函数回调的。

    2)过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器

    3)拦截器只能对Action请求起作用,而过滤器可以对几乎所有的请求起作用。

    4)在Action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次   

    * 拦截器 采用 责任链 模式

        > 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。

        > 责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行

    * 在struts2 中可以定义很多个拦截器,将多个拦截器按照特定顺序 组成拦截器栈 (顺序调用 栈中的每一个拦截器 )


Struts2的自定义拦截器

编写拦截器

需要实现Interceptor接口,实现接口中的三个方法。

    * interceptor接口有很多的实现类,编写最简单的方式就是继承AbstractInterceptor实现类。      

    * 代码例如:


       public String intercept(ActionInvocation invocation) throws Exception {
                User user = (User) ServletActionContext.getRequest().getSession().getAttribute("existUser");
                    if(user == null){
                        ActionSupport as = (ActionSupport) invocation.getAction();
                        as.addActionError("您没有登陆!");
                        return as.LOGIN;
                    }else{
                        // 放行
                        return invocation.invoke();
                    }
                }


需要在struts.xml中进行拦截器的配置

配置一共有两种方式

 第一种方式

            在<package>包中定义拦截器,出现在<package>包的上方

<interceptors>
             <interceptor name="loginInterceptor" class="cn.zlq.interceptor.LoginInterceptor"></interceptor>
</interceptors>

          在某个action中引入拦截器

       <interceptor-ref name="loginInterceptor"></interceptor-ref>

 第二种方式

        在<package>包中定义拦截器的时候,自己直接定义一个拦截器栈

        <interceptors>
                <interceptor name="loginInterceptor" class="cn.zlq.interceptor.LoginInterceptor"/>
                <interceptor-stack name="myStack">
                        <interceptor-ref name="loginInterceptor"/>
                        <interceptor-ref name="defaultStack"/>
                </interceptor-stack>
        </interceptors>

       在Action包中引入自己定义的拦截器栈

        <action name="book_*" class="cn.zlq.action.BookAction" method="{1}">
                <interceptor-ref name="myStack"/>
        </action>



二、Struts2的文件上传


Struts2框架的使用拦截器完成了文件上传

底层使用也是FileUpload开源的组件。

    * 提供FileUpload拦截器,用于解析multipart/form-data编码格式请求,解析上传文件的内容 

    * fileUpload拦截器 默认在 defaultStack 栈中, 默认会执行的 

    * 在Action中编写文件上传,需要定义三个属性

            文件类型File ,属性名与表单中file的name属性名一致.

            字符串类型String , 属性名:前段是name属性名一致 +ContentType;

            字符串类型String , 属性名:前段是name属性名一致+FileName;

        最后需要为上述的三个属性提供set方法。

        可以通过FileUtils提供 copyFile 进行文件复制,将上传文件 保存到服务器端 


文件上传中存在的问题

     * 先配置input逻辑视图

    * 在页面中显示错误信息

    * 文件上传的总大小默认值是2M,如果超过了2M,程序会报出异常。可以使用<s:actionError>来查看具体信息!

        > 解决总大小的设置,找到常量


           * struts.multipart.parser=jakarta       -- 默认文件上传解析器,就是FileUpload组件

           * struts.multipart.saveDir=             -- 文件上传的临时文件存储目录

           * struts.multipart.maxSize=2097152      -- 文件上传的最大值(总大小),默认是2M

        > 可以在struts.xml中设置常量,修改文件上传的默认总大小!!!

           <constant name="struts.multipart.maxSize" value="5000000"></constant>


通过拦截器来设置文件上传的一些属性

        先在<action>标签中引入文件上传的拦截器

        <interceptor-ref name="defaultStack">
            <!-- 设置单个上传文件的大小 -->
            <param name="fileUpload.maximumSize">2097152</param>
            <!-- 设置扩展名 -->
            <param name="fileUpload.allowedExtensions">.txt</param>
        </interceptor-ref>


多文件上传

   * 在Action中还是编写三个属性

        > 属性需要是数组或者List集合,这样就可以完成多文件上传了。        

        > 注意:是数组或者List集合        

        private File [] upload;             // 代表上传的文件

        private String [] uploadContentType;    // 代表文件的类型

        private String [] uploadFileName;       // 上传文件的名称

        提供属性的set方法


三、Struts2的文件下载


Action类必须要有返回结果,并且返回结果中必须要依赖stream结果类型。

   * 在<action>标签中配置stream的结果类型

   * 可以通过<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>源码发现有一些需要设置的属性。

       <result name="success" type="stream">
                 <param name="contentType">${contentType}</param>
                 <param name="contentDisposition">attachment;filename=${downFileName}</param>
                 <param name="inputName"></param>
        </result>

    上面的代码的${contentType}这种写法需要Action类提供对应的方法,对应的方法如下

       // 获取文件的MIME类型
        public String getContentType(){
            return ServletActionContext.getServletContext().getMimeType(filename);
        }       
        // 设置文件的输入流
        public InputStream getInputStream(){
         return ServletActionContext.getServletContext().getResourceAsStream("/download/"+filename);
        }
        // 设置Content-Disposition属性
        public String getDownFilename() throws IOException{
            String agent = ServletActionContext.getRequest().getHeader("User-Agent");
            return this.encodeDownloadFilename(filename, agent);
        }

解决下载文件中文乱码的问题

       public String encodeDownloadFilename(String filename, String agent) throws IOException{
                if(agent.contains("Firefox")){ // 火狐浏览器
                        filename = "=?UTF-8?B?"+new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?=";
                        }else{ // IE及其他浏览器
                                        filename = URLEncoder.encode(filename,"utf-8");
                                }

                        return filename;
            }





下一章节:Struts2的知识整理总结 (五)——值栈与OGNL表达式

上一章节:Struts2的知识整理总结(三)—— 数据封装和类型转换



猜你喜欢

转载自blog.csdn.net/qq_25814003/article/details/53548268
今日推荐