SpringMVC实现注解式权限验证的实例
作者:Erola 发布时间:2021-11-19 11:52:44
对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现。但借助于Spring MVC中的action * 我们可以实现注解式的权限验证。
一.首先介绍一下action * :
HandlerInterceptor是Spring MVC为我们提供的 * 接口,来让我们实现自己的处理逻辑,HandlerInterceptor 的内容如下:
public interface HandlerInterceptor {
boolean preHandle(
HttpServletRequest request, HttpServletResponse response,
Object handler)
throws Exception;
void postHandle(
HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView)
throws Exception;
void afterCompletion(
HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex)
throws Exception;
}
可以看到接口有3个方法,其含义如下:
preHandle:在执行action里面的处理逻辑之前执行,它返回的是boolean,这里如果我们返回true在接着执行postHandle和afterCompletion,如果我们返回false则中断执行。
postHandle:在执行action里面的逻辑后返回视图之前执行。
afterCompletion:在action返回视图后执行。
HandlerInterceptorAdapter适配器是Spring MVC为了方便我们使用HandlerInterceptor而对HandlerInterceptor 的默认实现,里面的3个方法没有做任何处理,在preHandle方法直接返回true,这样我们继承HandlerInterceptorAdapter后只需要实现3个方法中我们需要的方法即可,而不像继承HandlerInterceptor一样不管是否需要3个方法都要实现。
当然借助于HandlerInterceptor我们可以实现很多其它功能,比如日志记录、请求处理时间分析等,权限验证只是其中之一。
二.下面我们就来一步一步来完成注解式权限验证的功能。
首先添加一个账户的Controller和登录的Action及视图来模拟在没有权限时跳转到登陆页面,内容分别如下:
com.demo.web.controllers包中的AccountController.java:
package com.demo.web.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping(value = "/account")
public class AccountController {
@RequestMapping(value="/login", method = {RequestMethod.GET})
public String login(){
return "login";
}
}
views文件夹下的视图login.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
这里是登录界面
</body>
</html>
新建包com.demo.web.auth,添加自定义注解AuthPassport,内容如下:
package com.demo.web.auth;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthPassport {
boolean validate() default true;
}
添加自己的 * 实现AuthInterceptor继承于HandlerInterceptorAdapter,内容如下:
package com.demo.web.auth;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class AuthInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(handler.getClass().isAssignableFrom(HandlerMethod.class)){
AuthPassport authPassport = ((HandlerMethod) handler).getMethodAnnotation(AuthPassport.class);
//没有声明需要权限,或者声明不验证权限
if(authPassport == null || authPassport.validate() == false)
return true;
else{
//在这里实现自己的权限验证逻辑
if(false)//如果验证成功返回true(这里直接写false来模拟验证失败的处理)
return true;
else//如果验证失败
{
//返回到登录界面
response.sendRedirect("account/login");
return false;
}
}
}
else
return true;
}
}
配置项目的springservlet-config.xml添加如下内容:
<mvc:interceptors>
<!-- 国际化操作 * 如果采用基于(请求/Session/Cookie)则必需配置 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
<!-- 如果不定义 mvc:mapping path 将拦截所有的URL请求 -->
<bean class="com.demo.web.auth.AuthInterceptor"></bean>
</mvc:interceptors>
这样在执行每个action方法是都会调用AuthInterceptor处理,当判断action上有我们定义AuthPassport注解时就会执行里面的权限验证逻辑。
运行项目:
可以看到执行了我们在springservlet-config.xml定义的HelloworldController的index方法。
<!-- 如果当前请求为“/”时,则转发到“/helloworld/index" -->
<mvc:view-controller path="/" view-name="forward:/helloworld/index"/>
下面我们在HelloworldController的index方法上加上自定义注解AuthPassport:
@AuthPassport
@RequestMapping(value={"/index","/hello"})
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "Hello World!");
modelAndView.setViewName("index");
return modelAndView;
}
重新运行项目:
可以看到正确执行了权限判断逻辑,这样我们只需要在我们在需要权限验证的action上加上这个注解就可以实现权限控制功能了。
注解式权限验证的内容到此结束。
代码下载:demo
来源:http://www.cnblogs.com/liukemng/p/3751338.html


猜你喜欢
- 示例接口定义为了方便笔者先自己写了个简单的接口用于展示,返回当前时间,具体如下/// <summary>/// GetToday
- MyBatis简介MyBatis前身是iBatis,是一个基于Java的数据持久层/对象关系映射(ORM)框架.MyBatis是对JDBC的
- 之前已经为大家介绍过利用Java实现带GUI的气泡诗词特效,本文将为大家介绍另一种方法同样也可以实现气泡诗词的效果。下面是示例代码impor
- 本文实例讲述了Android返回键功能的实现方法。分享给大家供大家参考。具体如下:在开发android应用时,常常通过按返回键(即keyCo
- java -jar设置添加启动参数方法java -jar 参数前后位置说明springboot项目启动的时候可以直接使用java -jar
- 项目中为了实现账号多设备登录的监听 一个账号在别的设备登录时在该设备上需要弹出对话框提示 故而用到全局对话框方案一、1、在开发中有时会用到全
- 1. 最小生成树连通图中的每一棵生成树 , 都是原图的极大无环子图 , 即: 从中删去任何一条边 , 生成树就不再连通;反之 , 在其中引入
- 前言:Springboot的出现极大的简化了开发人员的配置,而这之中的一大利器便是springboot的starter,starter是sp
- 最近学习Spring的源码,发现一个利器BeanPostProcessor。这个后置处理器可以在bean初始化前后对bean进行操作。我们可
- 一、序言Java多线程编程线程池被广泛使用,甚至成为了标配。线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线
- 实例如下:/// <summary> /// 上传ftp服务 /// </summary>
- poi解析Excel文件版本问题解决办法poi解析Excel文件时有两种格式: HSSFWorkbook格式用来解析Excel2003(xl
- 前言现如今几乎大多数Java应用,例如我们耳熟能详的tomcat, struts2, netty...等等数都数不过来的软件,要满足通用性,
- 大家在使用 Intellij IDEA 的时候会经常遇到各种乱码问题,甚是烦扰。栈长也偶尔会用下IDEA,也有一些解决乱码的经验,我给大家总
- 之前的文章向大家介绍了几个项目中常用的实用功能,那么在这篇文中,我将向大家介绍如何获取Android手机中已经安装的手机应用程序,好了,废话
- 一、继承引言继承关系可以对不同模块的依赖版本做统一管理,因为子模块中的依赖基本都继承于父模块,父模块中指定哪个版本,子模块就继承哪个版本,可
- 本文为大家分享了NancyFx框架检测任务管理器的具体方法,供大家参考,具体内容如下先建一个空的项目和之前的NancyFx系列一样的步骤然后
- 本文实例为大家分享了C语言实现字符串拼接和拷贝的具体代码,供大家参考,具体内容如下字符串拼接:#include<stdio.h>
- 手机一般有两种类型的输入设备。一种是键盘类型的输入设备,通常它包含电源键和音量下键。另一种是触摸类型的输入设备,触摸屏就属于这种类型。键盘类
- 实现Struts登录1、jar包拷贝首先是建立java web项目,之后打开我们我们下载好strtus框架,Struts-1.2.9-bin