SpringMVC之JSR303与拦截器

目录

一.JSR303

1.什么是JSR303

 2.为什么使用JSR303

3.JSR303常用注解 

4.快速入门

4.1导入Maven依赖

4.2 配置校验规则

 4.3 对服务端数据添加进行校验

4.4 结果测试

二.拦截器

1.什么是拦截器

2.拦截器与过滤器

3.应用场景

4.基本拦截器配置

5 案例演示(模拟登录请求拦截)

5.1配置拦截器

 5.2.编写controller层

5.3测试结果

​编辑

6.拦截器的工作

原理


一.JSR303

1.什么是JSR303

JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。 JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint(约束) 的实现,除此之外还有一些附加的 constraint

 2.为什么使用JSR303

使用JSR 303(Bean Validation)有许多好处,它可以帮助开发人员轻松实施数据验证和约束,从而提高应用程序的质量和可维护性。

  1. 代码简洁性: JSR 303允许开发人员在JavaBean上使用注解来定义验证规则,使代码更加简洁、清晰和易于理解。验证规则与数据模型直接关联,不需要编写大量的自定义验证代码。

  2. 重用性: JSR 303提供了一组通用的验证注解,如@NotNull、@Size、@Email等,这些注解可以在不同的数据模型中重复使用,避免了重复编写验证逻辑的需要。

  3. 集成性: JSR 303可以轻松集成到Java EE 和 Spring 等常见的Java框架中,这意味着你可以在使用这些框架的项目中无缝地应用数据验证。例如,在Spring框架中,你可以使用@Valid注解来触发Bean Validation验证。

  4. 提高数据质量: 使用JSR 303可以确保数据在进入应用程序、存储到数据库、传输到客户端或用于其他用途之前是合法和有效的。这有助于防止无效、不一致或损坏的数据进入系统,提高了数据的质量和完整性。

  5. 减少错误和漏洞: 数据验证是防止应用程序中的许多常见错误和漏洞的关键。通过使用JSR 303进行验证,可以降低因输入错误或恶意输入而导致的安全漏洞的风险。

  6. 可扩展性: JSR 303允许开发人员创建自定义验证注解和验证器,以满足特定应用程序的需求。这使得你可以根据具体业务逻辑来定义自己的验证规则。

总之,JSR 303是Java中一种强大的数据验证机制,它使数据验证变得更加容易和一致,有助于提高应用程序的质量、可维护性和安全性,其最重要特性就是为了防止一些非法请求对后端进行攻击

3.JSR303常用注解 

注解说明
@Null用于验证对象为null
@NotNull用于对象不能为null,无法查检长度为0的字符串
@NotBlank只用于String类型上,不同于@NotNull的是,@NotBlank还会去掉前后空格后验证是否为空。
@NotEmpty用于集合类、String类不能为null,且size>0。但是带有空格的字符串校验不出来
@Size用于对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length用于String对象的大小必须在指定的范围内
@Pattern用于String对象是否符合正则表达式的规则
@Email用于String对象是否符合邮箱格式
@Min用于Number和String对象是否大等于指定的值
@Max用于Number和String对象是否小等于指定的值
@AssertTrue用于Boolean对象是否为true
@AssertFalse用于Boolean对象是否为false

@Validated与@Valid区别

@Validated:

  • Spring提供的

  • 支持分组校验

  • 可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上

  • 由于无法加在成员属性(字段)上,所以无法单独完成级联校验,需要配合@Valid

@Valid:

  • JDK提供的(标准JSR-303规范)

  • 不支持分组校验

  • 可以用在方法、构造函数、方法参数和成员属性(字段)上

  • 可以加在成员属性(字段)上,能够独自完成级联校验

4.快速入门

4.1导入Maven依赖

<!-- 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>

4.2 配置校验规则

1.在模型类中校验属性是否为空

 @NotNull(message = "书籍id不能为空")private Integer bid;@NotBlank(message = "书籍名称不能为空")private String bname;@NotBlank(message = "书籍价格不能为空")private Float price;

 4.3 对服务端数据添加进行校验

