【SpringMVC】JSR303与拦截器的使用

news2024/10/5 18:30:42

文章目录

  • 一、JSR303
    • 1.1 JSR303是什么
    • 1.2 JSR 303的好处包括
    • 1.3 常用注解
    • 1.4 实例
      • 1.4.1 导入JSR303依赖
      • 1.4.2 规则配置
      • 1.4.3 编写校验方法
      • 1.4.4 编写前端
  • 二、拦截器
    • 2.1 拦截器是什么
    • 2.2 拦截器与过滤器的区别
    • 2.3.应用场景
    • 2.4 快速入门
    • 2.5.拦截器链
    • 2.6 登录拦截权限案例
      • 2.6.1 LoginController.java
      • 2.6.2 配置拦截器
      • 2.6.3 创建拦截器
      • 2.6.4 测试

一、JSR303

1.1 JSR303是什么

JSR 303是Java规范请求(Java Specification Request)的编号,它定义了Java Bean验证的标准规范。JSR 303的全称是Bean Validation,它提供了一种在Java应用程序中进行数据验证的机制。

Bean Validation是一种基于注解的验证框架,它允许开发人员在Java Bean的属性上添加验证规则,以确保数据的合法性和完整性。通过使用Bean Validation,开发人员可以在数据输入阶段就捕获错误,避免后续可能出现的潜在问题。

1.2 JSR 303的好处包括

  1. 简化验证逻辑:通过使用注解,开发人员可以在Java Bean的属性上直接添加验证规则,而不需要编写繁琐的验证代码。
  2. 统一验证规范:JSR303定义了一组常用的验证注解,使得不同的开发人员在验证过程中可以使用相同的规范,提高了代码的可读性和可维护性。
  3. 提高代码质量:通过在Java Bean中添加验证规则,可以在数据输入阶段就捕获错误,避免了后续可能出现的潜在问题。
  4. 可扩展性:JSR303提供了自定义注解的能力,开发人员可以根据自己的需求定义新的验证注解。

1.3 常用注解

  1. @NotNull:用于验证属性值不能为null。
  2. @Size:用于验证字符串、集合或数组的大小是否在指定范围内。
  3. @Min:用于验证数字属性的最小值。
  4. @Max:用于验证数字属性的最大值。
  5. @Pattern:用于验证字符串属性是否符合指定的正则表达式。
  6. @Email:用于验证字符串属性是否符合电子邮件格式。
  7. @NotBlank:用于验证字符串属性是否非空且长度大于0。
  8. @NotEmpty:用于验证字符串、集合或数组属性是否非空。
  9. @Range:用于验证数字属性是否在指定范围内。
  10. @Valid:用于嵌套验证,验证关联对象。

1.4 实例

1.4.1 导入JSR303依赖

<!-- JSR303 -->
<hibernate.validator.version>6.0.7.Final</hibernate.validator.version>
 
<!-- JSR303 -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>${hibernate.validator.version}</version>
</dependency>

1.4.2 规则配置

package com.xqx.model;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
 
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
 
@Data//相当于set get toString方法
@AllArgsConstructor //有参构造器
@NoArgsConstructor //无参构造器
public class Book{

