先说说为什么要使用springMVC的全局拦截器,比如 当我们在访问接口的时候,我们一般都会先判断这个用户是否登陆,我们就要在每个接口的前面都要判断一下,想想是不是很蛋疼,那工作量。。。

这时候,我们需要一个拦截器,他的作用就是,在每个请求的时候会先被它拦截,同时,还会得到request、response、请求url等等参数。

是不是很炫酷

话不多说,直接上代码

这个类是springMVC给我们实现的,只需要继承 HandlerInterceptorAdapter 类就可以了

HttpInterceptor.java
package com.mmall.controller.common.interceptor;

import com.google.common.collect.Maps;
import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.pojo.User;
import com.mmall.util.CookieUtil;
import com.mmall.util.JsonUtil;
import com.mmall.util.RedisShardedPoolUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map; /**
* Created by 敲代码的卡卡罗特
*/ public class AuthorityInterceptor implements HandlerInterceptor { private Logger logger = LoggerFactory.getLogger(AuthorityInterceptor.class); @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//请求controller中的方法名 HandlerMethod handlerMethod = (HandlerMethod)handler; //解析HandlerMethod String methodName = handlerMethod.getMethod().getName();
String className = handlerMethod.getBean().getClass().getSimpleName(); StringBuffer requestParamBuffer = 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);
}
//只是得到请求参数然后拼接成字符串
requestParamBuffer.append(mapKey).append("=").append(mapValue);
} //对于拦截器中拦截manage下的login.do的处理,对于登录不拦截,直接放行
if(StringUtils.equals(className,"UserManageController") && StringUtils.equals(methodName,"login")){
logger.info("权限拦截器拦截到请求,className:{},methodName:{}",className,methodName);//如果是拦截到登录请求,不打印参数,因为参数里面有密码,全部会打印到日志中,防止日志泄露
return true;
} logger.info("权限拦截器拦截到请求,className:{},methodName:{},param:{}",className,methodName,requestParamBuffer); // User user = (User)request.getSession().getAttribute(Const.CURRENT_USER); User user = null;
String loginToken = CookieUtil.readLoginToken(request);
if(StringUtils.isNotEmpty(loginToken)){
String userJsonStr = RedisShardedPoolUtil.get(loginToken);
user = JsonUtil.string2Obj(userJsonStr,User.class);
} if(user == null || (user.getRole().intValue() != Const.Role.ROLE_ADMIN)){
//返回false.即不会调用到controller里的方法
response.reset();//geelynote 这里要添加reset,否则报异常 getWriter() has already been called for this response
response.setCharacterEncoding("UTF-8");//geelynote 这里要设置编码,否则会乱码
// response.setContentType("text/html;charset=utf-8");
response.setContentType("application/json;charset=UTF-8");//geelynote 这里要设置返回值类型,因为全部是json接口。 PrintWriter out = response.getWriter(); //上传由于富文本的控件要求,要特殊处理返回值,这里面区分是否登录以及是否有权限
if(user == null){
if(StringUtils.equals(className,"ProductManageController") && (StringUtils.equals(methodName,"richtextImgUpload") )){
Map resultMap = Maps.newHashMap();
resultMap.put("success",false);
resultMap.put("msg","请登录管理员");
out.print(JsonUtil.obj2String(resultMap));
}else{
out.print(JsonUtil.obj2String(ServerResponse.createByErrorMessage("拦截器拦截,用户未登录")));
} }else{
if(StringUtils.equals(className,"ProductManageController") && (StringUtils.equals(methodName,"richtextImgUpload") )){
Map resultMap = Maps.newHashMap();
resultMap.put("success",false);
resultMap.put("msg","无权限操作");
out.print(JsonUtil.obj2String(resultMap)); }else{
out.print(JsonUtil.obj2String(ServerResponse.createByErrorMessage("拦截器拦截,用户无权限操作")));
}
} out.flush();//geelynote 这里要关闭流
out.close(); //geelynote
return false;//这里虽然已经输出,但是还会走到controller,所以要return false
}
return true;
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
} }

解释一下上面的方法,一共需要实现三个方法。第一个方法意思是,每次请求之前先被它拦截到,然后返回true的时候继续实现我们controller层的业务,接口完成之后会继续到第二个方法,然后再到第三个方法。

那第二个方法和第三个方法有什么区别呢?????

第二个方法是controller层不报错的情况下才会走这个方法,如果报错就不走,但是第三个方法肯定会走。

方法里面的业务逻辑是我随便写的,可以忽略,就是得到request的url和参数。然后日志记录下 然后判断是否登陆,是否是管理员,然后会根据一些特殊的请求的url和方法做一些特殊的处理 比如说 请求登陆接口的时候就放行 等等~~~

最后,我们需要在spring-servlet.xml中声明一下

