一种基于annotation的Spring-mvc权限控制方法
简介
本文介绍一种采用annotation来对spring-mvc进行权限控制的方法. 通过枚举类来定义权限项. 将annotation标注到需要控制权限的spring-mvc方法上. 然后,在spring-mvc中定义全局过滤器, 过滤所有spring-mvc方法, 查看方法上的权限annotation信息, 以此对权限进行控制.
程序源代码: https://github.com/eagle0445/sample/
优点
编写比较方便, 在需要控制权限的方法上进行annotation的标注即可, ide能够对annotation进行识别支持. 查看权限配置比较方便, 因为annotation就在方法上, 不用去其他地方翻看. 实现方式比较简单.
具体实现
1.建立权限枚举类
建立权限枚举类型, 用于描述权限的种类, 包含了权限的名称. 每个枚举值中包含了权限中文名称和权限索引值(即权限位). (思考:是否可以直接用中文名称作为枚举值的名称,我在其他程序已经用了中文枚举名称了,暂时没有遇到问题)
<!-- lang: java -->
public enum AuthorityType{
// 包含了枚举的中文名称, 枚举的索引值
WORKER("增删改查员工", 1),
SALES_ORDER_CREATE("创建订单", 6),
SALES_ORDER_FIND("查看订单", 7),
SALES_ORDER_MODIFY("修改订单", 8),
SALES_ORDER_DELETE("删除订单", 9),
;
private String name;
private int index;
private AuthorityType(String name, int index) {
this.name = name;
this.index = index;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
2.登录方式的枚举类
登录方式的枚举类, page代表传统登录页面, json表示ajax的登录
<!-- lang: java -->
public enum ResultTypeEnum {
//整页刷新
page,
//json数据
json
}
3.建立表示权限annotation类
建立annotation类, 用于标注到需要权限验证的地方
<!-- lang: java -->
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FireAuthority {
AuthorityType[] authorityTypes();
ResultTypeEnum resultType() default ResultTypeEnum.page;
}
4.在user类中加入权限字段
在user用户类中添加文本字段表示权限, 字段长度为250字符(因为mysql默认255个字符,可以代表250个权限应该够用了), 字符内容是0或者1. 1表示有权限, 0表示无权限. 提示: 对于用户的权限配置, 只要将对应的权限位设置为0或者1即可.
<!-- lang: sql -->
create table user (
id integer not null auto_increment,
name varchar(255),
right_content varchar(255),
primary key (id)
) type=InnoDB
5.权限验证算法
权限判断方法, 权限判断的实现算法, 用于判断是否有权限
<!-- lang: java -->
public class AuthorityHelper {
/**
* 判断是否有权限
* @param akey aString中位置的索引值,也就是权限位
* @param aString 权限字段,比如 11010101011101
* @return
*/
public static boolean hasAuthority(int akey,String aString){
return ConstanHelper.getAuthorityVaule(akey,rc);
if(aString==null || "".equals(aString)){
return false;
}
char value = aString.charAt(akey);
if(value == '1'){
return true;
}
return false;
}
}
6.建立控制权限的interceptor类
建立interceptor类, 用于过滤需要控制权限的方法.
<!-- lang: java -->
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class AuthorityAnnotationInterceptor extends HandlerInterceptorAdapter {
final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.debug("");
HandlerMethod handler2=(HandlerMethod) handler;
FireAuthority fireAuthority = handler2.getMethodAnnotation(FireAuthority.class);
if(null == fireAuthority){
//没有声明权限,放行
return true;
}
logger.debug("fireAuthority", fireAuthority.toString());
HttpSession session = request.getSession();
Worker manager = (Worker)session.getAttribute(SessionHelper.WorkerHandler);
boolean aflag = false;
for(AuthorityType at:fireAuthority.authorityTypes()){
if(AuthorityHelper.hasAuthority(at.getIndex(), manager.getRightContent())==true){
aflag = true;
break;
}
}
if(false == aflag){
if (fireAuthority.resultType() == ResultTypeEnum.page) {
//传统的登录页面
StringBuilder sb = new StringBuilder();
sb.append(request.getContextPath());
sb.append("/oprst.jsp?oprst=false&opmsg=").append(URLEncoder.encode(ControllerProperty.NOT_HAVE_AUTHORITY,"utf-8"));
response.sendRedirect(sb.toString());
} else if (fireAuthority.resultType() == ResultTypeEnum.json) {
//ajax类型的登录提示
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
OutputStream out = response.getOutputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,"utf-8"));
pw.println("{\"result\":false,\"code\":12,\"errorMessage\":\""+ControllerProperty.NOT_HAVE_AUTHORITY+"\"}");
pw.flush();
pw.close();
}
return false;
}
return true;
}
}
7.配置interceptor类
在spring-mvc中配置interceptor, 实现过滤.
<!-- lang: xml -->
<mvc:interceptors>
<bean class="interceptor.AuthorityAnnotationInterceptor"></bean>
</mvc:interceptors>
8.标注需要控制权限的方法
在需要控制访问的spring-mvc方法上面加上对应的标注.
//方式一
<!-- lang: java -->
@FireAuthority(AuthorityType. SALES_ORDER_CREATE)
@RequestMapping(value="/save.spr", method=RequestMethod.POST)
public ModelAndView save(String name) throws Exception {
//some code
}
//方式二
<!-- lang: java -->
@FireAuthority(authorityTypes = {AuthorityType.SALES_ORDER_DELETE,AuthorityType.SALES_ORDER_CREATE})
@RequestMapping(value="/save.spr", method=RequestMethod.POST)
public ModelAndView save(String name) throws Exception {
//some code
}
//方式三
<!-- lang: java -->
@FireAuthority(authorityTypes = AuthorityType.SALES_ORDER_DELETE, resultType=ResultTypeEnum.page)
@RequestMapping(value="/save.spr", method=RequestMethod.POST)
public ModelAndView save(String name) throws Exception {
//some code
}
9.完成了
^_^
一种基于annotation的Spring-mvc权限控制方法的更多相关文章
- 基于 Annotation 的 Spring AOP 权限验证方法的实现
1. 配置 applicationContext 在 Spring 中支持 AOP 的配置非常的简单,只需要在 Spring 配置文件 applicationContext.xml 中添加: < ...
- Spring7:基于注解的Spring MVC(下篇)
Model 上一篇文章<Spring6:基于注解的Spring MVC(上篇)>,讲了Spring MVC环境搭建.@RequestMapping以及参数绑定,这是Spring MVC中最 ...
- Spring:基于注解的Spring MVC
什么是Spring MVC Spring MVC框架是一个MVC框架,通过实现Model-View-Controller模式来很好地将数据.业务与展现进行分离.从这样一个角度来说,Spring MVC ...
- 基于注解的 Spring MVC 简单入门
web.xml 配置: <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class> ...
- Spring6:基于注解的Spring MVC(上篇)
什么是Spring MVC Spring MVC框架是一个MVC框架,通过实现Model-View-Controller模式来很好地将数据.业务与展现进行分离.从这样一个角度来说,Spring MVC ...
- Spring学习笔记之四----基于Annotation的Spring AOP编程
你能使用@Aspect annotation将某个Java类标注为Aspect,这个Aspect类里的所有公有方法都可以成为一个Advice,Spring提供了5个Annotation去将某个方法标注 ...
- 基于注解的Spring MVC的简单入门——简略版
网上关于此教程各种版本,太多太多了,因为我之前没搭过框架,最近带着两个实习生,为了帮他们搭框架,我只好...惭愧啊...基本原理的话各位自己了解下,表示我自己从来没研究过Spring的源码,所以工作了 ...
- 基于注解的 Spring MVC(上)
什么是Spring MVC Spring MVC框架是一个MVC框架,通过实现Model-View-Controller模式来很好地将数据.业务与展现进行分离.从这样一个角度来说,Spring MVC ...
- 基于Maven 的 Spring MVC
Spring MVC 他是基于MVC的设计模式做出来的,他是Spring对Servlet的进一步的封装 MVC:Model View Controller 如何使用Spring MVC?(Spri ...
随机推荐
- c#事件与委托
C#.net 目录(?)[-] 将方法作为方法的参数 将方法绑定到委托 事件的由来 事件和委托的编译代码 委托事件与Observer设计模式 范例说明 Observer设计模式简介 实现范例的Obse ...
- 在office2010怎么样删除图片背景
在网络上找到一张图片,当你只想要某些部分,但不想要图片的背景的时候,应该怎么办呢,当然你可以借助专业的图片处理工具,如:PS,然后对于大多数没有接触过此软件的同学来说要将背景去掉,实属不易,有没有简单 ...
- java之初识服务器跨域获取数据
当一个项目膨大到无法进行整理时,而作为新负责维护的团队是非常苦恼的.对于想实现两个系统的数据访问,使用Ajax数据请求方式获取jsonp格式的数据 需要有前端jquery库文件. 前端代码通过jque ...
- js让程序暂停一段时间再执行
function sleep(d){ for(var t = Date.now();Date.now() - t <= d;); } sleep(5000); //当前方法暂停5秒
- Spark入门实战系列--3.Spark编程模型(上)--编程模型及SparkShell实战
[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Spark编程模型 1.1 术语定义 l应用程序(Application): 基于Spar ...
- REST API出错响应的设计
REST API应用很多,一方面提供公共API的平台越来越多,比如微博.微信等:一方面移动应用盛行,为Web端.Android端.IOS端.PC端,搭建一个统一的后台,以REST API的形式提供服务 ...
- java设计模式(二)---工厂方法模式
2普通工厂方法模式 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建. 2.1创建接口 /** * 发送接口 * Created by mrf on 2016/2/25. */ public ...
- JAVA 设计模式 观察者模式
用途 观察者模式 (Observer) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观 ...
- 采用Kettle分页处理大数据量抽取任务
作者:Grey 原文地址: http://greyzeng.com/2016/10/31/big-data-etl/ 需求: 将Oracle数据库中某张表历史数据导入MySQL的一张表里面. 源表(O ...
- 用原生JS读写CSS样式的方法总结
为了日后方便查询,本人翻阅了一些资料总结了以下方法,仅限原生JS,如有不对的地方欢迎指出!只求大家看完觉得有学到点什么就OK了! 一.可以通过DOM节点对象的style对象(即CSSStyleDe ...