首页 > 其他分享 >Spring Boot拦截器

Spring Boot拦截器

时间:2022-11-21 16:10:14浏览次数:52  
标签:拦截器 Spring Boot user org augus import com

Spring MVC 中提供了拦截器功能,可以根据 URL 对请求进行拦截,主要应用于登陆校验、权限验证、乱码解决、性能监控和异常处理等功能上。Spring Boot 同样提供了拦截器功能。 
而在 Spring Boot 项目中,使用拦截器功能需要以下 3 步即可:

  1. 定义拦截器;
  2. 注册拦截器;
  3. 指定拦截规则(如果是拦截所有,静态资源也会被拦截)

一、定义拦截器

在 Spring Boot 中定义拦截器比较简单,只需要创建一个拦截器类,并实现 HandlerInterceptor 接口即可。HandlerInterceptor  接口中定义以下 3 个方法,如下表。

返回值类型

方法声明

描述

boolean

preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 

该方法在控制器处理请求方法前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回 false 表示中断后续操作。

void

postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)

该方法在控制器处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步修改。

void

afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

该方法在视图渲染结束后执行,可以通过此方法实现资源清理、记录日志信息等工作。

以 springboot08 项目为例,在 com.augus.interceptors中创建一个名为 LoginInterceptor 的拦截器类,对登陆进行拦截,代码如下。

package com.augus.interceptors;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

@Slf4j
//创建拦截器类
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取session域中登录的用户对象
Object loginUser = request.getSession().getAttribute("loginUser");
//如果为空,则表示未登录
if(loginUser == null){
//未登录,则返回登录页面
request.setAttribute("msg","您没有权限进行此操作,请先登录");
/*request.getRequestDispatcher("/toLogin").forward(request, response);
* 1、属于转发,也是服务器跳转,相当于方法调用,在执行当前文件的过程中转向执行目标文件,两个文件(当前文件和目标文件)属于同一次请求,前后页共用一个request,可以通过此来传递一些数据或者session信息,request.setAttribute()和request.getAttribute()。
* 2、在前后两次执行后,地址栏不变,仍是当前文件的地址。
* 3、不能转向到本web应用之外的页面和网站,所以转向的速度要快。
* 4、URL中所包含的“/”表示应用程序(项目)的路径。
* */
request.getRequestDispatcher("/user/login").forward(request, response);
return false;
}else{
//登录后的就放行
return true;
}
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("postHandle执行{}", modelAndView);
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("afterCompletion执行异常{}", ex);
}
}

二、注册拦截器

在com.augus.interceptors包下创建一个实现了 WebMvcConfigurer 接口的配置类(使用了 @Configuration 注解的类),重写 addInterceptors() 方法,并在该方法中调用 registry.addInterceptor() 方法将自定义的拦截器注册到容器中。