<mvc:interceptors>     
<!-- 定义在这里会拦截指定的请求url -->
<mvc:mapping path="/manage/**"/>
<bean class="com.mmall.common.HttpInterceptor" />
</mvc:interceptors>

注意一下:这里面你可以在拦截器里面写具体拦截或者不拦截的方法也可以在spring-servlet.xml中写

大功告成!!!

springMVC的全局拦截器的更多相关文章

  1. 9.springMVC中的拦截器

    springMVC中的拦截器大概大致可以分为以下几个步骤去学习: 1.自定义一个类实现HandlerInterceptor接口,这里要了解其中几个方法的作用 2.在springMVC的配置文件中添加拦 ...

  2. SpringMVC中的拦截器

    1. 自定义拦截器 实现HandlerInterceptor接口 拦截器一: package cn.rodge.ssm.interceptor;import javax.servlet.http.Ht ...

  3. 【SpringMVC学习11】SpringMVC中的拦截器

    Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理.本文主要总结一下springmvc中拦截器是如何定义的,以及测试拦截器的执行情况和使用 ...

  4. (转)SpringMVC学习(十二)——SpringMVC中的拦截器

    http://blog.csdn.net/yerenyuan_pku/article/details/72567761 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter, ...

  5. Struts2 全局拦截器、result 的实现

    定义一个可以继承的包,在这个包里面写入自己常用的拦截器,于是就实现了全局拦截器的实现. 现在,我们定义一个专门用来继承的包: <!--专门提供前台继承的包--> <package n ...

  6. SpringMVC中的拦截器、过滤器的区别、处理异常

    1. SpringMVC中的拦截器(Interceptor) 1.1. 作用 拦截器是运行在DispatcherServlet之后,在每个Controller之前的,且运行结果可以选择放行或拦截! 除 ...

  7. SpringMVC 学习笔记(拦截器的配置))

    在设置SpringMVC的拦截器时,需要在SpringMVC中配置 拦截器对象,拦截器的的对象要 实现 HandlerInterceptor 接口 拦截器类的设置: public class inte ...

  8. struts2 全局拦截器,显示请求方法和參数

    后台系统中应该须要一个功能那就是将每一个请求的url地址和请求的參数log出来,方便系统调试和bug追踪,使用struts2时能够使用struts2的全局拦截器实现此功能: import java.u ...

  9. wepy全局拦截器

    wepy有支持全局拦截器,但是请求需要使用wepy.request().then(): 在app.wpy文件中配置以下内容,与data同级 constructor(){ super(); this.u ...

随机推荐

  1. BZOJ2434 [NOI2011] 阿狸的打字机 【树链剖分】【线段树】【fail树】【AC自动机】

    题目分析: 画一下fail树,就会发现就是x的子树中属于y路径的,把y剖分一下,用线段树处理 $O(n*log^2 n)$. 代码: #include<bits/stdc++.h> usi ...

  2. Minimum number of steps CodeForces - 805D(签到题)

    D. Minimum number of steps time limit per test 1 second memory limit per test 256 megabytes input st ...

  3. spfa优化板子

    用双端队列,当待加入元素小于队首元素时 加入队首, 否则 加入队尾 slf优化 if(!vis[e.v]) { if(Q.empty()) Q.push_front(e.v); else { if(d ...

  4. Hdoj 2084.数塔 题解

    Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大 ...

  5. JAVA 获取指定网址的IP地址 实例

    如今买票是一大难事,在高峰时段 打开12306网站,慢的像蜗牛,想到以前用修改hosts文件来登录Google(Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址 ...

  6. 【BZOJ4771】七彩树(主席树)

    [BZOJ4771]七彩树(主席树) 题面 BZOJ 题解 如果没有深度限制,每次只询问子树内的颜色个数,除了树套树\(dfs\)序加前驱或者后继强行二维数点之外,还有这样一种做法: 把所有相同颜色的 ...

  7. 【转】STM32三种启动模式

    @2018-12-16 [小记] STM32 启动区域 STM32三种启动模式 借助上述文章理解官方文档<一种从用户代码调用系统存储器中 Bootloader 的方法 >

  8. 【转】非常实用的高频PCB电路设计70问

    1.如何选择PCB 板材? 选择PCB 板材必须在满足设计需求和可量产性及成本中间取得平衡点.设计需求包含电气和机构这两部分.通常在设计非常高速的 PCB 板子(大于 GHz 的频率)时这材质问题会比 ...

  9. luogu4093 序列 (cdq分治优化dp)

    设f[i]是以i位置为结尾的最长满足条件子序列的长度 那么j能转移到i的条件是,$j<i , max[j]<=a[i] , a[j]<=min[i]$,其中max和min表示这个位置 ...

  10. Composer 安装时要求输入授权用户名密码?

    D:\work\dreamland-yii>composer require "saviorlv/yii2-dysms:dev-master" Authentication ...