设为首页 收藏本站
查看: 970|回复: 0

[经验分享] SpringMVC拦截器(资源和权限管理)

[复制链接]

尚未签到

发表于 2017-3-2 11:44:30 | 显示全部楼层 |阅读模式
  1.DispatcherServlet
    SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet。

  DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller来处理。  所以我们现在web.xml中加入以下配置:



       <!-- 初始化 DispatcherServlet时,该框架在 web应用程序WEB-INF目录中寻找一个名为[servlet-名称]-servlet.xml的文件,
并在那里定义相关的Beans,重写在全局中定义的任何Beans -->
<servlet>
<servlet-name>springMybatis</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMybatis</servlet-name>
<!-- 所有的的请求,都会被DispatcherServlet处理 -->
<url-pattern>/</url-pattern>
</servlet-mapping>

  2.静态资源不拦截
    如果只配置拦截类似于*.do格式的url,则对静态资源的访问是没有问题的,但是如果配置拦截了所有的请求(如我们上面配置的“/”),就会造成js文件、css文件、图片文件等静态资源无法访问。

      一般实现拦截器主要是为了权限管理,主要是拦截一些url请求,所以不对静态资源进行拦截。要过滤掉静态资源一般有两种方式,

      第一种是采用<mvc:default-servlet-handler
/>,(一般Web应用服务器默认的Servlet名称是"default",所以这里我们激活Tomcat的defaultServlet来处理静态文件,在web.xml里配置如下代码即可:)





        <!-- 该servlet为tomcat,jetty等容器提供,将静态资源映射从/改为/static/目录,如原来访问 http://localhost/foo.css ,现在http://localhost/static/foo.css -->
<!-- 不拦截静态文件 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/js/*</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/images/*</url-pattern>
<url-pattern>/fonts/*</url-pattern>
</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属性显示指定:






[html] view plain copy print?

  • <mvc:default-servlet-handler default-servlet-name="所使用的Web服务器默认使用的Servlet名称" />  
  
      第二种是采用<mvc:resources />,在springmvc的配置文件中加入以下代码:






[html] view plain copy print?

  • <mvc:resources mapping="/js/**" location="/static_resources/javascript/"/>   
  • <mvc:resources mapping="/styles/**" location="/static_resources/css/"/>   
  • <mvc:resources mapping="/images/**" location="/static_resources/images/"/>  
  

  3.自定义拦截器
  
    SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法。preHandle在业务处理器处理请求之前被调用,
postHandle在业务处理器处理请求执行完成后,生成视图之前执行,afterCompletion在DispatcherServlet完全处
理完请求后被调用,可用于清理资源等
。所以要想实现自己的权限管理逻辑,需要继承HandlerInterceptorAdapter并重写其三个方法。
    首先在springmvc.xml中加入自己定义的拦截器我的实现逻辑CommonInterceptor,






[html] view plain copy print?

  • <!--配置拦截器, 多个拦截器,顺序执行 -->  
  • <mvc:interceptors>   
  •     <mvc:interceptor>   
  •         <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->  
  •         <mvc:mapping path="/" />  
  •         <mvc:mapping path="/user/**" />  
  •         <mvc:mapping path="/test/**" />  
  •         <bean class="com.alibaba.interceptor.CommonInterceptor"></bean>   
  •     </mvc:interceptor>  
  •     <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->  
  • </mvc:interceptors>  
  

    我的拦截逻辑是“在未登录前,任何访问url都跳转到login页面;登录成功后跳转至先前的url”,具体代码如下:






[java] view plain copy print?

  • /**
  • *  
  • */  
  • package com.alibaba.interceptor;  

  • import javax.servlet.http.HttpServletRequest;  
  • import javax.servlet.http.HttpServletResponse;  

  • import org.slf4j.Logger;  
  • import org.slf4j.LoggerFactory;  
  • import org.springframework.web.servlet.ModelAndView;  
  • import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;  

  • import com.alibaba.util.RequestUtil;  


  • /**
  • * @author tfj
  • * 2014-8-1
  • */  
  • public class CommonInterceptor extends HandlerInterceptorAdapter{  
  •     private final Logger log = LoggerFactory.getLogger(CommonInterceptor.class);  
  •     public static final String LAST_PAGE = "com.alibaba.lastPage";  
  •     /*
  •      * 利用正则映射到需要拦截的路径     
  •       
  •     private String mappingURL;
  •      
  •     public void setMappingURL(String mappingURL) {     
  •                this.mappingURL = mappingURL;     
  •     }   
  •   */  
  •     /**  
  •      * 在业务处理器处理请求之前被调用  
  •      * 如果返回false  
  •      *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
  •      * 如果返回true  
  •      *    执行下一个拦截器,直到所有的拦截器都执行完毕  
  •      *    再执行被拦截的Controller  
  •      *    然后进入拦截器链,  
  •      *    从最后一个拦截器往回执行所有的postHandle()  
  •      *    接着再从最后一个拦截器往回执行所有的afterCompletion()  
  •      */   
  •     @Override   
  •     public boolean preHandle(HttpServletRequest request,   
  •             HttpServletResponse response, Object handler) throws Exception {   
  •         if ("GET".equalsIgnoreCase(request.getMethod())) {  
  •             RequestUtil.saveRequest();
  •         }
  •         log.info("==============执行顺序: 1、preHandle================");   
  •         String requestUri = request.getRequestURI();
  •         String contextPath = request.getContextPath();
  •         String url = requestUri.substring(contextPath.length());

  •         log.info("requestUri:"+requestUri);   
  •         log.info("contextPath:"+contextPath);   
  •         log.info("url:"+url);   

  •         String username =  (String)request.getSession().getAttribute("user");   
  •         if(username == null){  
  •             log.info("Interceptor:跳转到login页面!");  
  •             request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);  
  •             return false;  
  •         }else  
  •             return true;     
  •     }

  •     /**
  •      * 在业务处理器处理请求执行完成后,生成视图之前执行的动作   
  •      * 可在modelAndView中加入数据,比如当前时间
  •      */  
  •     @Override   
  •     public void postHandle(HttpServletRequest request,   
  •             HttpServletResponse response, Object handler,
  •             ModelAndView modelAndView) throws Exception {     
  •         log.info("==============执行顺序: 2、postHandle================");   
  •         if(modelAndView != null){  //加入当前时间   
  •             modelAndView.addObject("var", "测试postHandle");   
  •         }
  •     }

  •     /**  
  •      * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等   
  •      *   
  •      * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()  
  •      */   
  •     @Override   
  •     public void afterCompletion(HttpServletRequest request,   
  •             HttpServletResponse response, Object handler, Exception ex)
  •             throws Exception {   
  •         log.info("==============执行顺序: 3、afterCompletion================");   
  •     }

  • }
  注:上述代码里我写了一个RequestUtil,主要实现获取当前Request、Session对象,保存和加密页面,取出等功能。
  至此,拦截器已经实现了,效果如图:
  
我直接访问/test/hello,会被拦截

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-349285-1-1.html 上篇帖子: 关于Java Web应用中的配置部署描述符web.xml 下篇帖子: android 近百个源码项目【转】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表