栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring MVC 拦截器实现登录

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring MVC 拦截器实现登录

上篇博文我在博客中讲到如何使用spring MVC框架来实现文件的上传和下载,今天小钱给大家再来分享和介绍Spring MVC框架中相当重要的一块功能——拦截器。

关于拦截器的概念我在这里就不多说了,大家可以上网百度或者看别人写的具体博客,我今天要说的是拦截器在实际开发中它有什么作用,怎样用Spring MVC拦截器来实现可拔插方式管理各种功能。Interceptor拦截器,它的主要作用就是拦截用户的请求并进行相应的处理。什么意思呢?比如说:通过拦截器来进行用户的权限验证,或者是用来判断用户是否已经登录等。

Spring MVC拦截器是可拔插式的设计。如果需要某个拦截器,只需要在配置文件中应用该拦截器即可,如果不需要使用拦截器,只需要在配置文件中取消其应用拦截器。不管是否应用某个拦截器,对Spring MVC框架不会有任何的影响。本文将介绍HandlerInterceptor接口和演示“Spring MVC拦截器实现用户权限验证”项目案例来学习、掌握拦截器。

本项目源码下载:Spring MVC拦截器实现用户权限验证

HandlerInterceptor接口

Spring MVC中的Interceptor拦截器拦截的请求是通过实现HandlerInterceptor接口来完成的。在Spring MVC中定义一个Interceptor拦截器非常简单,通过在要定义的Interceptor拦截器类中实现Spring的HandlerInterceptor接口,或是继承抽象类HandlerInterceptorAdapter。

HandlerInterceptor接口定义了三个方法,Spring MVC就是通过这三个方法来对用户的请求进行拦截处理的,下面对这三个方法进行具体的详解:

(1)boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handle)。顾名思义,这个方法将在请求处理之前被调用。Spring MVC中的Interceptor实行的是链式调用,即在一个应用中或者说在一个请求中可以同时存在多个Interceptor。每个Interceptor的调用会依据它的声明顺序依次执行,而且最先执行的是Interceptor中的preHandle方法,所以可以在这个方法中进行一些前置的初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是boolean类型的,当返回值为FALSE时,表示请求结束,后续的Interceptor和Controller都不会再执行;当返回值为TRUE时就会继续调用下一个Interceptor的preHandle方法;如果已经是最后一个Interceptor,就会调用当前请求的Controller方法。

(2)void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView mv)。该方法和之后的afterCompletion方法都只能在当前所属的Interceptor的preHandle方法的返回值为TRUE时才能被调用。postHandle方法,顾名思义,就是在当前请求被处理之后,也就是Controller方法被调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作。postHandle方法被调用的方向跟preHandle是相反的,也就是说先声明的Interceptor的postHandle方法反而会后执行,这和Struts2里面的Interceptor的执行过程类似。

(3)void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception exception)。 该方法也是在当前所属的Interceptor的preHandle方法的返回值为TRUE时才会执行。顾名思义,该方法将在这个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行。这个方法的主要作用就是进行资源整理。

拦截器实现用户权限验证

本文将通过Spring MVC拦截器完成一个用户权限验证的功能。即用户必须登录之后才可以访问这个web网站的首页,如果没有登录就直接访问网站首页,则拦截器会拦截请求,并将请求重新转发到登录页面,同时提示用户“需要先登录再访问网站”,由于是演示案例,所以成功登录之后的网站页面我们直接是拼的一个网页显示给用户。本项目作为测试案例,我就不创建Maven项目了,直接创建的是一个Dynamic Web Project(动态的web项目),项目名称为:Interceptor,本项目采用Tomcat 8作为web服务器,我们需要在项目中引入以下jar包,jar包我就截图演示了,附件源码中lib文件夹下会有,这里直接给一个项目的目录结构,如下图:

 

首先呢,我们要做一个网页,这个网页就是用来提示用户的登录信息,提示输入用户名和密码,在此我们在项目的WebContent/WEB-INF/content文件夹中创建一个loginForm.jsp,这是一个jsp文件,具体代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>




登录页面


用于演示拦截器登录页面




