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>

测试

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

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

相关文章

PostgreSQL 事务并发锁

文章目录 PostgreSQL 事务大家都知道的 ACID事务的基本使用保存点 PostgreSQL 并发并发问题MVCC PostgreSQL 锁机制表锁行锁 总结 PostgreSQL 事务 大家都知道的 ACID 在日常操作中&#xff0c;对于一组相关操作&#xff0c;通常要求要么都成功&#xff0c;要么都失败。在关系…

html实现邮件模版布局-flex布局table布局-demo

邮件模版布局 flex - 布局简单方便 兼容性差 table - 优点 就是兼容性好&#xff0c;其他没有优点 注&#xff1a;使用图片需要png最好&#xff0c;使用svg图google邮箱会出现不能使用的情况 效果图 flex布局 <!DOCTYPE html> <html lang"en" xmlns:th&qu…

Mojo 语言官网

Mojo面向 AI 开发者的新型编程语言&#xff0c;无缝支持CPU、GPU&#xff0c;兼容Python&#xff0c;跟Python类似的语法&#xff0c;但是比Python快68000倍。目前Mojo仅支持Ubuntu&#xff0c;暂不支持Windows和Mac&#xff0c;可以在Mojo Playground先体验一下。 Mojo 语言…

JVM类加载和双亲委派机制

当我们用java命令运行某个类的main函数启动程序时&#xff0c;首先需要通过类加载器把类加载到JVM&#xff0c;本文主要说明类加载机制和其具体实现双亲委派模式。 一、类加载机制 类加载过程&#xff1a; 类加载的过程是将类的字节码加载到内存中的过程&#xff0c;主要包括…

Outlook无需API开发连接钉钉群机器人,实现新增会议日程自动发送群消息通知

Outlook用户使用场景&#xff1a; 在企业中&#xff0c;会议和活动的顺利举行对于业务运转和团队协作至关重要。然而&#xff0c;计划的变动总是无法避免&#xff0c;这可能会导致其他人的计划受到影响&#xff0c;打乱原有的安排。为了解决这个问题&#xff0c;许多企业开始使…

前端面试要点

0914 JScript深拷贝和浅拷贝&#xff08;js解构赋值算哪个&#xff1f;&#xff09; 深拷贝和浅拷贝 回流和重绘 回流和重绘 webpack打包流程 Webpack打包 虚拟DOM 虚拟DOM git合并分支 git合并分支 CSS盒子模型 CSS盒子模型 0911 WebPack分包 webpack分包 ts泛型 ts泛型 优化…

基于Python计算PLS中的VIP值(变量投影重要性分析法)

sklearn中PLS回归模型并没有计算VIP值的方法,但VIP又是很重要的筛选变量方法。下附代码思路与完整代码。 计算公式: 其中: VIPj:对应于第j个特征的VIP值;p:预测变量的总数;A:PLS成分的总数;R矩阵:A个PLS成分中,每个成分a都对应一套系数wa将X转换为成分得分,系数矩…

spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表

一、添加aop starter依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>二&#xff1a;自定义字段翻译注解。&#xff08;修改功能时&#xff0c;需要显示如…

亚马逊关于在澳大利亚销售儿童玩具和游戏的政策合规标准是什么?

亚马逊关于在澳大利亚销售儿童玩具和游戏的政策 在亚马逊澳大利亚商城中&#xff0c;设计用于或明确表示专供 14 岁及以下儿童玩耍用的所有商品或材料均视为儿童玩具。 商品根据以下标准确定为“儿童商品”&#xff1a; 预期用途&#xff1a; ASIN 是否可供儿童使用&#xff…

JAVA面向对象(OOP)总结----宏观的程序设计

类&#xff1a;使用关键字class&#xff0c;抽象的概念集合。例如人类&#xff0c;具有共性的产物。 对象&#xff1a;具有自己独立属性&#xff0c;具有个性的个体。 类中可以定义的内容&#xff1a; 成员变量&#xff08;属性&#xff09;&#xff1b;成员方法&#xff08;…

