当前位置: 首页 > news >正文

SpringMVC-----JSR303以及拦截器

目录

JSR303

什么是JSR303

JSR303的作用

JSR303常用注解 

入门使用 

 拦截器是什么

 拦截器的工作原理

拦截器的作用

拦截器的使用


JSR303

什么是JSR303

JSR303是Java为Bean数据合法性校验提供给的标准框架,已经包含在JavaEE6.0中1。

JSR303通过在Bean属性中标注类似@NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证1。JSR303的参考实现是HibernateValidator,除了支持所有标准的校验注解外,HibernateValidator还具有JSR-380的实现12。

JSR303的作用

JSR303是Java为Bean数据合法性校验提供给的标准框架,其主要作用是提供一种可插拔的验证机制,用于在Java EE和Java SE环境中对Java Bean进行数据校验12。

JSR303通过在Bean属性中标注标准的注解来指定校验规则,并通过验证接口对Bean进行验证。其参考实现是HibernateValidator,除了支持所有标准的校验注解外,HibernateValidator还具有JSR-380的实现12。

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>

在实体类相对应的属性中增加注解用来指定校验  

 @NotNull(message = "班级编号不能为空")
//    @Size(max = 100,min = 10,message = "大小必须在10至100之间")protected Integer book_id;@NotBlank(message = "班级名不能为空")protected String book_name;@NotBlank(message = "班级教员老师不能为空")protected Float price;private String image="暂无图片";

增加以下方法

@RequestMapping("/valiAdd")public String valiAdd(@Validated Bookxx bookxx,BindingResult result,HttpServletRequest req){
//        如果服务端验证不通过,有错误if(result.hasErrors()){
//            服务端验证了实体类的多个属性,多个属性都没有验证通过List<FieldError> fieldErrors = result.getFieldErrors();Map<String,Object> map = new HashMap<>();for (FieldError fieldError : fieldErrors) {
//                将多个属性的验证失败信息输送到控制台System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());map.put(fieldError.getField(),fieldError.getDefaultMessage());}req.setAttribute("errorMap",map);}else {this.bookxxBiz.insertSelective(bookxx);return "redirect:list";}return "clz/edit";}

 在我们的编辑页面修改一下代码

<h1>编辑界面</h1>
<form action="${pageContext.request.contextPath }/clz/${empty book?'valiAdd' : 'edit'}" method="post">书籍编号:<input type="text" name="book_id" value="${book.book_id }"><span style="color: red;">${errorMap.book_id}</span><br>书籍名字:<input type="text" name="book_name" value="${book.book_name }"><span style="color: red;">${errorMap.book_name}</span><br>价格:<input type="text" name="price" value="${book.price }"><span style="color: red;">${errorMap.price}</span><br><input type="submit">
</form>

 测试

 拦截器是什么

拦截器(Interceptor)是一种设计模式,主要用于在方法调用之前、之后或异常抛出时执行一些额外的逻辑操作。拦截器可以用于实现一些公共的横切关注点,例如日志记录、性能监测、事务管理等。

在Java开发框架中,如Spring框架,拦截器是常见的组件,用于在请求处理的不同阶段进行拦截和处理。主要通过实现拦截器接口或扩展拦截器类来定义拦截器逻辑。拦截器可以在请求到达控制器之前、之后或视图渲染之前、之后进行处理。

使用拦截器可以实现各种功能,如身份认证、授权验证、参数校验、异常处理等。它们提供了一种灵活且可重用的方式来扩展和定制应用程序行为。

在Java中,常见的拦截器实现方式包括Java动态代理、Servlet过滤器、Spring AOP(面向切面编程)等。这些拦截器可以帮助开发人员轻松地实现横切关注点的功能,并提供了一种优雅的解决方案来处理公共的业务逻辑。

 拦截器的工作原理

拦截器的作用

  1. 日志记录:拦截器可以用于记录系统运行时的关键信息或操作日志,帮助开发人员进行故障排查、性能优化和系统监测。

  2. 认证和授权:拦截器可以实现身份认证和授权验证,确保只有经过认证的用户能够访问受限资源,并根据用户权限决定其可执行的操作。

  3. 参数校验和数据转换:拦截器可以拦截请求,并对请求参数进行验证和转换,确保数据的合法性和正确性,提高系统的稳定性和安全性。

  4. 统一异常处理:拦截器可以捕获和处理应用程序中的异常,提供统一的异常处理逻辑,避免在每个业务方法中都处理相同的异常情况。

  5. 缓存和性能优化:拦截器可以用于缓存数据或计算结果,提高系统的响应速度和性能。

  6. 日志审计:拦截器可以记录用户的操作行为、业务流程等关键信息,用于审计和追踪系统的操作历史。

  7. 事务管理:拦截器可以控制事务的开启、提交或回滚,确保数据库操作的一致性和完整性。

拦截器的作用不仅限于以上几点,实际上可以根据具体的业务需求定制拦截器的功能和逻辑。它们为应用程序提供了一种灵活和可扩展的方式,实现公共的横切关注点,并提高系统的可维护性和可复用性

拦截器的使用

创建一个名为 Interceptor 的包,存放创建自定义拦截器 再创建一个创建自定义拦截器,名为 : OneInterceptor

package com.xiaoxu.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class OneInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("【OneInterceptor】:preHandle...");return true ;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("【OneInterceptor】:postHandle...");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("【OneInterceptor】:afterCompletion...");}
}

