简介

本文介绍一种采用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.完成了

^_^

最新文章

  1. ASP.NET中使用UpdatePanel实现局部异步刷新方法和攻略(转)
  2. pair&lt;&gt;结构体模版的用法
  3. linux 搭建jenkins+创建maven工程JOB
  4. centos 下使用sublime
  5. WinForm设置控件焦点(转)
  6. strlen、strcmp、strcat、strcpy、memcpy基础函数的实现
  7. Eclipse下运行拷贝的项目,更改项目名后报404
  8. asp.net使用unescape读取js escape编码过的字符串
  9. 201521123102 《Java程序设计》第12周学习总结
  10. scss 编译方法
  11. cocoa-charts 导入其依赖库TABlib 报UIKit Foundation找不到的问题
  12. Win10 开启移动热点 WiFi 的简单方法
  13. MyEclipse、Eclipse使用配置及部分问题
  14. SCU 4444: Travel(最短路)
  15. Yii2 session的使用方法(2)
  16. 集合之fail-fast机制
  17. iOS - 跑马灯、弹幕
  18. (转)MySQL百万级数据库优化
  19. 盘点SEO和SEM的优劣势
  20. 关于VPS主机KVM/OPENVZ/CN2区别与含义

热门文章

  1. java 中获取2个时间段中所包含的周数(股票的周数-&gt;从周六到周五)
  2. Linux快速入门04-扩展知识
  3. C++程序员们,快来写最简洁的单例模式吧
  4. WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
  5. SQL*Loader之CASE9
  6. HTML5的学习--performance
  7. Android基于mAppWidget实现手绘地图(十六)–处理一次触摸多个地图对象
  8. Windows Azure Cloud Service (37) 浅谈Cloud Service
  9. java中String的相等比较
  10. HT for Web基于HTML5的图像操作(二)