这时我们需要进行处理/login的请求,我们需要写请求的功能代码,在src目录下创建“cn.edu.jit.controller”包,在创建一个UserController类,用来处理用户请求。具体代码如下:

package cn.edu.jit.controller;

import javax.servlet.http.HttpSession;

import cn.edu.jit.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;


@Controller
public class UserController {

  
  @RequestMapping(value="/login")
   public ModelAndView login(String loginname,String password,ModelAndView mv,HttpSession session) {
    //模拟数据库根据登录名和密码查找用户,判断用户登录
    if(loginname != null && loginname.equals("钱春华") 
 && password 
 != null 
 && password.equals("123456")) {
      //模拟创建用户
      User user = new User();
      user.setLoginname(loginname);
      user.setPassword(password);
      user.setUsername("钱春华");
      //登录成功,将user对象设置到HttpSession作用范围域
      session.setAttribute("user", user);
      //转发到main请求
      mv.setViewName("redirect:main");
    } else {
      //登录失败,设置失败提示信息,并跳转到登录页面
      mv.addObject("message", "登录名或密码错误,请重新输入!");
      mv.setViewName("loginForm");
    }
    return mv;
  }

}

UserControlle类的login方法用来处理登录的请求,本项目没有使用数据库存储数据,只是简单的模拟了用户的登录,只要用户输入登录名是“钱春华”,密码是“123456”,则验证通过,并创建一个User对象保存到HttpSession当中,同时将请求使用客户端跳转到main请求:如果登录失败提示信息到ModelAndView对象,同时将请求使用客户端跳转到loginFrom请求,即登录页面。

同样地,我们刚刚写了一个用户的登录请求,我们接下来要处理/main请求,用于实现登录之后给用户显示书的详细定价以及出版信息,我们还在“cn.edu.jit.controller”包中创建一个名为BookController类,用于处理图书请求。具体代码如下:

package cn.edu.jit.controller;

import java.util.ArrayList;
import java.util.List;

import cn.edu.jit.domain.Book;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class BookController {
  
  @RequestMapping(value="/main")
   public String main(Model model) {
    //模拟数据库获得所有图书集合
    List book_list = new ArrayList();
    book_list.add(new Book("java.jpg","JAVA核心技术1","周立新 编著",90.00));
    book_list.add(new Book("ee.jpg","Android第一行代码","郭霖 编著",72.50));
    book_list.add(new Book("android.jpg","Spring+MyBatis企业应用实战","李刚 编著",58.00));
    book_list.add(new Book("ajax.jpg","SpringMVC实战","Alex Bretet 编著",99.00));
    //将图书集合添加到model当中
    model.addAttribute("book_list", book_list);
    //跳转到main页面
    return "main";
  }

}

BookController类中的main方法用来处理网站首页的请求,该方法获得所有图书的信息,并将它们设置到Model当中,然后传递到main页面。由于本案例没有使用数据库存储数据,只是简单的创建了一个集合模拟从数据库获取图书信息。

下面是登录成功后访问网页的main.jsp代码,该jsp代码位于WebContent/WEB-INF/content文件夹中。如下具体代码所示:

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>