在服务端中进行校验,校验的模型的属性中出现错误,则将错误信息的属性进行遍历添加到map集合中并保存起来回显到前端,需要注意的是,注解@validated保存的是校验时的参数,最终校验的结果保存在BindingResult中

 //    给数据添加服务端校验@RequestMapping("/valiAdd")public String valiAdd(@Validated HBook hBook, 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.hBookbiz.insertSelective(hBook);return "redirect:list";}return "book/edit";}

4.4 结果测试

 1.当我们在表单中不添加参数直接进行提交,按正常情况会报出空指针异常,但是在进行后端校验后

2.会将错误信息回显到前端,同时,也将错误信息打印在控制台

注意点:

这时候我们肯定会疑问,这不和前端验证也差不多嘛,他们的区别在于,我们进行前端验证时大多使用的是JS语法,但是有时候安全系数不高,不法分子会通过一些手段可以直接绕过前端验证进行发送请求,这个时候后端验证的优势就体现出来了,在实际开发过程中,不管是前端校验还是后端校验,都要在网页中进行实现,前端验证主要是给我们的程序所面向的客户所使用,而后端验证更像是保护我们的程序,提高安全性

二.拦截器

1.什么是拦截器

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

2.拦截器与过滤器

什么是过滤器(Filter)

依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。

拦截器与过滤器的区别

  • 过滤器(filter)

    1.filter属于Servlet技术,只要是web工程都可以使用

    2.filter主要由于对所有请求过滤

    3.filter的执行时机早于Interceptor

  • 拦截器(interceptor)

    1.interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用

    2.interceptor通常由于对处理器Controller进行拦截

    3.interceptor只能拦截dispatcherServlet处理的请求

3.应用场景

  • 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

  • 权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;

  • 性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

  • 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

4.基本拦截器配置

在当前Java目录下新建一个interceptor包,创建拦截器类

1.

package com.YU.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...");}
}

2.

package com.YU.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...");}
}

然后在我们的spring-mvc.xml配置文件中配置多拦截器

<mvc:interceptors><!--2) 多拦截器(拦截器链)--><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.YU.interceptor.OneInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/clz/**"/><bean class="com.YU.interceptor.TwoInterceptor"/></mvc:interceptor></mvc:interceptors>

5 案例演示(模拟登录请求拦截)

5.1配置拦截器

实现思路:在当前拦截器中首先判断是否为登录或者退出中的操作的一种,如果是那么进行下一步操作进入登录页面,在登录页面中获取表单提交的数据,判断登录信息是否保存到session中,如果session存在,那么就跳转到主页面中,如果session不存在,那么就对其进行拦截重定向到登录页面

package com.YU.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 {}
}

 5.2.编写controller层

这里我们做了登录和退出的方法,登录时,登录信息准确,则将其保存到session中,并返回主页面,退出时则将session进行销毁,在登录时信息不准确会被拦截器拦截

package com.YU.web;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** @author YU* @create 2023-09-12 10:09*/
@Controller
public class LoginController {@RequestMapping("/login")public String login(HttpServletRequest req){String uname = req.getParameter("uname");HttpSession session = req.getSession();if ("YU".equals(uname)){session.setAttribute("uname",uname);}return "redirect:/book/list";}@RequestMapping("/logout")public String logout(HttpServletRequest req){req.getSession().invalidate();return "redirect:/book/list";}
}

5.3测试结果

我们在登录时信息不准确,会被拦截重定向回登录页面,

在信息准确时将登录信息保存到session中拦截器进行判断并放行进入主页面

当登录信息保存到session中时我们可以通过访问退出的方法,销毁session,这时会重定向到登录页面,需要重新登录,未保存session拦截器依然会对其进行拦截

6.拦截器的工作

