100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Spring MVC拦截器配置以及统一登陆校验实现

Spring MVC拦截器配置以及统一登陆校验实现

时间:2020-03-10 23:16:41

相关推荐

Spring MVC拦截器配置以及统一登陆校验实现

拦截器概念

这里引用百度百科里面的说法,java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作

用途

日志记录:记录请求的一些信息和请求参数权限校验:如登陆校验,管理员权限校验性能监控:监控请求处理的时间通用行为:如读取cookie信息等

配置Spring MVC拦截器

配置 dispatch-servlet.xml

<mvc:interceptors><!-- 如果在interceptors中配置bean,那么所有定义在这里的bean都会被拦截--><!--<bean></bean>--><mvc:interceptor><mvc:mapping path="/manage/**"/><!--过滤登陆死循环情况--><!--<mvc:exclude-mapping path="/manage/login.do"/>--><bean class="com.mon.interceptor.AuthorityInterceptor"/></mvc:interceptor></mvc:interceptors>

分析配置中的节点
interceptors节点:这个节点是SpringMVC的拦截器集配置节点,在这个节点里面我们可以声明多个interceptorinterceptor节点:这个节点是配置拦截路径以及你拦截器实现类的节点

mapping节点:符合mapping路径匹配的请求都会经过拦截器exclude-mapping节点:符合exclude-mapping路径匹配的请求都不会经过拦截器bean节点:配置我们自己的实现类,实现类要实现HandlerInterceptor接口

path情况分析
如果要拦截同一个controller下的所有的请求,如/manage/***.do,path应该为/manage/*如果要拦截请求路径为manage包下不同controller的所有请求,如/manage/product/b.do/manage/order/list.do,path应该为/manage/**如果想要某个请求不走拦截器,那么可以配置exclude-mappingpath应该为具体的url,准确到方法,如/manage/login.do
spring MVC拦截器请求流程
spring请求流程具体如下:
浏览器/客户端发送请求给我们的服务器请求来到Spring的dispatchServlet进行请求分发dispatchServlet检查我们在dispatch-servlet.xml定义好的规则,按照规则判断请求是否走拦截器如果判断请求不走拦截器,请求直接分发到对应的controller(这里默认有对应的controller)如果判断请求是走拦截器的,就走我们自己实现的拦截器,验证请求,通过就放行,走到controller,反之则提前返回给客户端
spring请求流程图

实现拦截器示例(java)

这是自己实现的一个统一登陆校验拦截器,具体代码如下,写代码之前一定要根据自己的实际情况,把dispatch-servlet.xml中的拦截器路径配置好,不然拦截器无法正常工作

@Slf4jpublic class AuthorityInterceptor implements HandlerInterceptor{@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info(("preCompletion"));//请求中controller的方法名HandlerMethod handlerMethod = (HandlerMethod)handler;//解析handlermethod//获取方法名String methodName = handlerMethod.getMethod().getName();//获取类名,simplename是获取名字不带包名,name是带包名的String className = handlerMethod.getBean().getClass().getSimpleName();//解析参数StringBuffer stringBuffer = new StringBuffer();Map paramMap = request.getParameterMap();Iterator it = paramMap.entrySet().iterator();while ((it.hasNext())){Map.Entry entry = (Map.Entry) it.next();String mapKey = (String) entry.getKey();String mapValue = "";//request的这个参数map的value返回的是一个String[]Object obj = entry.getValue();if (obj instanceof String[]){String[] strs = (String[])obj;mapValue = Arrays.toString(strs);}stringBuffer.append(mapKey).append("=").append(mapValue);}//判断登陆,如果是登陆就放行if(StringUtils.equals(className, UserManageController.class.getSimpleName())&&StringUtils.equals(methodName,"login")){//登陆的时候不能把参数的日志也打上,如果日志泄露,账号密码就会泄露log.info("权限拦截器拦截到的请求 className{} methodName{}",className,methodName);return true;}//判断登陆User user = session.getAttribute(Const.CURRENT_USER);if(user == null )){//未登录,返回false,不会调用controller里面的方法//response必须重置重置,否则会宝getWritter() has already been called for this response//这里我们手动接管了SpringMVC原生的返回,而是托管到拦截器中返回response.reset();//这是返回编码,否者会乱码response.setCharacterEncoding("UTF-8");//设置返回值类型response.setContentType("application/json;chartset=UTF-8");PrintWriter out = response.getWriter();out.print("你想返回的错误信息")}out.flush();out.close();return false;}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info(("postCompletion"));}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info(("afterCompletion"));}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。