		 @NotBlank(message = “书本信息不能为空!")
		 private String bookName;

		 @NotNull(message = “书本价格不能为空!")
		 private Float bookPrice:
		 
		 private String bookType;
 
   
}

1.4.3 编写校验方法

  /**
     * 书本新增
     * 请求路径 SSM/book/editBook
     * @param book
     * @return
     */
    @RequestMapping("/addBook")
    public String addBook(@Validated Book book, BindingResult bindingResult){
        System.out.println("进入新增方法");
        //判断是否验证成功
        if(bindingResult.hasErrors()){
            System.out.println("验证失败");
            //验证失败
            return "book/addBook";
 
        }else {
            //验证成功
        bookService.insert(book);
        return "redirect:queryBookPage";
        }
    }
 
    /**
     *  @ModelAttribute: 所标记的方法为非请求处理方法,在所有请求方法之前被调用
     *  @odelAttribute 在所有的@RequestMapping的方法之前被调用!
     *
     *  作用:数据预加载
     *  特点:无返回值
     */
    @ModelAttribute
    public void init(Model model){
        System.out.println("非请求处理方法");
        //必须操作
        model.addAttribute("book",new Book());
    }

1.4.4 编写前端

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
    <%@include file="/common/head.jsp"%>
    <title>Title</title>
</head>
<style>
       .cl{
           color: red;
       }
 
</style>
<body>
<h1>书本新增</h1>
    <fmt:form modelAttribute="book"  action="${ctx}/book/addBook" method="post">
        <label>书本名称:</label><input type="text" name="bookName"><fmt:errors cssClass="cl" path="*"/><br/>
        <label>书本价格:</label><input type="text" name="bookPrice"><%--<fmt:errors cssClass="cl"  path="bookPrice"/>--%><br/>
        <label>书本类型:</label>
        <select name="bookType">
            <option value="神话">神话</option>
            <option value="教育">教育</option>
            <option value="文学">文学</option>
            <option value="玄幻">玄幻</option>
        </select>
 
        <br/>
        <input type="submit" value="添加">
    </fmt:form>
 
</body>
</html>

在这里插入图片描述

二、拦截器

2.1 拦截器是什么

SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。

2.2 拦截器与过滤器的区别

拦截器(Interceptor)通常是指一种拦截和处理请求的组件或模块。它可以在请求到达目标之前或之后进行拦截,并对请求进行修改、记录或处理。拦截器通常用于实现横切关注点(cross-cutting concerns),如日志记录、安全认证、性能监控等。拦截器可以在应用程序的不同层级中使用,例如在网络层、业务逻辑层或数据访问层。

过滤器(Filter)则是一种用于过滤和处理数据的组件或模块。它可以在数据流经过时对数据进行过滤、转换或处理。过滤器通常用于对数据进行预处理或后处理,以满足特定的需求或要求。常见的应用包括数据清洗、数据转换、数据压缩等。过滤器可以在不同的数据处理环节中使用,例如在输入输出流、数据库查询、图像处理等。

2.3.应用场景

  • 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
  • 权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;
  • 性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
  • 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

2.4 快速入门

创建拦截器

package com.xqx.interceptor;
 
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/*
1. 定义拦截器类,实现HandlerInterceptor接口
2. 注意当前类必须受Spring容器控制
 */
public class OneInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【OneInterceptor】:preHandle...");
 
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("【OneInterceptor】:postHandle...");
 
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("【OneInterceptor】:afterCompletion...");
    }
}

配置拦截器

在spring-mvc.xml中配置:

    <!--配置拦截器-->
    <mvc:interceptors>
        <bean class="com.xqx.interceptor.OneInterceptor"></bean>
    </mvc:interceptors>

2.5.拦截器链

如果多个拦截器能够对相同的请求进行拦截,则多个拦截器会形成一个拦截器链,主要理解拦截器链中各个拦截器的执行顺序。拦截器链中多个拦截器的执行顺序,根拦截器的配置顺序有关,先配置的先执行。

在spring-mvc.xml中配置多个拦截器

    <!--2) 多拦截器(拦截器链)-->
    <mvc:interceptors>
            <mvc:interceptor>
                <!--拦截所有-->
                <mvc:mapping path="/**"/>
                <bean class="com.xqx.interceptor.OneInterceptor"/>
            </mvc:interceptor>
            <mvc:interceptor>
                <!--拦截users下的controller-->
                <mvc:mapping path="/book/**"/>
                <bean class="com.xqx.interceptor.TwoInterceptor"/>
            </mvc:interceptor>
    </mvc:interceptors>

使用了拦截器链的效果
在这里插入图片描述

2.6 登录拦截权限案例

2.6.1 LoginController.java

package com.xqx.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
 
import javax.servlet.http.HttpSession;
 
@Controller
public class LoginController {
 
    /**
     * 跳转到登录页面
     * @return
     */
    @RequestMapping("tologin")
    public String toLogin(){
        return "login";
    }
 
    /**
     * 登录方法
     * @param username 账号
     * @param password 密码
     * @return
     */
    @RequestMapping("/userLogin")
    public String userLogin(String username, String password, HttpSession session, Model model){
        if("admin".equals(username)|| password.equals("123")){
           session.setAttribute("username",username);
            //这里的"/"是跳转的@RequestMapping配置的值
            return "redirect:/";
        }
 
        model.addAttribute("msg","账号或者密码错误");
        return "login";
    }
 
 
    /**
     * 安全退出
     * @param session
     * @return
     */
    @RequestMapping("/userLogout")
    public String userLogout(HttpSession session){
        //清空session
        session.invalidate();
 
        return "redirect:tologin";
    }
 
 
 
}