package com.augus.interceptors;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
/*
addPathPatterns("/**") :表示拦截所有的请求,包括静态资源的请求
addPathPatterns("/**")
*/
//注册拦截器
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/", "/login", "/user/main", "/user/login", "/user/doLogin","/css/**", "/images/**", "/js/**", "/fonts/**");
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
//当访问 “/” 时,直接跳转到登陆页面
registry.addViewController("/").setViewName("/user/login");
}
}

三、指定拦截规则

修改 MyMvcConfig 配置类中 addInterceptors() 方法的代码,继续指定拦截器的拦截规则,代码如下。

package com.augus.interceptors;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
/*
addPathPatterns("/**") :表示拦截所有的请求,包括静态资源的请求
addPathPatterns("/**")
*/
//注册拦截器
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/", "/login", "/user/login", "/user/doLogin","/css/**", "/images/**", "/js/**", "/fonts/**");
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
//当访问 “/” 时,直接跳转到登陆页面
registry.addViewController("/").setViewName("/user/login");
}
}

在指定拦截器拦截规则时,调用了两个方法,这两个方法的说明如下:

  • addPathPatterns:该方法用于指定拦截路径,例如拦截路径为“/**”,表示拦截所有请求,包括对静态资源的请求。
  • excludePathPatterns:该方法用于排除拦截路径,即指定不需要被拦截器拦截的请求。

四、案例解析:拦截器实现登录功能验证

1.需求说明

从表中查询出来数据,进行登录操作的拦截

 

Spring Boot拦截器_mvc

2.搭建springboot项目

我这里就是基于之前测试打包的那个springboot08模块实现的,使用 thymeleaf 模板技术实现,利用上面实现的拦截器完成

3.在com.augus.pojo包中创建User表实体类

package com.augus.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class User implements Serializable {
private Integer uid;
private String username;
private String password;
}

4.在resources目录中的mybatis包中创建 UserMapper.xml,内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.augus.mapper.UserMapper">
<!--查询所有的员工信息-->
<select id="findByUserName" resultType="user">
select * from user where username = #{username}
</select>
</mapper>

5.在com.augus.mapper包中创建 UserMapper接口,内容如下:

package com.augus.mapper;

import com.augus.pojo.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper {
User findByUserName(String username);
}

6.在com.augus.service包

创建接口 UserService,内容如下:

package com.augus.service;

import com.augus.pojo.User;

public interface UserService {
User findByUserName(String username);
}

在service包下创建impl包,存放实体类:

package com.augus.service.impl;

import com.augus.mapper.UserMapper;
import com.augus.pojo.User;
import com.augus.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;

@Override
public User findByUserName(String username) {
return userMapper.findByUserName(username);
}
}

7.在com.augus.controller包下创建 LoginController 控制器

package com.augus.controller;

import com.augus.pojo.User;
import com.augus.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;
import java.util.Map;

@Slf4j
@Controller
@RequestMapping("/user")
public class LoginController {
@Autowired
private UserService userService;

@RequestMapping("/login")
public String userLogin(){
return "login";
}

@RequestMapping("/doLogin")
public String doLogin(User user, Map<String,Object> map, HttpSession session){
//根据用户用户名查询用户信息
User userQuery = userService.findByUserName(user.getUsername());

if(userQuery != null && userQuery.getPassword().equals(user.getPassword())){
//将登录的用户信息方到session域中
session.setAttribute("loginUser", user);
log.info("登陆成功,用户名:" + user.getUsername());
//防止重复提交使用重定向
return "redirect:/user/main";
}else {
map.put("msg", "用户名或密码错误");
log.error("登录失败");
return "login";
}
}

@RequestMapping("/main")
public String main(){
return "main";
}
}

8.在resources下的templates下创建前端页面

8.1.创建login.html,代码为:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>hi</title>
</head>
<body>
<form th:action="@{/user/doLogin}" method="post">
<table style="margin: auto">
<tr>
<td th:if="${not #strings.isEmpty(msg)}" colspan="2" align="center">
<p style="color: red;margin: auto" th:text="${msg}"></p>
</td>
</tr>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" required><br></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" required><br></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="登陆">
<input type="reset" value="重置">
</td>
</tr>
</table>
</form>
</body>
</body>
</html>

8.1.创建main.html,代码为:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>系统主页</title>
</head>
<body>
<h1 th:text="'欢迎您:'+${session.loginUser.getUsername()}" th:if="${not #strings.isEmpty(session.loginUser)}"></h1>
</body>
</html>

9.启动项目

通过浏览器访问登录后的主页(http://localhost:8080/springboot08/user/main ),会提示无权限,需要登录才行  

Spring Boot拦截器_拦截器_02

在登陆页用户名和密码输入框内分别输入 “zhangsan”和“132123” 错误的账户或者密码,点击下方的登陆按钮,结果如下图。

 

Spring Boot拦截器_spring_03

 在登陆页用户名和密码输入框内分别输入 “zhangsan”和“123456”,点击下方的登陆按钮,结果如下图。

Spring Boot拦截器_mvc_04



标签:拦截器,Spring,Boot,user,org,augus,import,com
From: https://blog.51cto.com/u_13661275/5874035

相关文章

  • Spring Data (数据)MongoDB
    版本4.0.0SpringDataMongoDB项目将Spring的核心概念应用于使用MongoDB文档样式数据存储的解决方案的开发。我们提供了一个“模板”作为存储和查询文档的高级抽象。您可能......
  • SpringMVC知识
    1Spring框架Spring框架指的都是SpringFramework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。Spring自带IoC(InverseofControl:控制反转)和A......
  • spring boot调试redis报错:Unable to connect to Redis; 问题记录
    1、代码packagecom.example.spring1121;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springfr......
  • springboot maxheadersize 配置不当 oom
    在SpringBoot项目中,我们可以通过如下配置来设置header的大小:server.max-http-header-size=102400但如果此参数设置不好,便会引来OOM等相关问题,特别是并发的时候。m......
  • Spring Data (数据)JPA(二)
    5.1.8.锁定若要指定要使用的锁定模式,可以在查询方法上使用注释,如以下示例所示:​​@Lock​​例120。在查询方法上定义锁定元数据interfaceUserRepositoryextendsReposit......
  • spring cloud的定义
    SpringCloud是一系列框架的有序集合。SpringCloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来。通过SpringBoot风格......
  • JeecgBoot 3.4.4 版本发布,开源的企业级低代码平台
    项目介绍JeecgBoot是一款企业级的低代码平台!前后端分离架构SpringBoot2.x,SpringCloud,AntDesign&Vue3,Mybatis-plus,Shiro,JWT支持微服务。强大的代码生成器让前后端代码......
  • springmvc 项目启动后自动运行方法
    packagecom.jeeplus.modules.asr.config;importcom.jeeplus.common.config.Global;importcom.jeeplus.modules.asr.netty.server.UDPServer;importcom.jeeplus.modu......
  • SpringMVC - RestFul
    一、RestFul是一个请求路径的风格,将请求参数放在url中以/来分割请求参数。url:/delete/1    1就是参数RestFul的请求方式对应的是不同的操作get : 查询post:......
  • Spring-boot-源码-BeanMetadataElement
    org.springframework.beans.BeanMetadataElement接口BeanMetadataElement/**Interfacetobeimplementedbybeanmetadataelementsthatcarryaconfiguration......