SpringMVC拦截器(资源和权限管理)

2023-11-14

原文地址:http://blog.csdn.net/tonytfjing/article/details/39207551


1.DispatcherServlet

    SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet。
    DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller来处理。  所以我们现在web.xml中加入以下配置:
  1. <!-- 初始化 DispatcherServlet时,该框架在 web应用程序WEB-INF目录中寻找一个名为[servlet-名称]-servlet.xml的文件,  
  2.          并在那里定义相关的Beans,重写在全局中定义的任何Beans -->  
  3.    <servlet>  
  4.      <servlet-name>springMybatis</servlet-name>  
  5.      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  6.      <load-on-startup>1</load-on-startup>  
  7.    </servlet>  
  8.    <servlet-mapping>  
  9.      <servlet-name>springMybatis</servlet-name>  
  10.      <!-- 所有的的请求,都会被DispatcherServlet处理 -->  
  11.      <url-pattern>/</url-pattern>  
  12.    </servlet-mapping>  

2.静态资源不拦截

       如果只配置拦截类似于*.do格式的url,则对静态资源的访问是没有问题的,但是如果配置拦截了所有的请求(如我们上面配置的“/”),就会造成js文件、css文件、图片文件等静态资源无法访问。
      一般实现拦截器主要是为了权限管理,主要是拦截一些url请求,所以不对静态资源进行拦截。要过滤掉静态资源一般有两种方式,
      第一种是采用<mvc:default-servlet-handler />,(一般Web应用服务器默认的Servlet名称是"default",所以这里我们激活Tomcat的defaultServlet来处理静态文件,在web.xml里配置如下代码即可:)
  1. <!-- 该servlet为tomcat,jetty等容器提供,将静态资源映射从/改为/static/目录,如原来访问 http://localhost/foo.css ,现在http://localhost/static/foo.css -->  
  2. <!-- 不拦截静态文件 -->  
  3. <servlet-mapping>  
  4.     <servlet-name>default</servlet-name>  
  5.     <url-pattern>/js/*</url-pattern>  
  6.     <url-pattern>/css/*</url-pattern>  
  7.     <url-pattern>/images/*</url-pattern>  
  8.     <url-pattern>/fonts/*</url-pattern>  
  9. </servlet-mapping>  

        Tomcat, Jetty, JBoss, and GlassFish  默认 Servlet的名字 -- "default"
        Resin 默认 Servlet的名字 -- "resin-file"
        WebLogic 默认 Servlet的名字  -- "FileServlet"
        WebSphere  默认 Servlet的名字 -- "SimpleFileServlet"
        
       如果你所有的Web应用服务器的默认Servlet名称不是"default",则需要通过default-servlet-name属性显示指定:
  1. <mvc:default-servlet-handler default-servlet-name="所使用的Web服务器默认使用的Servlet名称" />  

      第二种是采用<mvc:resources />,在springmvc的配置文件中加入以下代码:
  1. <mvc:resources mapping="/js/**" location="/static_resources/javascript/"/>    
  2. <mvc:resources mapping="/styles/**" location="/static_resources/css/"/>    
  3. <mvc:resources mapping="/images/**" location="/static_resources/images/"/>  


3.自定义拦截器

    SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法。preHandle在业务处理器处理请求之前被调用,
    postHandle在业务处理器处理请求执行完成后,生成视图之前执行,afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 。所以要想实现自己的权限管理逻辑,需要继承HandlerInterceptorAdapter并重写其三个方法。
    首先在springmvc.xml中加入自己定义的拦截器我的实现逻辑CommonInterceptor,
  1. <!--配置拦截器, 多个拦截器,顺序执行 -->  
  2. <mvc:interceptors>    
  3.     <mvc:interceptor>    
  4.         <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->  
  5.         <mvc:mapping path="/" />  
  6.         <mvc:mapping path="/user/**" />  
  7.         <mvc:mapping path="/test/**" />  
  8.         <bean class="com.alibaba.interceptor.CommonInterceptor"></bean>    
  9.     </mvc:interceptor>  
  10.     <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->  
  11. </mvc:interceptors>  


    我的拦截逻辑是“在未登录前,任何访问url都跳转到login页面;登录成功后跳转至先前的url”,具体代码如下:
  1. /** 
  2.  *  
  3.  */  
  4. package com.alibaba.interceptor;  
  5.   
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9. import org.slf4j.Logger;  
  10. import org.slf4j.LoggerFactory;  
  11. import org.springframework.web.servlet.ModelAndView;  
  12. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;  
  13.   
  14. import com.alibaba.util.RequestUtil;  
  15.   
  16.   
  17. /** 
  18.  * @author tfj 
  19.  * 2014-8-1 
  20.  */  
  21. public class CommonInterceptor extends HandlerInterceptorAdapter{  
  22.     private final Logger log = LoggerFactory.getLogger(CommonInterceptor.class);  
  23.     public static final String LAST_PAGE = "com.alibaba.lastPage";  
  24.     /* 
  25.      * 利用正则映射到需要拦截的路径     
  26.       
  27.     private String mappingURL; 
  28.      
  29.     public void setMappingURL(String mappingURL) {     
  30.                this.mappingURL = mappingURL;     
  31.     }    
  32.   */  
  33.     /**  
  34.      * 在业务处理器处理请求之前被调用  
  35.      * 如果返回false  
  36.      *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链 
  37.      * 如果返回true  
  38.      *    执行下一个拦截器,直到所有的拦截器都执行完毕  
  39.      *    再执行被拦截的Controller  
  40.      *    然后进入拦截器链,  
  41.      *    从最后一个拦截器往回执行所有的postHandle()  
  42.      *    接着再从最后一个拦截器往回执行所有的afterCompletion()  
  43.      */    
  44.     @Override    
  45.     public boolean preHandle(HttpServletRequest request,    
  46.             HttpServletResponse response, Object handler) throws Exception {    
  47.         if ("GET".equalsIgnoreCase(request.getMethod())) {  
  48.             RequestUtil.saveRequest();  
  49.         }  
  50.         log.info("==============执行顺序: 1、preHandle================");    
  51.         String requestUri = request.getRequestURI();  
  52.         String contextPath = request.getContextPath();  
  53.         String url = requestUri.substring(contextPath.length());  
  54.         
  55.         log.info("requestUri:"+requestUri);    
  56.         log.info("contextPath:"+contextPath);    
  57.         log.info("url:"+url);    
  58.           
  59.         String username =  (String)request.getSession().getAttribute("user");   
  60.         if(username == null){  
  61.             log.info("Interceptor:跳转到login页面!");  
  62.             request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);  
  63.             return false;  
  64.         }else  
  65.             return true;     
  66.     }    
  67.     
  68.     /** 
  69.      * 在业务处理器处理请求执行完成后,生成视图之前执行的动作    
  70.      * 可在modelAndView中加入数据,比如当前时间 
  71.      */  
  72.     @Override    
  73.     public void postHandle(HttpServletRequest request,    
  74.             HttpServletResponse response, Object handler,    
  75.             ModelAndView modelAndView) throws Exception {     
  76.         log.info("==============执行顺序: 2、postHandle================");    
  77.         if(modelAndView != null){  //加入当前时间    
  78.             modelAndView.addObject("var""测试postHandle");    
  79.         }    
  80.     }    
  81.     
  82.     /**  
  83.      * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等   
  84.      *   
  85.      * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()  
  86.      */    
  87.     @Override    
  88.     public void afterCompletion(HttpServletRequest request,    
  89.             HttpServletResponse response, Object handler, Exception ex)    
  90.             throws Exception {    
  91.         log.info("==============执行顺序: 3、afterCompletion================");    
  92.     }    
  93.   
  94. }    

    注:上述代码里我写了一个RequestUtil,主要实现获取当前Request、Session对象,保存和加密页面,取出等功能。