首页

  table{border-collapse:collapse;border-spacing:0;border-left:1px solid #888;border-top:1px solid #888;background:#efefef;}
  th,td{border-right:1px solid #888;border-bottom:1px solid #888;padding:5px 15px;}
  th{font-weight:bold;background:#ccc;}



欢迎[${sessionScope.user.username }]访问
封面图书名称作者出版价格
${book.name } ${book.author } ${book.price }

接下来,我将设计拦截器验证用户是否登录,如果用户没有登录,不可以访问除登录页面和登录请求的所有Controller。我们在src文件下创建名为“cn.edu.jit.interceptor”这个包,在这个包下创建“AuthorizationInterceptor”类,用于演示拦截器验证用户是否登录。具体代码如下:

package cn.edu.jit.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.edu.jit.domain.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


public class AuthorizationInterceptor implements HandlerInterceptor {

  //不拦截"/loginForm"和"/login"请求
  private static final String[] IGNORE_URI = {"/loginForm", "/login"};

  
  @Override
  public void afterCompletion(HttpServletRequest request,
      HttpServletResponse response, Object handler, Exception exception)
      throws Exception {
    System.out.println("AuthorizationInterceptor afterCompletion --> ");

  }
  
  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response,
      Object handler, ModelAndView mv) throws Exception {
    System.out.println("AuthorizationInterceptor postHandle --> ");

  }

   
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
      Object handler) throws Exception {
    System.out.println("AuthorizationInterceptor preHandle --> ");
    //flag变量用于判断用户是否登录,默认为false 
    boolean flag = false; 
    //获取请求的路径进行判断
    String servletPath = request.getServletPath();
    //判断请求是否需要拦截
    for (String s : IGNORE_URI) {
      if (servletPath.contains(s)) {
 flag = true;
 break;
      }
    }
    //拦截请求
    if (!flag) {
      //1.获取session中的用户 
      User user = (User) request.getSession().getAttribute("user");
      //2.判断用户是否已经登录 
      if(user == null) {
 //如果用户没有登录,则设置提示信息,跳转到登录页面
  System.out.println("AuthorizationInterceptor拦截请求:");
  request.setAttribute("message", "请先登录再访问网站");
  request.getRequestDispatcher("loginForm").forward(request, response);
      } else {
 //如果用户已经登录,则验证通过,放行
  System.out.println("AuthorizationInterceptor放行请求:");
  flag = true;
      }
    }
    return flag;    
  }

}

我们需要在springmvc-config.xml文件中配置拦截器,配置代码具体如下:


  
    

在src文件下创建“cn.edu.jit.domain”包,用于存放图书和用户的两个实例,具体代码如下:

Book类代码:

package cn.edu.jit.domain;

import java.io.Serializable;

public class Book implements Serializable{

  private Integer id;//id 
  private String name;//书名
  private String author;//作者
  private Double price;//价格
  private String image;//封面图片

  public Book() {
    super();
  }
  public Book( String image,String name, String author, Double price) {
    super();
    this.image = image;
    this.name = name;
    this.author = author;
    this.price = price;
  }
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getAuthor() {
    return author;
  }
  public void setAuthor(String author) {
    this.author = author;
  }

  public Double getPrice() {
    return price;
  }
  public void setPrice(Double price) {
    this.price = price;
  }
  public String getImage() {
    return image;
  }
  public void setImage(String image) {
    this.image = image;
  }
  @Override
  public String toString() {
    return "Book [id=" + id + ", name=" + name + ", author=" + author
 + ", price=" + price + ", image=" + image + "]";
  }

}

User类代码:

package cn.edu.jit.domain;

import java.io.Serializable;

public class User implements Serializable {

  private Integer id;//id
  private String loginname;//登录名
  private String password;//密码
  private String username;//用户名

  public User() {
    super();
  }
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getLoginname() {
    return loginname;
  }
  public void setLoginname(String loginname) {
    this.loginname = loginname;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  public String getUsername() {
    return username;
  }
  public void setUsername(String username) {
    this.username = username;
  }

  @Override
  public String toString() {
    return "User [id=" + id + ", loginname=" + loginname + ", password="
 + password + ", username=" + username + "]";
  }


}

springmvc-config.xml配置文件具体配置信息如下:




  
  
   
  
  
  
  
    
    
    
      /WEB-INF/content/
    
    
    
      .jsp
    
  

  
    
      
       
      
    
  



web.xml配置文件具体配置信息如下:



 MultipartFileTest

 
 
  springmvc
  
    org.springframework.web.servlet.DispatcherServlet
  
  
   contextConfigLocation
   /WEB-INF/springmvc-config.xml
  
  1
 

 
 
  springmvc
  /
 

 
 
    characterEncodingFilter
    org.springframework.web.filter.CharacterEncodingFilter
    
      encoding
      UTF-8
    
 
  
    characterEncodingFilter
    /*
  



总结:今天主要就介绍Spring MVC拦截器,通过引用拦截器机制,Spring MVC框架可以使用可插拔方式管理各种功能。以上就是完整的使用Spring MVC拦截器实现了用户的权限验证,本文所有的案例都是本人亲自测试,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/145398.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号