SpringMVC学习系列(9) 之 实现注解式权限验证

 

对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在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上加上这个注解就可以实现权限控制功能了。

注解式权限验证的内容到此结束。

SpringMVC实现注解式权限验证(转)的更多相关文章

  1. SpringMVC实现注解式权限验证

    SpringMVC学习系列(9) 之 实现注解式权限验证 对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servle ...

  2. SpringMVC学习系列(9) 之 实现注解式权限验证

    对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MV ...

  3. SpringMVC学习(9):实现注解式权限验证

    对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MV ...

  4. SpringMVC(9)实现注解式权限验证

    对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MV ...

  5. SpringMVC(10)实现注解式权限验证

    在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容->异 ...

  6. Spring3 springMVC添加注解式WebSocket

    Spring3添加注解式WebSocket 推荐升级成spring4以后,spring4已经集成WebSocket. 由于种种原因,项目开发处于快结束的阶段了,升级成spring4不想那么麻烦,但是又 ...

  7. SpringMVC拦截器+Spring自定义注解实现权限验证

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  8. springmvc基于注解的权限控制

    一.权限码 /** * @Title: AuthCode.java * @Package cn.com.kamfu.auth * @Description: TODO(用一句话描述该文件做什么) * ...

  9. 基于springmvc开发注解式ip拦截器

    一.注解类 @Documented @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) ...

随机推荐

  1. Web应用和RESTful架构

    Web应用和RESTful架构 单页Web应用 概述 单页Web应用并不是突然诞生的一门新技术,而是web展示的一种新的尝试.它将所有的动作局限于一个Web页面,在加载站点首页的时候就加载站点需要的J ...

  2. HBase Maven 工程模块梳理

    HBase Maven 工程各个 Model 功能说明: github 地址:git://git.apache.org/hbase.git 版本:2.0.0-SNAPSHOT hbase-annota ...

  3. 你的flume-ng的第一篇博客

    我在flume-ng 1.1.0 孵化版的时候就开始接触了,自己也搞了一段时间,没事扯扯心得吧. 先说在前面,flume-ng 后面的版本,我没仔细读change log ,比较农民 , 不知道新添了 ...

  4. Binder机制,从Java到C (8. ServiceManager in Native)

    在第三篇 Binder机制,从Java到C (3. ServiceManager in Java) 中,讲到ServiceManager的Stub端在Native,Proxy端在Java.实际上,还要 ...

  5. Push Notification总结系列(二)

    Push Notification系列概括: 1.Push Notification简介和证书说明及生成配置 2.Push Notification的iOS处理代码和Provider详解 3.Push ...

  6. Bootstrap3.0学习第八轮

    Bootstrap3.0学习第八轮(工具Class)   前言 阅读之前您也可以到Bootstrap3.0入门学习系列导航中进行查看http://www.cnblogs.com/aehyok/p/34 ...

  7. EL表达式与三目运算符

    在页面实现常量替换,比如 entity.auditi 的值如果为0显示不需要否则显示需要 因为需求就这两个值 所以使用三目运算符比较简洁 如果值为很多个 可使用if  else进行判断 ${entit ...

  8. Docker ( Is docker really better than VM ?)

    Docker is so popular. Arha? Let's try! Docker needs the linux kernel shoud be upper than 3.10.x Let' ...

  9. ExtJS初接触 —— 了解 Ext Core

    ExtJS初接触 —— 了解 Ext Core Ext Core是一款和jQuery媲美的轻型JS库,基于MIT许可.对于Dom的操作,我个人还是比较喜欢用jQuery.当然如果项目中用的是ExtJS ...

  10. ADS的go to命令

    我们有时候在一个函数右键没有看到“go to”选项,这是因为没有Make,要先Make之后才能使用go to 命令