自定义标签和注解实现简单的权限控制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012848709/article/details/82724162

楔子

前一段时间看了一个水平很高的代码,使用了自定义注解和标签,实现了权限的控制和表单字段的校验。此处简单模拟一下自定义注解和标签实现权限控制。

code

模式不涉及数据库查询校验,下面是模式的效果。
这里写图片描述

自定义标签


1:自定义标签

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee web-jsptaglibrary_2_1.xsd">
    <display-name>权限控制标签</display-name>
    <tlib-version>1.0</tlib-version>

    <!-- 页面使用引入如下示例 -->
    <!-- <%@ taglib uri="/prev-tag" prefix="slp"%> -->
    <short-name>slp</short-name>
    <uri>/prev-tag</uri> <!-- 也可这样写<uri>http://azhuzi.com/jstl/fake</uri> -->
    <tag>
        <name>privilege</name>
        <tag-class>cn.zhuzi.prev.PrivilegeTag</tag-class>
        <body-content>JSP</body-content>
        <description>privilege tag</description>
        <attribute>
            <description>user oprator action</description>
            <name>oprator</name> <!-- 属性名字 -->
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
    </tag>
</taglib>

2:标签对应的代码

public class PrivilegeTag extends TagSupport {
    // 无法直接使用注解获取spring bean
    @Resource
    JdbcTemplate jdbcTemplate;
    private static final long serialVersionUID = 1L;

    /**
     * 权限操作名
     */
    private String oprator;

    @Override
    public int doStartTag() throws JspException {
        // TODO 获取servletContext(放在次处,仅仅是为了学习 没法使用注解时怎么获取 spring bean)
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        ServletContext servletContext = webApplicationContext.getServletContext();
        String sysTitle = (String) servletContext.getAttribute("title");
        System.out.println(sysTitle);

        // TODO 获取spring bean (放在次处,仅仅是为了学习 没法使用注解时怎么获取 spring bean)
        JdbcTemplate jdbcTemplate = (JdbcTemplate) webApplicationContext.getBean("jdbcTemplate");
        List<Map<String, Object>> queryForList = jdbcTemplate.queryForList("  SELECT * FROM `kindle_pub_list`");
        for (Map<String, Object> map : queryForList) {
            System.out.println(map);
            System.out.println(map);
        }
        // TODO (放在次处,仅仅是为了学习 没法使用注解时怎么获取 spring bean)
        KindleBookMapper kindleBookMapper = (KindleBookMapper) webApplicationContext.getBean("kindleBookMapper");
        KindleBook selectByPrimaryKey = kindleBookMapper.selectByPrimaryKey(4);
        System.out.println(selectByPrimaryKey);
        // 从Session中获取该用户具有的权限(此处没用,仅仅是为了模式 标签获取session)
        String priStr = (String) pageContext.getSession().getAttribute("sys_role_resource");

        // TODO 这是模式的权限
        List<String> pri = Arrays.asList("del", "bookquery");
        if (pri != null && pri.contains(this.oprator)) {
            // TODO 显示
            return EVAL_BODY_INCLUDE;
        } else {
            // TODO 不显示
            return SKIP_BODY;
        }
    }

    public String getOprator() {
        return oprator;
    }

    public void setOprator(String oprator) {
        this.oprator = oprator;
    }
}

3:jsp页面的使用

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<c:set var="proPath" value="${pageContext.request.contextPath}" />
<%@ taglib uri="/prev-tag" prefix="slp"%>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

    <slp:privilege oprator="getbook">
        <button id="getbook">查找书籍</button>
    </slp:privilege>
    <slp:privilege oprator="del">
        <button id="del">删除书籍</button>
    </slp:privilege>



    <a href="${proPath}/kindle/book/getById?id=5">查找数据a标签</a>
</body>

4:简单图解上述内容
这里写图片描述

5:web.xml

有一点我还是不太理解:为何要在WEB.XML中配置jsp-config,在模拟是,发现不配置也可以。

    <!-- 权限标签 -->
    <jsp-config>
        <taglib>
            <taglib-uri>/prev-tag</taglib-uri>
            <taglib-location>/WEB-INF/jstl/preRes.tld</taglib-location>
        </taglib>
    </jsp-config>

自定义注解

上述自定义标签 实现了JSP页面 控制按钮等 的显示与否,此处 自定义标签,控制访问时是否放行
我是使用的SpringMVC,使用拦截器实现的

1:注解

@Documented//将此注解包含在javadoc中
//RetentionPolicy表示 什么级别保留该注解
//          SOURCE 注解编译时丢弃
//          CLASS  注解 在class文件中使用,VM会丢弃
//          RUNTIME VM运行期间也保存,因此可以通过反射机制获取注解信息
@Retention(RetentionPolicy.RUNTIME)
//METHOD 表示方法  ;TYPE表示类、接口、或者枚举
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface Prev {
    /**
     * 权限名称
     * 
     * @return
     */
    public String oprator();


    /**
     * 权限描述
     * 
     * @return
     */
    public String decription() default "";
}

2:拦截器


public class PrivilegeInterceptorAdapter extends HandlerInterceptorAdapter {
    @Resource
    JdbcTemplate jdbcTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object preHandle) throws Exception {
        Method currentMethod = getCurrentMethod(preHandle);
        Prev pre = currentMethod.getAnnotation(Prev.class);
        if (pre == null) {
            return true;
        } else {
            String oprator = pre.oprator();
            String decription = pre.decription();
            System.out.println("操作权限-->" + decription);

            // TODO模拟 从session获取权限
            @SuppressWarnings("unchecked")
            List<String> privilegeList = (List<String>) request.getSession().getAttribute("privilege");

            if (privilegeList.contains(oprator)) {
                return true;
            } else {
                if (request.getHeader("X-Requested-With") != null && request.getHeader("X-Requested-With").equalsIgnoreCase("XMLHttpRequest")) {// 是ajax请求
                    response.setCharacterEncoding("text/html;charset=UTF-8");
                    response.setContentType("text/html;charset=UTF-8");
                    PrintWriter writer = response.getWriter();
                    StringBuffer jsonTip = new StringBuffer("{\"result\":");
                    jsonTip.append(false).append(",\"tip\":\"您无权操作\"}");
                    writer.print(jsonTip.toString());
                    return false;
                } else {// 非ajax请求
                    String content = request.getSession().getServletContext().getContextPath();
                    // response.sendRedirect(content + "/refuse.html");//转发到页面
                    response.setContentType("text/html;charset=utf-8");
                    response.getWriter().write("您无权操作");
                    return false;
                }
            }

        }
    }

    private Method getCurrentMethod(Object invocation) throws Exception {
        HandlerMethod method = (HandlerMethod) invocation;
        //TODO 此处获取的是 controlller 类
        Class<?> beanType = method.getBeanType();
        System.out.println(beanType.getAnnotation(RequestMapping.class));

        //TODO 此处获取的执行的方法
        return method.getMethod();
    }
}

3:controller方法上使用

@Controller
@RequestMapping("/kindle/book")
public class KindleBookController extends SysBaseController {

    @Prev(oprator = "book:del", decription = "删除书籍")
    public Object delByID(int id) {
        int count = kindleBookService.delByID(id);
        return new EuResult(KindleConstants.msg_success);

    }

    @RequestMapping("getById")
    @ResponseBody
    @Prev(oprator = "book:get", decription = "查找书籍")
    public Object getById(int id) {
        KindleBook dic = kindleBookService.getById(id);
        return dic;
    }

效果图
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012848709/article/details/82724162