原理

  • preHandle:用于对拦截到的请求进行预处理,方法接收布尔(true,false)类型的返回值,返回true:放行,false:不放行。

    执行时机:在处理器方法执行前执行

    方法参数

    参数说明
    request请求对象
    response响应对象
    handler拦截到的方法处理

  • postHandle:用于对拦截到的请求进行后处理,可以在方法中对模型数据和视图进行修改

    执行时机:在处理器的方法执行后,视图渲染之前

    方法参数

    参数说明
    request请求对象
    response响应对象
    handler拦截到的处理器方法
    ModelAndView处理器方法返回的模型和视图对象,可以在方法中修改模型和视图

  • afterCompletion:用于在整个流程完成之后进行最后的处理,如果请求流程中有异常,可以在方法中获取对象

    执行时机:视图渲染完成后(整个流程结束之后)

    方法参数

    参数说明
    request请求参数
    response响应对象
    handler拦截到的处理器方法
    ex异常对象

今天的学习到这里就结束了,感谢各位大大的观看,各位大大的三连是博主更新的动力,感谢谢谢谢谢谢谢谢谢各位的支持!!!!! 

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

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

相关文章

区块链实验室(23) - FISCO中PBFT耗时与流量特征

前面的实验(区块链实验室(11) - PBFT耗时与流量特征)用仿真的PBFT观察耗时。现在用真实的Fisco网络再次观察其特征。同样地&#xff0c;用相同的网络&#xff0c;即100个节点构成的无标度网络。在每个节点上发起10次交易&#xff0c;记录每次交易的耗时。结果见下图所示。 前半…

VSCode『SSH』连接服务器『GUI界面』传输

前言 最近需要使用实验室的服务器训练带有 GUI 画面的 AI 算法模型&#xff08;pygame&#xff09;&#xff0c;但是我是使用 SSH 连接的&#xff0c;不能很好的显示模型训练的效果画面&#xff0c;所以下面将会讲解如何实现 SSH 连接传输 Linux GUI 画面的 注&#xff1a;我们…

Postman —— HTTP请求基础组成部分

一般来说&#xff0c;所有的HTTP Request都有最基础的4个部分组成&#xff1a;URL、 Method、 Headers和body。 &#xff08;1&#xff09;Method 要选择Request的Method是很简单的&#xff0c;Postman支持所有的请求方式。 &#xff08;2&#xff09;URL 要组装一条Request…

华为HCIA(五)

Vlan id 在802.1Q中 高级ACL不能匹配用户名和源MAC 2.4G频段被分为14个交叠的&#xff0c;错列的20MHz信道&#xff0c;信道编码从1到14&#xff0c;邻近的信道之间存在一定的重叠范围 STA通过Probe获取SSID信息 Snmp报文 网络管理设备异常发生时会发送trap报文 D类地址是…

基于Java网络书店商城设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

亚马逊云科技 Amazon Lightsail :一种在云服务器上运行容器的简单方法

当向开发人员介绍亚马逊云科技云服务时&#xff0c;通常会花一点时间来介绍并演示 Amazon Lightsail 。它是迄今为止开始使用亚马逊云科技的最简单方法。使用它&#xff0c;您在几分钟内即可在自己的虚拟服务器上运行您的应用程序。而后增加了在 Amazon Lightsail 上部署基于容…

C语言字符函数和字符串函数(1)

大家好&#xff0c;我们又见面了&#xff0c;让大家久等了&#xff0c;我们今天就来学习字符函数和字符串函数。 在开启今天的学习之前呢&#xff0c;我来解决一下一些小伙伴平时找不到库函数使用的烦恼&#xff0c;因为我们cplusplus.com最新版本不能够查询函数&#xff0c;我…

排查disabled问题之谷歌新版本特性

问题复现 最近我突然接手一个后台的bug&#xff0c;这个后台很久没有迭代更新了&#xff0c;我也不熟悉业务&#xff0c;所以只能看一下源码&#xff0c;问题很快就复现&#xff0c;测试的修复操作也很正确&#xff0c;就是因为渲染的input标签中存在disableddisabled’属性导…

英国留学生务必谨慎使用ChatGPT!!!

ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;是OpenAI研发的聊天机器人程序&#xff0c;于2022年11月30日发布。ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它能够基于在预训练阶段所见的模式和统计规律…

1.IAR-8051安装

新版安装教程&#xff1a;IAR EW for 8051 简介与安装 新版软件zhuce&#xff1a;IAR EW for 8051 软件注册 - 知乎 这个新版的我也放到网盘里面了&#xff0c;自己自行选择安装 一、下载IAR-8051 链接&#xff1a;https://pan.baidu.com/s/1mYwSQvSjAiSzltrEbK3yAw?pwd43cd …

