servlet极简单权限拦截设计处理

在java web的开发中 遇到的极其简单的权限控制,整个小项目就分为四五种用户的权限角色,因此不想考虑使用框架以及数据库建角色表,菜单表,操作表等来完成权限设计,而是采用反射,注解的简单方法完成。

核心代码

BaseServlet.java文件

package com.zk.servlet;

import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zk.annotation.Permission;
import com.zk.bean.User;

/**
 * servlet基类
 *
 * @Description TODO
 * @author zk
 * @version 1.0
 * @date 2015-4-9 下午4:53:11
 */
@SuppressWarnings("all")
public abstract class BaseServlet extends HttpServlet {
    private static final long serialVersionUID = -6898295798172047477L;
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        /**
         * 思路1 .根据method参数 处理 2.使用反射调用
         *   2 加入简单的权限判断(当然也可以通过过滤器设计 拦截实现)
         *      由于本案例不需要复杂的权限设计,故没有采用分别建几张表 来存角色,菜单,操作等信息,只用在用户表添加一个字段 level  0 1,4,7来处理
         *      0:此用户无效(软删除)相当于已经删除
         *      1: 普通访客等级 无需登录 主要是前端的信息浏览
         *      4 :会员等级 可以登录,进行相关操作
         *      7 :顶级管理员操作
         *      中间预留一些字段做不同的权限。
         *  3权限判断的核心思路:
         *             1> 建一个 BaseServlet 父类 让之类Servlet继承
         *             2> 在BaseServlet 中重写service 方法通过反射 以及在之类中的方法操作上加自定义注解【见下文自定义注解文件】 eg:@Permission(level=3)
         *             3> 在service 方法中通过 request.getParmenter("method") 获取在子类中对应的方法操作名称,并反射获取该方法名称
         *                上面的注解信息 level
         *             4> 对注解信息 以及用户的登录状态 和用户的level状态进行判断
         *                   对于有些操作需要登录 或者权限等级较高的  就可以重定向处理拦截权限
         *                      0等级忽略  由于1 为 普通权限 故先判断是否为普通权限 就是普通网站访问者权限
         *                        当操作方法的leve为1 放行
         *                        不为1 说明需要更高的用户权限
         *                        那么首先判断是否登录 没有登录的 返回登录
         *                        登录成功的  获取登录用户的leve状态 和请求该方法的操作level权限等级对比
         *                        如果用户的leve小于该方法操作的 就拦截 返回,反之就可以进行方法操作
         *
         *
         */
        // 只处理了post的乱码问题,get自行处理
        req.setCharacterEncoding("utf-8");
        // 只是处理 了 字符流的问题,字节流自行处理
        resp.setContentType("text/html;charset=utf-8");
        String methodName = req.getParameter("method");
        // 判断是否有方法
        if (methodName == null || methodName.trim().isEmpty()) {
            throw new RuntimeException("亲!请传入method的参数");
        }
        Class clazz = this.getClass();
        Method method = null;
        try {
            method = clazz.getMethod(methodName, HttpServletRequest.class,
                    HttpServletResponse.class);
            // 注意 此处利用注解 获取 每一个请求方法上的注解信息
            Permission info = method.getAnnotation(Permission.class);
            // 如果获取到注解信息
            if (info != null) {
                int level = info.level();// 访问此操作需要的权限级别
                if (level != 1) { // level 级别为默认的 最低等级 故无需处理 跳过
                    // level !=1 说明需要登录 以及更高等级的用户权限
                    User user = (User) req.getSession()
                            .getAttribute("backUser");
                    // 判断是否登录
                    if (req.getSession().getAttribute("backUser") == null) {
                        String contextPath = getServletContext()
                                .getContextPath();
                        resp.getWriter()
                                .print("亲,您还没有登录,请<a href=‘"
                                        + contextPath
                                        + "/index.jsp‘ target=‘_parent‘>登录</a>!");
                        return;
                    } else {
                        // 登录成功 判断用户所拥有等级与 此操作的等级
                        if (user.getLevel() < level) {
                            String contextPath = getServletContext()
                                    .getContextPath();
                            resp.getWriter()
                                    .print("对不起,你暂且无权限操作,请<a href=‘"
                                            + contextPath
                                            + "/index.jsp‘ target=‘_parent‘>登录</a>申请为会员!");
                            return;
                        }
                    }
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("亲!传入method的参数错误");
        }
        try {
            String result = (String) method.invoke(this, req, resp);
            if (result != null && !result.trim().isEmpty()) {
                req.getRequestDispatcher(result).forward(req, resp);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }

}

自定义注解文件Permission.java

package com.zk.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 自定义权限注解
 * @Description TODO
 * @author zk
 * @version 1.0
 * @date 2015-4-12 下午9:34:46
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD,ElementType.TYPE})
public @interface Permission {
    int level ();
}

子类Servlet的操作 使用示例:

package com.zk.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;

import com.zk.annotation.Permission;
import com.zk.bean.Customer;
import com.zk.bean.Message;
import com.zk.bean.MessageType;
import com.zk.bean.MessageTypeLev;
import com.zk.bean.PageBean;
import com.zk.bean.User;
import com.zk.service.CustomerService;
import com.zk.service.MessageService;
import com.zk.service.MessageTypeService;

/**
 * 和信息相关的控制器 继承自定义的BaseServlet
 *
 * @Description TODO
 * @author zk
 * @version 1.0
 * @date 2015-4-11 上午10:21:56
 */
public class MessageServlet extends BaseServlet {
    /**
     * 通过id删消息
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    @Permission(level = 3)// 注意 :注解的使用 不同的操作设置不同的值
    public String deleteById(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        String id = request.getParameter("id");
        String pageCode = request.getParameter("pageCode");
        String totalPage = request.getParameter("totalPage");
        MessageService cs = new MessageService();
        cs.deleteById(id);
        int pg = 1;
        if (Integer.parseInt(totalPage) % Integer.parseInt(pageCode) == 0) {
            if (Integer.parseInt(pageCode) > 1) {
                pg = Integer.parseInt(pageCode) - 1;
            } else {
                // 已结没有信息了
            }
        }
        return "/message?method=listMsg&pageCode=" + pg;
    }
}

附上user用户表设计的结构

-- ----------------------------
-- Table structure for t_customer
-- ----------------------------
CREATE TABLE `t_customer` (
  `id` varchar(40) NOT NULL,
  `username` varchar(20) DEFAULT NULL,
  `gender` varchar(10) DEFAULT NULL,
  `birthday` varchar(20) DEFAULT NULL,
  `cellphone` varchar(20) DEFAULT NULL,
  `email` varchar(40) DEFAULT NULL,
  `love` varchar(100) DEFAULT NULL,
  `type` varchar(40) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

总结:反射 注解 简单继承 统一处理。东西和思路比较粗糙,只是为了实现写简单功能,希望批判接受和建议,谢谢。

时间: 2024-10-05 04:59:11

servlet极简单权限拦截设计处理的相关文章

java web简单权限管理设计

一套最基本的权限管理包括用户.角色.资源. 数据库设计 我的设计如下: 用户:user 角色:role 用户-角色:user_role 资源:resource(包括上级菜单.子菜单.按钮等资源) 角色-资源:role_resource 标准的权限管理系统设计为以上5张表. 注:用户.用户-角色我就不做说明了,这两个是很简单的两块,用户的crud,以及为用户分配角色(多对多的关系)稍微琢磨一下就清楚了,下面都是针对为角色分配权限的实现 后台实现 展示层采用ztree树 <%@ page conte

简单权限管理设计

这套权限管理是配合Zend Framework设计的,用在其他地方的时候可以做些修改. 一.表构成 1.总共有七张表组成 2.管理员信息表(sys_user).系统模块信息表(sys_module)与用户分组信息表(sys_group)这三张是独立的表,没有与其他表发生关系. 3.用户分组信息表(sys_action)保存的就是一个个的操作行为,要控制的权限就是这些操作. 4.分组与用户信息表(sys_group_user)保存是用户与分组的关系,将一个个用户分组可以方便用组来控制权限. 5.用

关于PHP位运算的简单权限设计

写在最前面 最近想写一个简单的关于权限处理的东西,之前我也了解过用二进制数的位运算可以出色地完成这个任务.关于二进制数的位运算,常见的就是"或.与.非"这三种简单运算了,当然,我也查看了下PHP手册,还有"异或.左移.右移"这三个运算.记得上初中时数学老师就开始唠叨个不停了,在此我也不想对此运算再作额外的说明,直接进入正题. 如何定义权限 将权限按照2的N次方来定义值,依次类推.为什么要这样子定义呐?这样子定义保证了每个权限值(二进制)中只有一个1,而它恰好对应一种

通用权限管理设计

权限设计(初稿)     1. 前言:     权限管理往往是一个极其复杂的问题,但也可简单表述为这样的逻辑表达式:判断"Who对What(Which)进行How的操作"的逻辑表达式是否为真.针对不同的应用,需要根据项目的实际情况和具体架构,在维护性.灵活性.完整性等N多个方案之间比较权衡,选择符合的方案.     2. 目标:     直观,因为系统最终会由最终用户来维护,权限分配的直观和容易理解,显得比较重要简单,包括概念数量上的简单和意义上的简单还有功能上的简单.想用一个权限系统

系统权限管理设计 (转)

权限设计(初稿)      1. 前言:      权限管理往往是一个极其复杂的问题,但也可简单表述为这样的逻辑表达式:判断“Who对What(Which)进行How的操作”的逻辑表达式是否为真.针对不同的应用,需要根据项目的实际情况和具体架构,在维护性.灵活性.完整性等N多个方案之间比较权衡,选择符合的方案.      2. 目标:      直观,因为系统最终会由最终用户来维护,权限分配的直观和容易理解,显得比较重要简单,包括概念数量上的简单和意义上的简单还有功能上的简单.想用一个权限系统解

系统权限管理设计 (转:http://blog.csdn.net/chexlong/article/details/37697555)

权限设计(转:http://blog.csdn.net/chexlong/article/details/37697555) 1. 前言: 权限管理往往是一个极其复杂的问题,但也可简单表述为这样的逻辑表达式:判断"Who对What(Which)进行How的操作"的逻辑表达式是否为真.针对不同的应用,需要根据项目的实际情况和具体架构,在维护性.灵活性.完整性等N多个方案之间比较权衡,选择符合的方案. 2. 目标: 直观,因为系统最终会由最终用户来维护,权限分配的直观和容易理解,显得比较重

SpringMVC+Spring Data JPA+Shiro+EasyUI简单权限管理系统

SpringMVC+Spring Data JPA+Shiro+EasyUI简单权限管理系统 一直想做一个管理系统,希望它简洁,能做一个demo使用.以后在研究学习的时候,可以在此基础上增加代码.我觉得权限管理系统很值得做,因为涉及关系数据库模式的设计,能学到很多东西.万事开头难,先做个简单的,以后再慢慢完善的.任何事情关键是要做,不能停留在想. 前端 由于之前没有多少前端编程经验,所以做起前端比较吃力.之前前端使用Bootstrap,发现需要自己编写很多前端代码,虽然花费了很多时间,但是页面做

Web应用程序系统的多用户权限控制设计及实现-总结【11】

Web应用程序系统的多用户权限控制设计及实现通过10章内容讲述已经结尾了.写这些博客的目的很简单,方便自己以后参考,也留下自己编程岁月的一些痕迹.对于编程,对于工作,真是心甘情愿的就好. 由于这只是一个案例介绍,在实际应用时,应有不同.至少在项目结构中应有多层分类.由于本系统介绍的方案已经比较老套了,特别是数据处理模块方面,现在更推荐用 Entity Framework的数据库处理方式,应该是更好的,至少在编码上更轻松快捷.实际项目的分类模块如下所示: 对于读过这套方案的读者,我很荣幸.对于提出

ASP.NET大中小型系统权限管理设计

每个系统几乎都会有权限管理这一模块,我也为许多个大中小项目搭建过权限管理的模块,总结了一些经验和设计的思想,现在分享给大家,欢迎大家指出不足和一起交流. 下面我列出数据库权限模块的表设计,为了做最大的分享,下面的SQL语句和代码都是能直接运行. BEGIN TRANSACTION CREATE TABLE [dbo].[UserAccount]( [ID] [bigint] IDENTITY(1,1) NOT NULL, [CreatedDate] [datetime] NOT NULL, [C