torch.where()两种用法

参考官方文档。 官方文档中只给了第一种用法。根据条件condition&#xff0c;从input,other中选择元素f返回。如果满足条件&#xff0c;则返回input元素。若不满足&#xff0c;返回other元素。 还有一种用法是通过where返回张量中满足条件condition的坐标&#xff0c;以二维张…

【自动化测试】如何在jenkins中搭建allure

相信大家在做自动化测试过程中&#xff0c;都会用到自动化测试环境&#xff0c;目前最常见的就是通过容器化方式部署自动化测试环境&#xff0c;但对于一些测试小白&#xff0c;不是很会搭建持续集成环境&#xff0c;特别是从0-1的过程&#xff0c;需要自行搭建很多依赖环境&am…

springboot项目制作docker镜像,如何动态传递变量值?

springboot项目制作成docker镜像后&#xff0c;如何给properties文件的变量动态传递值呢&#xff1f; 步骤1&#xff1a;将properties文件设置为如下形式 serverUrl${SERVER_URL} apiKey${API_KEY}步骤2&#xff1a;制作成docker镜像后&#xff0c;启动镜像时&#xff0c;通过…

【PCL-11】提取平面上层的目标物,剔除平面下层目标物

因项目需求&#xff0c;需提取平面上的物体&#xff0c;不提取平面下的物体&#xff0c;尝试采用超体聚类LCCP分割的方式&#xff0c;但由于上层点云模型一侧有空洞&#xff0c;导致分割效果不理想。 这里采用pcl::ExtractPolygonalPrismData类&#xff0c;实现平面上物体的提取…

代码混淆和加固,保障应用程序的安全性

摘要&#xff1a;本文将详细介绍iOS技术博主在保护应用程序代码安全方面的两种重要方式&#xff1a;代码混淆和代码加固。通过代码混淆和加固&#xff0c;博主可以有效防止他人对应用程序进行逆向工程和篡改&#xff0c;提高应用程序的安全性。 引言&#xff1a;作为iOS技术博…

实时云渲染应用之虚拟仿真项目的四大优势

虚拟仿真在教育领域的应用越来越广&#xff0c;尤其在科研和实验教学领域&#xff0c;这主要是因为虚拟仿真具有操作简单、场景逼真、更安全、易维护的优势。比如在实验教学过程中&#xff0c;一些实验对象相对于学生来说过于宏观或微观&#xff0c;学生不易理解&#xff0c;而…

北邮22级信通院数电:Verilog-FPGA(1)实验一“跑通第一个例程” 过程中遇到的常见问题与解决方案汇总(持续更新中)

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 问题一&#xff1a;Verilog代码没有跑通 报…

数据类型

目录 1.数值类型 整数类型 int 小数类型 double 2.字符类型 固定长度字符串 char 可变长度字符串 varchar 3.日期时间类型 日期类型&#xff1a;date 日期时间类型&#xff1a;datetime MySQL从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article…

DLL调试方法 VS2012 C++ 有代码时

把exe放到输出目录 并把调试 命令 设为 ( S o l u t i o n D i r ) (SolutionDir) (SolutionDir)(Platform)$(Configuration)\SmartPayDemo.exe 尽量用debug模式 反过来也行&#xff0c;把dll放在exe工程下也行。 解决方案exe工程中添加dll工程 dll本身是没法运行的&#…

Unreal Engine Loop 流程

引擎LOOP 虚幻引擎的启动是怎么一个过程。 之前在分析热更新和加载流程过程中&#xff0c;做了一个图。记录一下&#xff01;&#xff01; ![在这里插入图片描述](https://img-blog.csdnimg.cn/f11f7762f5dd42f9b4dd9b7455fa7a74.png#pic_center 只是记录&#xff0c;以备后用…