2.6.2 配置拦截器

<mvc:interceptors>
    <bean class="com.xqx.interceptor.LoginInterceptor"></bean>
</mvc:interceptors>

2.6.3 创建拦截器

package com.xqx.interceptor;
 
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求路径
        String url = request.getRequestURI();
        System.out.println(url);
        //判断是否是跳转登录页面的请求 放行
        if(url.indexOf("/tologin")>0)
            return true;
        //判断是否是用户登录 放行
        if(url.indexOf("/userLogin")>0)
            return true;
        //获取session
        HttpSession session = request.getSession();
        //获取session中的用户对象
        String username = (String) session.getAttribute("username");
        //判断session中的用户对象是否存在,存在放行,不存在跳转登录页面
        if(username!=null)
            return true;
        request.setAttribute("msg","您还没有登录,请登录!");
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
        return false;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
 
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
 
    }
}

2.6.4 测试

账号密码错误的情况下
在这里插入图片描述
在未登录的情况下访问首页
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1005442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频监控系统/视频云存储EasyCVR接入国标GB28181设备无法播放设备录像,是什么原因?

安防视频监控平台EasyCVR支持将部署在监控现场的前端设备进行统一集中接入&#xff0c;可兼容多协议、多类型设备&#xff0c;管理员可选择任意一路或多路视频实时观看&#xff0c;视频画面支持单画面、多画面显示&#xff0c;视频窗口数量有1、4、9、16个可选&#xff0c;还能…

第四章 Linux网络编程

ARP 协议 ARP 协议&#xff08;Address Resolution Protocol&#xff09;通过 IP 地址查找对应的 MAC 地址。 当一个主机需要发送数据给另一个主机时&#xff0c;它首先会检查本地的 ARP 缓存表&#xff08;ARP cache&#xff09;中是否存在目标主机的 MAC 地址。如果存在&…

【VS插件】VS code上的Remote - SSH

【VS插件】VS code上的Remote - SSH 目录 【VS插件】VS code上的Remote - SSH获得Linux服务器或者Linux系统的IP地址下载插件远程登录注意如果Linux虚拟机系统无法连接成功可能是没有开启ssh服务优势 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2023.9.12 前言&#xff1…

社群团购是简单的商业模式,把握红利,冲刺双11

其实&#xff0c;不管微商、社群团购、直播带货、内容电商、视频号&#xff0c;小红书电商……都只是卖货的渠道&#xff0c;新渠道 社群团购让销售变得更加专业和简单&#xff0c;货源方负责产品的生产、渠道方负责销售。好好卖货&#xff0c;卖好货&#xff01; 是分工合作&a…

MATLAB | 绘图复刻(十二) | 桑基图+气泡图

hey 绘图复刻居然已经出到第十二期&#xff0c;破百指日可待hiahiahia&#xff0c;今天来复刻一下 Yu, W., Wang, Z., Yu, X. et al. Kir2.1-mediated membrane potential promotes nutrient acquisition and inflammation through regulation of nutrient transporters. Nat …

【css | loading】好看的loading特效

示例&#xff1a; https://code.juejin.cn/pen/7277764394618978365 html <div class"pl"><div class"pl__dot"></div><div class"pl__dot"></div><div class"pl__dot"></div><div c…

认识 AIGC ,浅淡 AIGC 的那些事—— AIGC:用 AI 创造万物

文章目录 &#x1f525;关于活动&#x1f4cb;前言&#x1f3af;什么是 AIGC&#x1f9e9;AIGC&#xff1a;用 AI 创造万物 &#x1f3af;AIGC 发展历程&#x1f3af;AIGC 峰会分享&#x1f3af;AIGC 与大模型&#x1f4dd;最后&#x1f4d1;参考资料 &#x1f525;关于活动 从…

数据库-基础篇-SQL-DML(数据操作语言)

目录 前言 一 . 添加数据(insert) 1.指定字段添加数据 2. 全部字段添加数据 3. 批量添加数据(指定字段) 4.批量添加数据(全部字段) 二 . 修改数据(Update) 三 . 删除数据 总结 前言 DML英文全称是Data Manipulation Language(数据操作语言)&#xff0c;用来对数据库中…

Revit SDK 内容摘要: 9.0 - 9.1

前提 不包含已单独写博客部分。 Revit SDK Samples 9.0 AllViews 创建图纸&#xff0c;并放置视图。 ViewSheet sheet ViewSheet.Create(doc, m_titleBlock.Id); double xDistance 0; double yDistance 0; CalculateDistance(sheet.Outline, views.Size, ref xDistance…

