在上一篇 SpringAOP 实现功能权限校验功能 中虽然用AOP通过抛异常,请求转发等勉强地实现了权限验证功能,但感觉不是那么完美,应该用拦截器来实现才是最佳的,因为拦截器就是用来拦截请求的,在请求层面进行权限验证是最好的时机。

假设下面的请求需要进行权限验证,在请求中通过参数params指定必须带有Helper.PARAM_FUNCTION_ID参数,这样拦截器通过判断是否带有该参数,如果带有则进行权限验证,否则不作处理。

@RequestMapping(value = "/moduleAccess.do",params=Helper.PARAM_FUNCTION_ID, method = RequestMethod.POST, produces="text/html;charset=utf-8")
@ResponseBody
public String moduleAccess(String action,FrmModule module) {
int rs = -1;
try{
if(Helper.F_ACTION_CREATE.equals(action)){
rs = moduleService.access(module,Helper.DB_ACTION_INSERT);
//module.setModuleid(rs);
module = moduleService.selectByPrimaryKey(rs);
}else if(Helper.F_ACTION_EDIT.equals(action)){
rs = moduleService.access(module,Helper.DB_ACTION_UPDATE);
module = moduleService.selectByPrimaryKey(module.getModuleid());
}else if(Helper.F_ACTION_REMOVE.equals(action)){
rs = moduleService.access(module,Helper.DB_ACTION_DELETE);
}else{
return JSON.toJSONString(new Result(false,"请求参数错误:action"));
}
}catch(Exception e){
e.printStackTrace();
return JSON.toJSONString(new Result(false,"操作失败,出现异常,请联系管理员!"));
}
if(rs<0){
return JSON.toJSONString(new Result(false,"操作失败,请联系管理员!"));
}
return JSON.toJSONString(new Result(true,module));
}

那么对应的拦截器就直接用登录验证的那个拦截器即可,SecurityInterceptor

package com.jykj.demo.filter;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import com.alibaba.fastjson.JSON;
import com.jykj.demo.entity.SysUser;
import com.jykj.demo.service.SysUserRolePermService;
import com.jykj.demo.util.Helper;
import com.jykj.demo.util.Result;
/**
* 1.此拦截器用于拦截所有请求,用于登录权限验证
* 2.拦截 带 moduleId 参数的请求,在渲染视图之前返回 模块权限值
* @author Administrator
*
*/
public class SecurityInterceptor implements HandlerInterceptor{
@Autowired
SysUserRolePermService sysUserRolePermService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("SecurityInterceptor preHandle:"+request.getContextPath()+","+request.getRequestURI()+","+request.getMethod());
HttpSession session = request.getSession();
if (session.getAttribute(Helper.SESSION_USER) == null) {
System.out.println("AuthorizationException:未登录!"+request.getMethod());
if("POST".equalsIgnoreCase(request.getMethod())){
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.write(JSON.toJSONString(new Result(false,"未登录!")));
out.flush();
out.close();
}else{
response.sendRedirect(request.getContextPath()+"/login");
}
return false;
} else {
Object obj = request.getParameter(Helper.PARAM_FUNCTION_ID);
if(obj==null) return true;//没有带功能参数不需要验证
int functionId = Integer.parseInt(obj.toString());
String rs = sysUserRolePermService.permissionValidate(functionId);
System.out.println("校验结果:"+rs);
if(rs.trim().isEmpty()){
return true;//正常通过
}else{
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.write(JSON.toJSONString(new Result(false,rs)));
out.flush();
out.close();
return false;
}
}
}
//模块权限值
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
/*
Object obj = request.getParameter(Helper.PARAM_MODULE_ID);
System.out.println(Helper.PARAM_MODULE_ID+":"+obj);
if(obj == null) return;//如果没有moduleId 参数,否则什么都不做,否则返回模块权限值
System.out.println("SecurityInterceptor postHandle:"+request.getContextPath()+","+request.getRequestURI()+","+request.getMethod());
SysUser loginUser = (SysUser)request.getSession().getAttribute(Helper.SESSION_USER);
int value = sysUserRolePermService.getModulePerm(loginUser.getUserid(),Integer.parseInt(obj.toString()));
modelAndView.addObject(Helper.MVALUE,value);
*/
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception { } }

拦截器配置不变

 <mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/> <!-- 拦截/ /test /login 等等单层结构的请求 -->
<mvc:mapping path="/**/*.aspx"/><!-- 拦截后缀为.aspx的请求 -->
<mvc:mapping path="/**/*.do"/><!-- 拦截后缀为 .do的请求 -->
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/signIn"/>
<mvc:exclude-mapping path="/register"/>
<bean class="com.jykj.demo.filter.SecurityInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>