【产品经理】深入B端SaaS产品设计核心理念

这几年各企业的B端业务都在做SaaS平台&#xff0c;但对SaaS的了解还不是完全全面&#xff0c;对于一些产品的定位以及设计还在探索中 本文讨论“为什么采用SaaS模式”、“SaaS产品有哪些”以及“如何做好SaaS产品设计”三个话题&#xff0c;核心是产品设计&#xff0c;主要从需…

LabVIEW开发航天器模拟器的姿态控制和反作用轮动量管理

LabVIEW开发航天器模拟器的姿态控制和反作用轮动量管理 在过去十年中&#xff0c;航天器一直是现代技术进步的先决条件。迄今为止&#xff0c;为了更好地完成各种实际任务&#xff0c;已经在航天器姿态控制领域进行了大量研究。航天器一旦进入太空&#xff0c;就容易出现不确定…

CSS

CSS CSS是什么 层叠样式表 (Cascading Style Sheets).CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结构分离.说白了就是让网页变得好看 什么是样式呢&#xff1f; 大小&#xff0c;位置&#xff0c;间距&#xff0c;颜色&a…

银行发展绿色金融,8条建议为您指路

在《财富潮涌&#xff1a;银行发展绿色经济创新路径》内容中&#xff0c;我们带大家了解了商业银行有关绿色财富、绿色服务及绿色运营的内容。今天&#xff0c;我们将阐述商业银行发展绿色金融的必要性以及在实践中商业银行应该如何发展色金融。 发展绿色金融的必要性与难点 1.…

华为杯数学建模比赛经验分享

再过一周左右,第二十届华为杯数学建模比赛就要开赛了&#xff0c;所以今天分享一下个人数学建模比赛的经验。 今天给大家分享一期关于华为杯数学建模比赛的经验分享&#xff0c;我将从以下三个方面展开说明&#xff1a; &#xff08;1&#xff09;如何准备数学建模比赛&#x…

Interceptor的使用场景:拦截请求中的租户信息,注入到租户上下文中

业务场景 在SaaS环境中&#xff0c;租户是最重要的隔离业务数据的属性了&#xff0c;在自己的项目体系环境中&#xff0c;租户id能保证有值。但有个特殊场景&#xff0c;某些特殊权限的账号需要修改指定租户的内容&#xff0c;也即前端会携带租户信息过来&#xff0c;并且内部涉…

共享单车场景下Cat.1网络表现如何?测试结果来了

为帮助行业客户提高Cat.1产品稳定性&#xff0c;近期&#xff0c;天翼物联组织终端客户郑州威科姆科技股份有限公司开展基于中国电信 Cat.1网络下的共享单车体验测试&#xff0c;内容涵盖单车实时位置监控、单车在线率、业务数据延迟、语音播报功能等。测试结果表明&#xff0c…

零基础学前端(四)1. 重点讲解 CSS:盒子模型、样式选择器

1. 该篇适用于从零基础学习前端的小白 2. 初学者不懂代码得含义也要坚持模仿逐行敲代码&#xff0c;以身体感悟带动头脑去理解新知识 3. 初学者切忌&#xff0c;不要眼花缭乱&#xff0c;不要四处找其它文档&#xff0c;要坚定一个教授者的方式&#xff0c;将其学通透&#xff…

uni-app:通过ECharts实现数据可视化-如何引入项目

效果 引入文件位置 代码 <template><view id"myChart"></view> </template> <script> import echarts from /static/js/echarts.js // 引入文件 export default {mounted() {// 初始化EChartsconst myChart echarts.init(document…

中秋特辑:Java事件监听实现一个猜灯谜小游戏

众所周知&#xff0c;JavaSwing是Java中关于窗口开发的一个工具包&#xff0c;可以开发一些窗口程序&#xff0c;然后由于工具包的一些限制&#xff0c;导致Java在窗口开发商并没有太多优势&#xff08;当然也有一些第三方的工具包也很好用&#xff09;&#xff0c;不过&#x…