首页 > 编程知识 正文

springmvc流程,spring 权限管理

时间:2023-05-04 01:55:16 阅读:154570 作者:2094

1.DispatcherServlet

SpringMVC具有统一的门户dispatcher servlet,所有请求都通过dispatcher servlet。

dispatcher servlet是一个前端控制器,位于web.xml文件中。 被阻止的请求由servlet自己定义块匹配规则,根据某个规则将被阻止的请求分发到目标控制器进行处理。 现在,将以下配置添加到web.xml中:

! 初始化- dispatcher servlet时,框架将在web APP应用程序的WEB-INF目录中查找名为[ servlet-name ]-servlet.XML的文件,并定义其关联的Beans 全局定义的bean-- servlet servlet-namespringmybatis/重写servlet-name servlet-class org.spring framework.web.servlet.diss ion servlet-class load-on-startup1/load-stup servlet servlet-mapping servlet-namespringmybatis/servlet-namagespring -所有请求都由dispatcher servlet处理--- UE

2.静态资源不拦截

如果配置为仅阻止url (如*.do格式),则可以访问静态资源,但如果配置为阻止所有请求(如上面配置的“/”),则静态资源(如js文件、css文件和图像文件)

实现典型的拦截器主要是为了权限管理,主要是阻止一些url请求,因此不会阻止静态资源。 过滤静态资源一般有两种方法。

第一种采用MVC : default-servlet-handler /。 (由于典型web APP应用程序服务器的缺省servlet名称为“default”,因此现在将激活Tomcat的defaultServlet

! -这个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 -。

Tomcat,Jetty,JBoss,and GlassFish的默认servlet的名称-- 'default '

Resin默认servlet的名称-- 'resin-file '

WebLogic默认servlet的名称--' file servlet '

WebSphere默认servlet的名称-- 'SimpleFileServlet '

如果所有web APP应用程序服务器的缺省servlet名称不是" default ",则必须在“default-servlet-name属性”视图中指定。

MVC : default-servlet-handler default-servlet-name='使用的Web服务器缺省servlet名称' /

第二,使用mvc:resources /,将以下代码添加到springmvc配置文件中:


<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,
<!--配置拦截器, 多个拦截器,顺序执行 --> <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”,具体代码如下:
/** * */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,会被拦截


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



版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。