SpringMVC自定义拦截器

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;
        }

 
 


猜你喜欢

转载自blog.csdn.net/anshengsuiyeu/article/details/80299279