至此,拦截器已经实现了,效果如图:

我直接访问/test/hello,会被拦截


登录成功后会跳转至/test/hello对应的页面





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringMVC拦截器(资源和权限管理) 的相关文章

  • java.lang.ClassNotFoundException:javax.mail.MessagingException

    我想使用 eclipse 将电子邮件从我的 gmail 帐户发送到另一个邮件帐户 我使用 apache tomcat 7 0 34 作为我的 Web 服务器 并使用端口 8080 作为 apache 服务器 HTTP 1 1 并使用 JRE
  • 两个整数乘积的模

    我必须找到c c a b mod m a b c m 是 32 位整数 但 a b 可以超过 32 位 我正在尝试找出一种计算 c 的方法 而不使用 long 或任何 gt 32 位的数据类型 有任何想法吗 如果m是质数 事情可以简化吗 注
  • 与 Eclipse 中的 Java Content Assist 交互

    作为我的插件项目的一部分 我正在考虑与 Eclipse 在 Java 文件上显示的内容辅助列表进行交互 我正在尝试根据一些外部数据对列表进行重新排序 我看过一些有关创建新内容辅助的教程 但没有看到有关更改现有内容辅助的教程 这可能吗 如果是
  • 如何调试“com.android.okhttp”

    在android kitkat中 URLConnection的实现已经被OkHttp取代 如何调试呢 OkHttp 位于此目录中 external okhttp android main java com squareup okhttp 当
  • Android中如何使用JNI获取设备ID?

    我想从 c 获取 IMEIJNI 我使用下面的代码 但是遇到了未能获取的错误cls 它总是返回NULL 我检查了环境和上下文 它们都没有问题 为什么我不能得到Context班级 我在网上搜索了一下 有人说我们应该使用java lang Ob
  • java inputstream 打印控制台内容

    sock new Socket www google com 80 out new BufferedOutputStream sock getOutputStream in new BufferedInputStream sock getI
  • 如何在单个查询中搜索 RealmObject 的 RealmList 字段

    假设我有一堂课 public class Company extends RealmObject private String companyId private RealmList
  • 如何在.NET中使用java.util.zip.Deflater解压缩放气流?

    之后我有一个转储java util zip Deflater 可以确认它是有效的 因为 Java 的Inflater打开它很好 并且需要在 NET中打开它 byte content ReadSample sampleName var inp
  • 在Java中运行bat文件并等待

    您可能会认为从 Java 启动 bat 文件是一项简单的任务 但事实并非如此 我有一个 bat 文件 它对从文本文件读取的值循环执行一些 sql 命令 它或多或少是这样的 FOR F x in CD listOfThings txt do
  • Java继承,扩展类如何影响实际类

    我正在查看 Sun 认证学习指南 其中有一段描述了最终修饰符 它说 如果程序员可以自由地扩展我们所知的 String 类文明 它可能会崩溃 他什么意思 如果可以扩展 String 类 我是否不会有一个名为 MyString 的类继承所有 S
  • 蓝牙发送和接收文本数据

    我是 Android 开发新手 我想制作一个使用蓝牙发送和接收文本的应用程序 我得到了有关发送文本的所有内容逻辑工作 但是当我尝试在手机中测试它时 我看不到界面 这是Main Activity Code import android sup
  • JDBC 时间戳和日期 GMT 问题

    我有一个 JDBC 日期列 如果我使用 getDate 则会得到 date 仅部分2009 年 10 月 2 日但如果我使用 getTimestamp 我会得到完整的 date 2009 年 10 月 2 日 13 56 78 890 这正
  • 为什么\0在java中不同系统中打印不同的输出

    下面的代码在不同的系统中打印不同的输出 String s hello vsrd replace 0 System out println s 当我在我的系统中尝试时 Linux Ubuntu Netbeans 7 1 它打印 When I
  • 使用 HtmlUnit 定位弹出窗口

    我正在构建一个登录网站并抓取一些数据的程序 登录表单是一个弹出窗口 所以我需要访问这个www betexplorer com网站 在页面的右上角有一个登录链接 写着 登录 我单击该链接 然后出现登录弹出表单 我能够找到顶部的登录链接 但找不
  • 在 Spring 上下文中查找方法级自定义注释

    我想知道的是 所有的类 方法Spring http en wikipedia org wiki Spring Framework注释为 Versioned的bean 我创建了自定义注释 Target ElementType METHOD E
  • partitioningBy 必须生成一个包含 true 和 false 条目的映射吗?

    The 分区依据 https docs oracle com javase 8 docs api java util stream Collectors html partitioningBy java util function Pred
  • 子类构造函数(JAVA)中的重写函数[重复]

    这个问题在这里已经有答案了 为什么在派生类构造函数中调用超类构造函数时 id 0 当创建子对象时 什么时候在堆中为该对象分配内存 在基类构造函数运行之后还是之前 class Parent int id 10 Parent meth void
  • MiniDFSCluster UnsatisfiedLinkError org.apache.hadoop.io.nativeio.NativeIO$Windows.access0

    做时 new MiniDFSCluster Builder config build 我得到这个异常 java lang UnsatisfiedLinkError org apache hadoop io nativeio NativeIO
  • 由 Servlet 容器提供服务的 WebSocket

    上周我研究了 WebSockets 并对如何使用 Java Servlet API 实现服务器端进行了一些思考 我没有花费太多时间 但在使用 Tomcat 进行一些测试时遇到了以下问题 如果不修补容器或至少对 HttpServletResp
  • Spring RESTful控制器方法改进建议

    我是 Spring REST 和 Hibernate 的新手 也就是说 我尝试组合一个企业级控制器方法 我计划将其用作未来开发的模式 您认为可以通过哪些方法来改进 我确信有很多 RequestMapping value user metho