few shot目标检测survey paper笔记(整体概念)

paper: Few-Shot Object Detection: A Comprehensive Survey (CVPR2021) 深度学习提高了目标检测的精度&#xff0c;但是它需要大量的训练数据。 对于训练数据集中没有见过的目标&#xff0c;是检测不了的&#xff0c;所以就限制了在实际中的应用。 如果想让模型去识别新的目标…

【SLAM】坐标系变换与外参标定

【SLAM】坐标系变换与外参标定 突然发现学习文档有下面这句话&#xff1a; 学习这件事不在乎有没有人教你&#xff0c;最重要的是在于你自己有没有觉悟和恒心。——法布尔 task02从二维坐标系开始推导坐标系变换参数&#xff0c;进而加入平移&#xff0c;加入Z轴拓展到三维坐…

论文笔记:Deep Representation Learning for Trajectory Similarity Computation

ICDE 2018 1 intro 1.1 背景 用于计算轨迹相似性的成对点匹配方法&#xff08;DTW&#xff0c;LCSS&#xff0c;EDR&#xff0c;ERP&#xff09;的问题&#xff1a; 轨迹的采样率不均匀 如果两个轨迹表示相同的基本路径&#xff0c;但是以不同的采样率生成&#xff0c;那么这…

uni-app 之 下拉刷新,上拉加载,获取网络列表数据

uni-app 之 下拉刷新&#xff0c;上拉加载&#xff0c;获取网络列表数据 image.png <template><view><!-- 车源模块 -->--- uni.request 网络请求API接口 ---<view v-for"(item) in newsArr" :key"item.id" style"display: fle…

uniapp使用Vue2框架生成二维码

1. 生成二维码插件 npm install qrcodejs2 --save 上代码&#xff1a; <template><view><view class"page" ><div id"qrCode" ref"qrCodeDiv" ></div></view><view class"page">核…

微信小程序音频后台播放功能

微信小程序在手机息屏后依旧能播放音频&#xff0c;需要使用 wx.getBackgroundAudioManager() 方法创建后台音乐播放器&#xff0c;并将音乐播放任务交给这个后台播放器。 具体实现步骤如下&#xff1a; 小程序页面中&#xff0c;使用 wx.getBackgroundAudioManager() 方法创…

springMVC1之ModelAttribute注解

什么叫先执行 只要控制器方法一过来&#xff0c; 这个控制器里面的所有方法都会比下面执行的慢一点 我们来访问一个页面 也就是说访问的是控制器里面下面这个方法 看一下控制台执行效果 还是shouUser先执行了 什么叫如果没有提交的字段使用原来的数据 比如下面这个方法 我们在调…

php高级 TP+Redis实现发布订阅和消息推送案例实战

Redis 的发布-订阅模型是一种消息通信模式&#xff0c;它允许客户端之间通过特定的频道进行通信。在这种模型中&#xff0c;有些客户端负责发布消息&#xff08;发布者&#xff09;&#xff0c;而其他客户端则订阅它们感兴趣的频道并接收这些消息&#xff08;订阅者&#xff09…

自动驾驶汽车下匝道路径优化控制策略研究

摘要 随着社会不断进步&#xff0c; 经济快速发展&#xff0c; 科学技术也在突飞猛进&#xff0c; 交通行业是典型的领域之一。现阶段的交通发展&#xff37; 实现智能交通系统为目标&#xff0c; 正逐渐从信息化步入智能化&#xff0c;朝着智慧化迈进。近年来&#xff0c;一系…

线程练习题

有三个线程&#xff0c;分别只能打印A&#xff0c;B和C&#xff0c;要求按顺序打印ABC&#xff0c;打印10次 输出示例&#xff1a; ABC ABC ABC ABC ABC ABC ABC ABC ABC ABC &#xff08;1&#xff09;、这种方法并不能达到题目要求&#xff0c;因为无法确认当线程…

ChatGPT AIGC 实现Excel行列多条件交叉查找

查找函数在Excel中一直是非常重要的知识点,我们让ChatGPT AIGC来总结一下关于查找函数的优点与了处。 Excel中的查找函数是一种非常强大且多用途的工具,具有以下优点和作用: 1. 数据定位:查找函数可以帮助我们在大量数据中快速定位某个特定的数据或信息。 2. 数据整理:如…