这样即实现了对某个功能的权限校验的功能 
客户端发送 /moduleAccess.do 请求,该请求带有参数Helper.PARAM_FUNCTION_ID,其值为某个功能的id 
然后拦截器拦截该请求,判断出带有该参数,则对其进行权限校验,如果未通过,写response给客户端,格式是json的字符串,并返回false表示请求已由本拦截器处理了,不会往下执行(返回true表示正常往下执行)。这样就达到了权限验证的目的。这是相对更优雅的实现方式,最起码比上一篇讲的用AOP来实现更优雅。

另外拦截器的postHandle方法是在控制器执行结束,页面渲染之前执行的,所以可以用来给页面添加或修改model属性。

Spring MVC 使用拦截器优雅地实现权限验证功能的更多相关文章

  1. spring mvc +cookie+拦截器功能 实现系统自动登陆

    先看看我遇到的问题: @ResponseBody @RequestMapping("/logout") public Json logout(HttpSession session ...

  2. Spring mvc登录拦截器

    自己实现的第一个Spring mvc登录拦截器 题目要求:拒绝未登录用户进入系统,只要发现用户未登录,则将用户请求转发到/login.do要求用户登录 实现步骤: 1.在spring的配置文件中添加登 ...

  3. 玩转spring MVC(七)----拦截器

    继续在前边的基础上来学习spring MVC中拦截器的使用,下面通过一个例子来实现(完整项目在这里下载:http://download.csdn.net/detail/u012116457/84334 ...

  4. springboot + 拦截器 + 注解 实现自定义权限验证

    springboot + 拦截器 + 注解 实现自定义权限验证最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定义 ...

  5. spring boot 使用拦截器,注解 实现 权限过滤

    http://www.cnblogs.com/zhangXingSheng/p/7744997.html spring boot 使用拦截器 实现 用户登录拦截 http://www.cnblogs. ...

  6. struts2学习笔记--拦截器(Interceptor)和登录权限验证Demo

    理解 Interceptor拦截器类似于我们学过的过滤器,是可以在action执行前后执行的代码.是我们做web开发是经常使用的技术,比如权限控制,日志.我们也可以把多个interceptor连在一起 ...

  7. [转载] Spring MVC - 处理器拦截器

    5.1.处理器拦截器简介 Spring Web MVC的处理器拦截器(如无特殊说明,下文所说的拦截器即处理器拦截器)类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理.   ...

  8. [Spring MVC] - Interceptor 拦截器

    Spring MVC中的Interceptor与Struts2的差不多. 下面是一个简单的Interceptor登陆验证例子: 1.需要在spring的配置文件中加入这段: <!-- 自定义拦截 ...

  9. spring mvc 配置文件拦截器过滤url

    最近在用spring mvc拦截器,sprin 版本号4.0.6.RELEASE, <mvc:interceptor> <mvc:mapping path="/admin/ ...

随机推荐

  1. Redis系列-存储篇list主要操作函数小结

    在总结list之前,先要弄明白几个跟list相关的概念: 列表:一个从左到右的队列,个人理解更类似于一个栈,常规模式下,先进列表的元素,后出. 表头元素:列表最左端第一个元素. 表尾元素:列表最右端的 ...

  2. bitset常用函数用法记录 (转载)

    有些程序要处理二进制位的有序集,每个位可能包含的是0(关)或1(开)的值.位是用来保存一组项或条件的yes/no信息(有时也称标志)的简洁方法.标准库提供了bitset类使得处理位集合更容易一些.要使 ...

  3. javaNIO是什么?由那几部分组成?各部分的作用。

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Sel ...

  4. [C/C++]C++标准中的名词

    1.qualified-id.nested-name-specifier: [example: struct A { struct B { void F(); }; }; A is an unqual ...

  5. 关于$.getJson

    这是一个Ajax函数的缩写,这相当于: 1 2 3 4 5 6 $.ajax({ dataType: "json", url: url, data: data, success: ...

  6. ios页面间传递参数四种方式

    ios页面间传递参数四种方式 1.使用SharedApplication,定义一个变量来传递. 2.使用文件,或者NSUserdefault来传递 3.通过一个单例的class来传递 4.通过Dele ...

  7. android:强制关闭其他应用

    强制关闭其他应用,可以使用ActivityManager,首先需要获取(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); 然后可以 ...

  8. 使用开源工具MonoDevelop开发GTK#图形界面

    转自:http://developer.51cto.com/art/201011/235040.htm Mono一直到现在的2.8已经完全可以胜任一些比较小的项目了,但相关的开发文档与教程一直比较匮乏 ...

  9. Java中线程的锁和数据库中的事务隔离级别

    当涉及到两个或多个线程操作同一个资源时,就会出现锁的问题. 数据库中的某一条记录或者是某一个对象中的字段,可以修改,也可以读取,一般情况下,读取的那个方法应该加锁(即用synchronized互斥), ...

  10. 算法----序列和的 top N

    Description: 两个长度为 n 的数组 A 和 B, 各从中选出一个元素相加 A[i] + B[j], 求 top n 小的那些和. 思路 1:这样的和总共有 n^2 个, 排序,然后取前 ...