随机推荐

  • React ajax

    目录 前置说明 常用的ajax请求库 axios 相关API 配置代理 方法一 配置代理 方法二 案例 github用户搜索 ES6小知识点 解构赋值 重命名 消息订阅与发布机制 fetch发送请求 关注分离的设计思想 list组件 sea
  • 计算机组成原理(一)

    文章目录 常识 第一章 进制转换 1 10与2进制互转 法一 短除法 法二 按权展开法表示十进制 2 10转其他进制 3 2转8进制 4 8转2进制 5 2转16进制 6 16转2进制 第二章 一 数据类型 原码 补码 1 模 2 n 1次
  • MySQL8.0.19修改root密码

    在MySQL 8 04前 执行 SET PASSWORD PASSWORD 新密码 但是MySQL8 0 4开始 这样默认是不行的 因为之前 MySQL的密码认证插件是 mysql native password 而现在使用的是 cachi
  • Python打包成exe文件操作

    脚本一般都会用到一些第三方包 比如开发的脚本或小工具 如果发送别人是不能直接用的 他还需要安装python解释器 甚至还要安装我们用的那些第三方包太麻烦了 我们这边直接打包成exe文件可供于别人使用 会更加方便 具体操作 1 首先就是安装p
  • 分苹果问题

    题目大意 有N个苹果 要把这些苹果粉给2个人 使得这两个人得到的苹果重量差最小 先求得N个苹果的重量总和 分成两堆 差值最小 则有一堆大于或等于SUM 2 有一堆小于等于SUM 2 所以有for j sum 2 j gt w i j 只要d
  • error C1076: compiler limit: internal heap limit reached 【UE4出现C1076错误的解决方法】

    如果编译后出现以下问题 导致这个问题的原因是 预分配 头内存不足 可以通过 Zm114 多分配一些
  • docker下交叉编译环境配置

    为什么在docker中搭建开发环境 Docker 是一个开源的应用容器引擎 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中 然后发布到任何流行的 Linux 机器上 也可以实现虚拟化 容器是完全使用沙箱机制 相互之间不会有任何接口
  • matlab数学实验 课件,MATLAB数学实验课件.PPT

    摘要 第一章 Matlab入门 MATLAB数学实验 第八章 随机模拟和统计分析 第八章 随机模拟和统计分析 8 1 预备知识 概率和统计 8 2 概率和统计的MATLAB指令 8 3 计算实验 随机模拟 Monte Carlo算法 8 4
  • [Koishi] 实现简易QQ机器人

    以前使用的QQ机器人是千寻Bot为基础框架的 配置环境相较于Koishi复杂得多 在此记录一下使用Koishi的踩坑过程 目录 1 软件下载与安装 1 1下载 1 2安装 2 插件 2 1插件安装 2 2插件更新 2 3插件配置 2 3 1
  • python从MySQL数据库中读取数据

    import pymysql 连接数据库 link pymysql connect host 127 0 0 1 连接地址 连接本地默认 127 0 0 1 user root 用户名 passwd 密码 port 3306 端口 默认为3
  • CPU数据预取对软件性能的影响

    一 什么是预取 预取是指将内存中的指令和数据提前存放到cache L1 L2 L3 中 从而加快处理器执行速度 Cache预取可以通过硬件或者软件实现 也就是分为硬件预取和软件预取两类 硬件预取 是通过处理器中专门的硬件来实现的 该硬件监控
  • 除了 :还有哪些空白符实体(转载)

    除了 nbsp 还有哪些空白符实体
  • CentOS7安装OpenLDAP+MySQL+PHPLDAPadmin(本人测试通过)

    转载自 http www cnblogs com bigbrotherer p 7251372 html 安装环境 CentOS 7 1 安装和设置数据库 在CentOS7下 默认安装的数据库为MariaDB 属于MySQL数据库的一个分支
  • jlink烧录,多个jlink同时烧录多个板子

    查看jlink的序列号 S N 如下是59408473 然后使用JFlashSPI exe打开之后 填写进去这个序列号 最后保存为jflash文件
  • 密码学原语如何应用?解析单向哈希的妙用|第9论

    作者 廖飞强 来源 微众银行区块链 隐私数据如何验明真伪 区块链数据何以可信 如何快速检验海量数据是否被篡改 单向哈希在其中起到了什么作用 隐私数据的价值很大程度上源自其真实性 如何防止数据被恶意篡改 是隐私保护方案设计中不可忽视的关键目标
  • springboot整合shiro-登录失败次数限制(八)

    原文地址 转载请注明出处 https blog csdn net qq 34021712 article details 80461177 王赛超 这次讲讲如何限制用户登录尝试次数 防止坏人多次尝试 恶意暴力破解密码的情况出现 要限制用户登
  • sqli-labs靶场15-16关(基于POST时间盲注)

    第十五关 sqlmap方法 python2 sqlmap py u http 127 0 0 1 sqlilabs Less 15 id 1 data uname admin passwd 1 submit Submit current d
  • 快速解决数据库连接失败

    无法连接到数据库 以Microsoft SQL Server Management Studio为例 以下简称 SSMS 显示下图连接失败界面 处理方法 打开SQL Server配置管理器 会出现如图服务器状态关闭 此时只需重新启动服务状态
  • RFID标签技术变成仓储物流物流关键技术

    伴随着各种各样电子商务的全方位普及化和市场需求的愈来愈猛烈 怎样完成节约成本 提升工作效能变成持续提升的总体目标 根据创建物流仓储物流运行的自动化技术 信息化 智能化系统 RFID技术变成与公司信息化管理体系的无缝拼接的关键公路桥梁 保证R
  • SpringMVC拦截器(资源和权限管理)

    原文地址 http blog csdn net tonytfjing article details 39207551 1 DispatcherServlet SpringMVC具有统一的入口DispatcherServlet 所有的请求都