配置自定义拦截器

 <mvc:interceptors><bean class="com.xiaoxu.interceptor.OneInterceptor"></bean></mvc:interceptors>

 在 Interceptor 的包里,创建一个拦截器 TwoInterceptor。

package com.xiaoxu.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class TwoInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("【TwoInterceptor】:preHandle...");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("【TwoInterceptor】:postHandle...");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("【TwoInterceptor】:afterCompletion...");}
}

 创建一个名为 : LoginInterceptor 的拦截器

package com.xiaoxu.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("【implements】:preHandle...");StringBuffer url = request.getRequestURL();if (url.indexOf("/login") > 0 || url.indexOf("/logout") > 0){//        如果是 登录、退出 中的一种return true;}
//            代表不是登录,也不是退出
//            除了登录、退出,其他操作都需要判断是否 session 登录成功过String uname = (String) request.getSession().getAttribute("uname");if (uname == null || "".equals(uname)){response.sendRedirect("/page/login");return false;}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

创建一个名为 : LoginController 的控制器 

package com.xiaoxu.web;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** @author小徐* @site www.veryedu.cn* @company xu集团* @create 2023-09-12 13:27*/
@Controller
public class LoginController {@RequestMapping("/login")public String login(HttpServletRequest req){String uname = req.getParameter("uname");HttpSession session = req.getSession();if ("zs".equals(uname)){session.setAttribute("uname",uname);}return "redirect:/clz/list";}@RequestMapping("/logout")public String logout(HttpServletRequest req){req.getSession().invalidate();return "redirect:/clz/list";}
}

创建一个 login.jsp 的显示页面,进行测试效果 

<%--Created by IntelliJ IDEA.User: 86155Date: 2023/9/12Time: 13:26To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head><body>
<h1>登录</h1>
<form action="/login" method="post">用户:<input name="uname"><input type="submit"></form>
</body>
</html>

测试

相关文章:

SpringMVC-----JSR303以及拦截器

目录 JSR303 什么是JSR303 JSR303的作用 JSR303常用注解 入门使用 拦截器是什么 拦截器的工作原理 拦截器的作用 拦截器的使用 JSR303 什么是JSR303 JSR303是Java为Bean数据合法性校验提供给的标准框架&#xff0c;已经包含在JavaEE6.0中1。 JSR303通过在Bean属性中标…...

基于若依框架实现markdown在线编辑

基于若依框架实现markdown在线编辑 1. 下载mavon-editor npm install mavon-editor --save2. 打开main.js文件, 添加如下 // markdown组件 import { mavonEditor } from "mavon-editor"; import "mavon-editor/dist/css/index.css";// markdown组件 Vue…...

CentOS7上从0开始搭建Zookeeper集群

CentOS7上搭建Zookeeper集群 环境准备安装jdk安装zookeeper下载zookeeper解压zookeeper修改zookeeper配置文件 搭建zookeeper集群修改zoo.cfg文件添加myid文件启动zookeeper集群 环境准备 首先你需要准备三台zookeeper&#xff08;待会会讲zookeeper的安装流程&#xff09;&am…...

康耐视读码器DataMan软件详细使用步骤

1、 点击桌面已经安装好的 dataman 软件并打开 2、 打开之后,点击刷新,刷出来读码器的图标,双击进行连接,或者选中后,点击右下角 的连接。(也可先进行第 9—(2)步更改读码器的 IP,对应的连接对象也更改到同一网 段)如图 3、 连接之后,在设置 快速设置下面把实时显…...

408强化(番外)文件管理

有点看不下去书&#xff0c;408&#xff0c;哎好久没看了&#xff0c;死磕数学时完全不想看其他科目&#xff0c;数学分数也尚未质变。 突然想到一个好点子&#xff0c;只看大纲尝试回忆一下这章的内容。 文件就是为了方便用户使用&#xff0c;按名访问而提出的&#xff0c;从…...

iptables 防火墙配置

文章目录 iptables 防火墙配置规则链的分类–五链处理的动作iptables 常用参数和作用iptables 防火墙配置查看规则链清空规则链设置默认规则将流入的流量丢弃允许ICMP协议流量通过删除默认策略允许所以流量通过设置将所有流入22端口的流量全部拒绝允许指定网段的22端口通过设置…...

面试官:我们深入聊聊Java虚拟机吧

哈喽&#xff01;大家好&#xff0c;我是奇哥&#xff0c;一位专门给面试官添堵的职业面试员 文章持续更新&#xff0c;可以微信搜索【小奇JAVA面试】第一时间阅读&#xff0c;回复【资料】更有我为大家准备的福利哟&#xff01; 文章目录 前言面试Java虚拟机内存模型垃圾收集器…...

【电源专题】案例:异常样机为什么只在40%以下电量时与其他样机显示电量差异10%,40%以上电量差异却都在5%以内。

本案例发生在一个量产产品的测试中,因为产品带电池,所以需要测试产品对于电池电量显示的精确程度。产品使用的是最简单的开路电压查表法进行设计。 案例测试报告的问题在于不同样机之间电量百分比存在差异,大部分是在3%~4%之间。但在7.2V电压时,能够差异10%左右。 在文章:…...

React 全栈体系(七)

第四章 React ajax 一、理解 1. 前置说明 React本身只关注于界面, 并不包含发送ajax请求的代码前端应用需要通过ajax请求与后台进行交互(json数据)react应用中需要集成第三方ajax库(或自己封装) 2. 常用的ajax请求库 jQuery: 比较重, 如果需要另外引入不建议使用axios: 轻…...

NVIDIA 显卡硬件支持的精度模式

很多炼丹师不知道自己英伟达显卡支持哪些精度模式&#xff0c;本文整理了NVIDIA官网的数据&#xff0c;为你解开疑惑。 1. 首先了解CUDA计算能力及其支持的精度模式&#xff1b; 2. 查看自己显卡&#xff08;或其它NVIDIA硬件&#xff09;的计算能力值为多少。 表1 CUDA计算…...

【Java|golang】210. 课程表 II---拓扑排序

一、拓扑排序的定义&#xff1a; 先引用一段百度百科上对于拓扑排序的定义&#xff1a; 对一个有向无环图 ( Directed Acyclic Graph 简称 DAG ) G 进行拓扑排序&#xff0c;是将 G 中所有顶点排成一个线性序列&#xff0c;使得图中任意一对顶点 u 和 v &#xff0c;若边 <…...

STM32CubeMX systick bug?

发觉用新版&#xff08;V6.9.1&#xff09;的它生成代码&#xff0c;会有问题。可能是 BUG。具体如下&#xff1a; 一个简单的点灯程序&#xff0c;用 Keil MDK 5.38a&#xff08;compiler version 6&#xff09;编译。 如果在变量前&#xff0c;不加上关键字“volatile”&am…...

徐亦达机器学习:Kalman Filter 卡尔曼滤波笔记 (一)

P ( x t P(x_t P(xt​| x t − 1 ) x_{t-1}) xt−1​) P ( y t P(y_t P(yt​| x t ) x_t) xt​) P ( x 1 ) P(x_1) P(x1​)Discrete State DM A X t − 1 , X t A_{X_{t-1},X_t} AXt−1​,Xt​​Any π \pi πLinear Gassian Kalman DM N ( A X t − 1 B , Q ) N(AX_{t-1}B,Q)…...

Java和vue的包含数组组件contains、includes

List<String> tempList Arrays.asList("10018","1007","10017","1012"); if(tempList.contains(initMap.get("asset_type_id").toString())){// todo 计算运营终点桩号-起点桩号BigDecimal diffSum collectNum(col…...

OpenCV_CUDA_VS编译安装

一、OpenCV 我这里是下载的OpenCV4.5.4&#xff0c;但是不知道到在vs里面build时一直报错&#xff0c;后面换了4.7.0的版本测试&#xff0c;安装成功。 Release OpenCV 4.5.4 opencv/opencv GitHub 这个里面有官方预编译好的OpenCV库&#xff0c;可以直接食用。 扩展包&am…...

基于减法优化SABO优化ELM(SABO-ELM)负荷预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

记录第一个启动代码的诞生

核使用R52&#xff0c;参考汇编模板&#xff0c;一步一步来实现。 首先是ld文件&#xff0c;这个没啥好说的&#xff0c;主要是关注给vector_table划一块地址、stack地址&#xff0c;如下&#xff1a; .text.intvec :{_vectors_start .;KEEP(*(.text.intvec))_vectors_end .;…...

基于STM32的简化版智能手表

一、前言 本文的OLED多级菜单UI为一个综合性的STM32小项目&#xff0c;使用多传感器与OLED显示屏实现智能终端的效果。项目中的多级菜单UI使用了较为常见的结构体索引法去实现功能与功能之间的来回切换&#xff0c;搭配DHT11&#xff0c;RTC&#xff0c;LED&#xff0c;KEY等器…...

揭秘弹幕游戏制作

最近好多人问弹幕游戏&#xff0c;甚至是招人的也要DOTS做弹幕游戏... 实际上目前的弹幕游戏绝大多数应该和DOTS没有半点关系&#xff0c;别忘了DOTS这项技术渲染问题还没能够被合理解决呢 所以目前用的全都是GPU Instance这项技术&#xff0c;于是乎我决定下场写这篇帖子&am…...

2327. 知道秘密的人数;1722. 执行交换操作后的最小汉明距离;2537. 统计好子数组的数目

2327. 知道秘密的人数 核心思想&#xff1a;动态规划&#xff0c;每天的人可以分为三种&#xff0c;可分享秘密的人&#xff0c;不可分享秘密的人&#xff0c;忘记秘密的人。定义f[i]为第i天可分享秘密的人&#xff0c;那么第(idelay ,iforget)天&#xff0c;会增加f[i]个可分…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

6.计算机网络核心知识点精要手册

计算机网络核心知识点精要手册 1.协议基础篇 网络协议三要素 语法&#xff1a;数据与控制信息的结构或格式&#xff0c;如同语言中的语法规则语义&#xff1a;控制信息的具体含义和响应方式&#xff0c;规定通信双方"说什么"同步&#xff1a;事件执行的顺序与时序…...