springMVC的全局拦截器
先说说为什么要使用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的全局拦截器的更多相关文章
- 9.springMVC中的拦截器
springMVC中的拦截器大概大致可以分为以下几个步骤去学习: 1.自定义一个类实现HandlerInterceptor接口,这里要了解其中几个方法的作用 2.在springMVC的配置文件中添加拦 ...
- SpringMVC中的拦截器
1. 自定义拦截器 实现HandlerInterceptor接口 拦截器一: package cn.rodge.ssm.interceptor;import javax.servlet.http.Ht ...
- 【SpringMVC学习11】SpringMVC中的拦截器
Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理.本文主要总结一下springmvc中拦截器是如何定义的,以及测试拦截器的执行情况和使用 ...
- (转)SpringMVC学习(十二)——SpringMVC中的拦截器
http://blog.csdn.net/yerenyuan_pku/article/details/72567761 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter, ...
- Struts2 全局拦截器、result 的实现
定义一个可以继承的包,在这个包里面写入自己常用的拦截器,于是就实现了全局拦截器的实现. 现在,我们定义一个专门用来继承的包: <!--专门提供前台继承的包--> <package n ...
- SpringMVC中的拦截器、过滤器的区别、处理异常
1. SpringMVC中的拦截器(Interceptor) 1.1. 作用 拦截器是运行在DispatcherServlet之后,在每个Controller之前的,且运行结果可以选择放行或拦截! 除 ...
- SpringMVC 学习笔记(拦截器的配置))
在设置SpringMVC的拦截器时,需要在SpringMVC中配置 拦截器对象,拦截器的的对象要 实现 HandlerInterceptor 接口 拦截器类的设置: public class inte ...
- struts2 全局拦截器,显示请求方法和參数
后台系统中应该须要一个功能那就是将每一个请求的url地址和请求的參数log出来,方便系统调试和bug追踪,使用struts2时能够使用struts2的全局拦截器实现此功能: import java.u ...
- wepy全局拦截器
wepy有支持全局拦截器,但是请求需要使用wepy.request().then(): 在app.wpy文件中配置以下内容,与data同级 constructor(){ super(); this.u ...
随机推荐
- [Codeforces741D]Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths——dsu on tree
题目链接: Codeforces741D 题目大意:给出一棵树,根为$1$,每条边有一个$a-v$的小写字母,求每个点子树中的一条最长的简单路径使得这条路径上的边上的字母重排后是一个回文串. 显然如果 ...
- 洛谷p2661信息传递题解
题目 这个题一眼看上去就是用并查集求最小环. 我们可以设两个数组分别是f,d分别表示该点的爸爸和该点到祖先的距离. 当该点的爸爸等于他时,那他肯定就是祖先. 此时信息就肯定传递完了,此时的整个图中(我 ...
- Quartus prime16.0 与modelsim ae 联调
前言 quartus和modelsim联调对仿真还是很方便的,当然最好是quartus干综合到烧录的活,modelsim单独仿真.而且ae版的性能比se版差. 流程: 1.配置modelsim ae路 ...
- 【转】gcc 编译使用动态链接库和静态链接库
1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...
- 「ZJOI2016」旅行者 解题报告
「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...
- HR_Two Strings
https://www.hackerrank.com/challenges/two-strings/problem?h_l=interview&playlist_slugs%5B%5D=int ...
- HDU5909Tree Cutting
题目大意 给定一颗树,每个点有点权,问对于每个m,有多少个联通块的权值异或和为m. 题解 解法1:可以考虑树形dp,设dp[u][i]表示以u为根的子树中u必须选,联通块权值异或值为i的联通块个数. ...
- Java复习总结——注解
注解 概念及作用 概念 注解即元数据,就是源代码的元数据 注解在代码中添加信息提供了一种形式化的方法,可以在后续中更方便的 使用这些数据 Annotation是一种应用于类.方法.参数.变量.构造器及 ...
- 20165223 学习基础和C语言基础调查
一.学习基础 1. 我所擅长的技能 从小我就对新鲜事物抱有浓厚的兴趣,因此多年来培养了许多爱好,对感兴趣的诸如绘画方面的国画.油画.素描.漫画等:音乐方面的钢琴.吉他.架子鼓等:运动方面的滑板.溜冰. ...
- Jupyter-Notebook 删除指定 kernel
原来是Python3+C# 查看列表jupyter kernelspec list 删除指定kernel:jupyter kernelspec remove icsharpkernel 删除成功:(刷 ...