• Java实战之01Struts204拦截器、上传下载、OGNL表达式


    十二、Struts2中的拦截器

    1、拦截器的重要性

    Struts2中的很多功能都是由拦截器完成的。比如:servletConfigstaticParamparamsmodelDriven等等。

    AOP编程思想的一种应用形式。

    2、拦截器的执行时机:

    \

    3、自定义拦截器

    3.1、拦截器的类试图(初级版本)

    3.2、编写步骤:

    a、编写一个类,继承AbstractInterceptor类或者实现Interceptor接口。重写intercept方法。

     1 public class MyInterceptorDemo1 extends AbstractInterceptor {
     2 
     3     public String intercept(ActionInvocation invocation) throws Exception {
     4         System.out.println("MyInterceptorDemo1拦截了:访问动作之前");
     5         //放行的含义:如果有下一个拦截器,则执行下一个拦截器。如果该拦截器是最后一个,则执行动作方法。
     6         String rtValue = invocation.invoke();//此行是放行的方法
     7         System.out.println("MyInterceptorDemo1拦截器"+rtValue);
     8         System.out.println("MyInterceptorDemo1拦截了:访问动作之后");
     9         return rtValue;
    10     }
    11 
    12 }

    b、配置拦截器:注意拦截器必须先声明再使用

     1             a、声明拦截器
     2                 <interceptors>
     3                     <interceptor name="myInterceptor1" class="cn.itcast.web.interceptors.MyInterceptorDemo1"></interceptor>
     4                 </interceptors>
     5             b、使用拦截器
     6                 <action name="action1" class="cn.itcast.web.action.Demo1Action" method="demo1">
     7                     <!-- 使用拦截器。当我们配置了一个拦截器之后,默认的拦截器栈就失效了-->
     8                     <interceptor-ref name="myInterceptor1"></interceptor-ref>
     9                     <result name="success">/success.jsp</result>
    10                 </action>

    3.3、执行顺序

    3.4、多个拦截器的执行顺序

    3.5intercept方法的返回值

    4、拦截器的应用:

    4.1、检查登录的拦截器案例

    配置文件:

     1 <package name="myDefault" extends="struts-default" abstract="true">
     2         <interceptors>
     3             <interceptor name="checkLoginInterceptorDemo2" class="cn.itcast.web.interceptors.CheckLoginInterceptorDemo2"></interceptor>
     4             <interceptor-stack name="myDefaultStack">
     5                 <interceptor-ref name="checkLoginInterceptorDemo2"></interceptor-ref>
     6                 <interceptor-ref name="defaultStack"></interceptor-ref>
     7             </interceptor-stack>
     8         </interceptors> 
     9         <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
    10         <global-results>
    11             <result name="login">/login.jsp</result>
    12         </global-results>
    13     </package>
    14     <package name="bbs" extends="myDefault">
    15         <action name="showMain" class="cn.itcast.web.action.BBSAction" method="showMain">
    16             <result name="success">/main.jsp</result>
    17         </action>
    18         <action name="showOther" class="cn.itcast.web.action.BBSAction" method="showOther">
    19             <result name="success">/other.jsp</result>
    20         </action>        
    21         <action name="login" class="cn.itcast.web.action.BBSAction" method="login">
    22             <interceptor-ref name="myDefaultStack">
    23                     <!-- 为拦截器注入参数,告知拦截器要排除的方法 -->
    24                     <param name="checkLoginInterceptorDemo2.excludeMethods">login</param>
    25             </interceptor-ref>
    26             <result name="success" type="redirectAction">showMain</result>
    27         </action>
    28     </package>

    动作类:

    1 public class Demo1Action extends ActionSupport {
    2 
    3     public String demo1(){
    4         System.out.println("Demo1Action的demo1方法执行了");
    5         return SUCCESS;
    6     }
    7 }

    拦截器:

     1 public class CheckLoginInterceptorDemo1 extends AbstractInterceptor {
     2 
     3     public String intercept(ActionInvocation invocation) throws Exception {
     4         Object obj = ServletActionContext.getRequest().getSession().getAttribute("userinfo");
     5         if(obj == null){
     6             return "login";
     7         }
     8         return invocation.invoke();//放行
     9     }
    10 
    11 }

    页面:

     1 <html>
     2   <head>
     3     <title>用户登录</title>
     4   </head>
     5   <body>
     6        <form action="${pageContext.request.contextPath}/login.action">
     7            用户名:<input type="text" name="username"/><br/>
     8            <input type="submit" value="登录"/>
     9        </form>
    10   </body>
    11 </html>

    4.2、案例中的问题

    问题:由于我们写了自己的拦截器,默认的拦截器不起作用了。

    解决办法:

    需要通过AbstractInterceptor类的子类入手,通过查看发现,该类还有一个子类是抽象的:

    所以我们在自定义拦截器时,还可以继承MethodFilterInterceptor并且重写doIntercept方法。

     1 public class CheckLoginInterceptorDemo2 extends MethodFilterInterceptor {
     2 
     3     public String doIntercept(ActionInvocation invocation) throws Exception {
     4         Object obj = ServletActionContext.getRequest().getSession().getAttribute("userinfo");
     5         if(obj == null){
     6             return "login";
     7         }
     8         return invocation.invoke();//放行
     9     }
    10 
    11 }

    并且在struts的配置文件中,配置需要拦截哪些方法,和需要放过哪些方法。

    4.3、拦截器类视图(全):

    十三、文件的上传(拦截器)和下载(stream结果类型)

    1、文件上传

    必要前提:

    a.表单method必须是post

    b.enctype取值必须是multipart/form-data

    c.提供文件选择域。

    动作类:

     1 public class UploadAction extends ActionSupport {
     2 
     3     private String username;
     4     private File photo;
     5     //struts2框架会为我们提供一个变量,用于保存文件名。
     6     private String photoFileName;//该变量的命名规则有要求:必须是文件变量的名称+FileName。严格区分大小写。
     7     
     8     
     9     public String upload()throws Exception{
    10         //1.获取文件要写到服务器的位置
    11         String basePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/uploads");
    12         //2.判断目录是否存在
    13         File file = new File(basePath);
    14         if(!file.exists()){
    15             file.mkdirs();
    16         }
    17         //3.写文件
    18         /*
    19          * 拷贝:是使用临时文件,复制一份到指定目录
    20          * FileUtils
    21          *      它是apache提供commons-io的jar包中一个类。
    22          * copyFile方法:
    23          *       把参数1复制到指定位置,指定位置是由参数2决定的
    24          * 参数:
    25          *      第一个:源文件
    26          *     第二个:目标文件
    27          * 
    28          * 弊端:
    29          *     会保存两份文件,一份是临时文件,一份是实际写的文件
    30          */
    31         //FileUtils.copyFile(photo, new File(file,photoFileName));
    32         /*
    33          * 剪切:是把临时文件重命名后,存到指定目录(一般采用此种方式)
    34          * 比复制的好处就是:只会保留一份文件
    35          */
    36         photo.renameTo(new File(file,photoFileName));
    37         return SUCCESS;
    38     }

    2、文件上传的配置

    2.1、文件上传大小限制(默认是2MB

    如果上传文件超过了默认大小,upload拦截器会转向一个input的逻辑视图。

    改变上传文件大小限制:

    1 <!-- 改变上传文件大小限制的方式:只能用修改常量的方式 -->
    2     <constant name="struts.multipart.maxSize" value="10485760"></constant>

    2.2、限制文件上传的类型

    a、通过限制上传文件的扩展名

       思路:给fileUpload拦截器注入参数

     1 <action name="upload" class="cn.itcast.web.action.UploadAction" method="upload">
     2             <!-- 给上传文件的拦截器注入参数,限制上传文件的大小
     3             此种方式无法限制上传文件的大小
     4             <interceptor-ref name="defaultStack">
     5                 <param name="fileUpload.maximumSize">10485760</param>
     6             </interceptor-ref> -->
     7             <interceptor-ref name="defaultStack">
     8                 <!-- 限制文件的扩展名 -->
     9                 <param name="fileUpload.allowedExtensions">.jpg,.png,.jpeg,.bmp</param>
    10                 <!-- 限制文件的MIME类型 -->
    11                 <param name="fileUpload.allowedTypes">image/jpeg,image/png,image/pjpeg</param>
    12             </interceptor-ref>
    13             <result name="success">/success.jsp</result>
    14             <result name="input">/index.jsp</result>
    15         </action>

    3、文件下载:其实就是一种结果类型(Stream

    动作类:

     1 public String download() throws Exception{
     2         //3.找到要下载文件的路径
     3         String basePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/uploads");
     4         //4.使用文件路径+文件名称,构建字节输入流
     5         fileName = "4O5A3624.jpg";//实际开发中是从数据库中查出来的
     6         inputStream = new FileInputStream(basePath+File.separator+fileName);
     7         //5、返回一个成功
     8         return SUCCESS;
     9         /*
    10          * 6.剩下的事,都交给struts2框架。是框架的stream的结果类型为我们实现的
    11          * 我们需要给stream结果类型提供参数
    12          *     <result name="success" type="stream">
    13                 <!-- 给结果类型注入参数:两个头 一个流 -->
    14                 <param name="contentType">application/octet-stream</param>
    15                 <param name="contentDisposition">attachment;filename=1.jpg</param>
    16                 <param name="inputStream">inputStream</param>
    17             </result>
    18          */
    19     }

    配置文件:

    1 <action name="download" class="cn.itcast.web.action.DownLoadAction" method="download">
    2             <result name="success" type="stream">
    3                 <!-- 给结果类型注入参数:两个头 一个流 -->
    4                 <param name="contentType">application/octet-stream</param>
    5                 <param name="contentDisposition">attachment;filename=1.jpg</param>
    6                 <param name="inputStream">inputStream</param>
    7             </result>
    8         </action>

    十四、OGNL简介

    1、什么是OGNL

    OGNLObject Graphic Navigation Language(对象图导航语言)的缩写,它是一个单独的开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

    2OGNL的功能

    前提:OGNLstruts2整合的一个开源项目,所以在struts2中,要想使用OGNL表达式,必须使用Struts2标签库

    2.1、支持普通方法的调用

     1   <body>
     2     <%--s:property标签
     3             作用:把该标签中value属性的值所对应的内容输出到浏览器上。
     4             属性:
     5                 value:取值不是一个普通的字符串,而是一个OGNL表达式。
     6                            它是去一个位置查找数据去了,把找到的结果显示出来。
     7     --%>
     8     <s:property value="OGNL-Expression"/><br/>
     9     <%--使用引号,把value的值括起来,取值将变成一个普通的字符串 --%>
    10     <s:property value="'OGNL-Expression'"/><br/>
    11     <%--支持普通方法调用 --%>
    12     <s:property value="'OGNL-Expression'.length()"/><br/>
    13     <s:property value="'OGNL-Expression'.toUpperCase()"/><br/>
    14     <s:property value="'OGNL-Expression'.split('-')[0]"/><hr/>
    15     <%--OGNL还可以访问静态属性 
    16         @包名.包名.类名@属性名称
    17         例如:
    18             @java.lang.Integer@MAX_VALUE
    19     --%>
    20     <s:property value="@java.lang.Integer@MAX_VALUE"/>
    21     <hr/>
    22     <%--OGNL还可以调用静态方法 
    23         @包名.包名.类名@方法名称
    24         例如:
    25             @java.lang.Math@random()
    26     --%>
    27     <s:property value="@java.lang.Math@random()"/>
    28     <hr/>
    29     <%--OGNL操作集合对象
    30         s:radio标签的list属性取值是一个OGNL表达式。
    31         {'男','女'}就相当于创建了一个List集合,里面包含了两个元素
    32      --%>
    33     <s:radio list="{'男','女'}" name="gender" label="性别"></s:radio>
    34     <hr size="50px" color="gray"/>
    35     <%--OGNL操作map对象 
    36         #{'male':'男','female':'女'}就相当于创建了一个map。冒号左侧的作为key,冒号右侧的作为value。
    37         在生成浏览器认识的html标签时:
    38             会把map的key给html标签的value赋值
    39             把map的value作为文本显示在页面上
    40             
    41         例如:
    42         <input type="radio" value="male">43         <input type="radio" value="female">44     --%>
    45     <s:radio list="#{'male':'男','female':'女'}" name="gender" label="性别"></s:radio>
    46   
    47   </body>

    (EL表达式只能调用静态方法)

  • 相关阅读:
    KMP算法理解
    vimium 快捷键
    如何选择优化器 optimizer
    用python实现归并排序
    用python实现快速排序
    用python实现插入排序
    使用PyCharm进行远程开发和调试
    查看python iterpreter的路径和当前选择的解释器
    grid search
    一些书单
  • 原文地址:https://www.cnblogs.com/minihouseCoder/p/5589333.html
Copyright © 2020-2023  润新知