SpringMVC可以使用自己的拦截器对请求进行拦截处理。必须要实现HandlerInterceptor接口。
@Slf4j public class AuthorityInterceptor implements HandlerInterceptor{ @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(); //解析参数,具体的参数key以及value是什么,我们打印日志 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 = StringUtils.EMPTY; //request这个参数的map,里面的vaue返回的是一个StringBuffer[] Object obj = entry.getValue(); if(obj instanceof String[]){ String[] strs = (String[])obj; mapValue = Arrays.toString(strs); } requestParamBuffer.append(mapKey).append("=").append(mapValue); } if(StringUtils.equals(className, "UserManageController") && StringUtils.equals(methodName, "login")) { log.info("权限拦截器拦截到请求,className:{},methodName:{}", className,methodName); // 如果是拦截到登录请求,不打印参数,因为参数里面有密码,全部会打印到日志中,防止日志泄露 return true; } log.info("权限拦截器拦截到请求,className:{},methodName:{},param:{}", className,methodName,requestParamBuffer.toString()); User user = null; String loginToken = CookieUtil.readLoginToken(request); if(StringUtils.isNotEmpty(loginToken)){ // 根据token 从redis中获取user的信息 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(); //这里要添加reset,否则报异常 response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=UTF-8"); 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(); out.close();//geelynote 这里要关闭 } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("postHandle"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("afterCompletion"); } }
在SpringMVC配置文件中配置这个bean
<mvc:interceptors> <!-- 定义在这里的,所有的都会拦截--> <mvc:interceptor> <!--manage/a.do /manage/*--> <!--manage/b.do /manage/*--> <!--manage/product/save.do /manage/**--> <!--manage/order/detail.do /manage/**--> <mvc:mapping path="/manage/**"/> //配置拦截的路径 <!--<mvc:exclude-mapping path="/manage/user/login.do"/>--> //将登录请求排除在外 <bean class="com.mmall.controller.common.interceptor.AuthorityInterceptor" /> </mvc:interceptor> </mvc:interceptors>
第二种将登录请求排除在拦截器外的方法:在代码中排除
在preHandle这个方法中
if(StringUtils.equals(className, "UserManageController") && StringUtils.equals(methodName, "login")) { log.info("权限拦截器拦截到请求,className:{},methodName:{}", className,methodName); // 如果是拦截到登录请求,不打印参数,因为参数里面有密码,全部会打印到日志中,防止日志泄露 return true; }