SpringMVC之JSR303和拦截器

2023-09-12 21:18:38

认识JSR303

JSR303是一项Java标准规范,也叫做Bean Validation规范,提供了一种JavaBean数据验证的规范方式。在SpringMVC中,可以通过引入JSR303相关的依赖,来实现数据的校验。

在使用JSR303进行校验时,需要在需要校验的JavaBean的属性上添加相应的注解,如@NotNull、@Size等。同时,还需要在需要进行校验的方法中使用@Valid注解进行标注,以通知SpringMVC进行校验操作。

JSR303提供了一些基本的校验注解,如@NotNull、@Size、@Pattern等,还可以通过自定义注解来实现更复杂的校验逻辑。除了基本的校验注解之外,JSR303还提供了一些组合注解,如@Valid、@GroupSequence等,可以更灵活地进行校验。

总的来说,JSR303在SpringMVC中的应用非常广泛,可以有效地提高数据的安全性和可靠性。

为什么要用

认识了JSR303那我们为什么要用他呢?

  1. 简单易用:JSR303提供了一些简单明了的注解和API,使得验证输入数据变得非常容易。

  2. 代码可读性:使用JSR303注解能让代码更具可读性,因为验证的逻辑可以直接在Java Bean中看到。

  3. 减少重复代码:使用JSR303注解可以避免编写重复的验证代码,并降低了维护和测试成本。

  4. 标准化:JSR303是Java EE标准之一,使用它可以使得代码更加标准化、可移植。

  5. 安全性:使用JSR303注解可以提高代码的安全性,因为可以对输入数据进行有效的验证,从而避免了安全漏洞的出现。

  6. 可扩展性:JSR303提供了一种简单的机制来扩展验证规则,从而使其满足应用程序的需求。

 注解

给大家解释一下

JSR303的注解主要用于验证Java Bean的属性,以确保属性的有效性和完整性。具体来说,主要有以下作用:

  1. 更方便地验证输入数据:通过使用JSR303的注解,可以很方便地验证输入数据是否符合要求,从而减少了开发人员的工作量。

  2. 提高程序的可维护性:通过在Java Bean的属性上定义验证规则,可以将验证逻辑与业务逻辑分离,从而使程序更易于维护和扩展。

  3. 增加程序的健壮性:通过对Java Bean属性的验证,可以有效地防止非法输入数据对程序的影响,减少程序出错的概率,增加程序的健壮性。

  4. 提高程序的安全性:通过对Java Bean属性的验证,可以确保输入数据的有效性和完整性,从而减少了程序被攻击的风险。

1. @NotNull:验证字段不为null。

2. @NotBlank:验证字段不为空,即长度大于0,去掉空格后长度大于0。

3. @NotEmpty:验证字段不为空,即长度大于0。

4. @Min:验证数字字段的最小值。

5. @Max:验证数字字段的最大值。

6. @Size:验证字段的大小范围。

7. @DecimalMin:验证十进制数字段的最小值。

8. @DecimalMax:验证十进制数字段的最大值。

9. @Pattern:验证字段匹配正则表达式。

10. @Email:验证字段为Email格式。

11. @Length:验证字段的长度。

12. @Range:验证字段的值在范围内。

13. @Valid:验证嵌套对象。

14. @AssertTrue:验证字段为true。

15. @AssertFalse:验证字段为false。

16. @Past:验证日期字段在当前时间之前。

17. @Future:验证日期字段在当前时间之后。

 总之,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>
MusicController 

在我们的MusicController方法中添加以下代码

 //    给数据添加服务端校验
    @RequestMapping("/valiAdd")
    public String valiAdd(@Validated Music music, 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.musicBiz.insertSelective(music);
            return "redirect:list";
        }
        return "mic/edit";
    }
配置校验 

制定规则限制他

 @NotNull(message = "学生编号不能为空")
    private Integer mid;
    @NotBlank(message = "学生名称不能为空")
    private String mname;
    @NotBlank(message = "学生年龄不能为空")
    private String mtype;
    @NotBlank(message = "学生性别不能为空")
    private String minfo;
  

 

认识拦截器 

Spring拦截器(Interceptor)是Spring MVC框架中的一种机制,用于在请求处理前和请求处理后拦截请求。Spring的拦截器类似于JavaEE中的过滤器(Filter),但是比过滤器更加灵活和强大。

Spring拦截器通过在配置文件中配置拦截器实现类,来将拦截器注入到Spring容器中。拦截器可以对请求进行前置处理(preHandle)、后置处理(postHandle)和完成处理(afterCompletion)。在拦截器中,可以实现很多业务逻辑,比如:日志记录、权限验证、参数验证等。

Spring拦截器可以拦截MVC请求、WebSocket请求、Restful请求等。在拦截器中,可以获取请求的相关参数、请求头等信息,可以对请求参数进行验证和修改,还可以在请求前后记录日志等操作。

使用Spring拦截器可以让我们的代码更加简洁,更加易于维护和扩展。同时,它也提高了代码的可用性和可读性,使我们的应用程序更加健壮和高效。

 为什么要用拦截器

拦截器是一种在请求处理前或处理后拦截请求和响应的机制。它可以在请求到达目标之前对请求进行预处理或在目标处理完响应后对响应进行后续处理。拦截器的作用是可以统一处理请求和响应数据,比如请求参数的校验、权限认证、日志记录等,可以减少代码重复、提高代码复用性、增强代码的可维护性和可测试性。此外,拦截器可以对请求和响应数据做出细粒度的控制,可以在某些特定的请求或响应条件下触发特定的处理逻辑,从而满足业务需求。因此,使用拦截器可以让我们更好地控制和管理请求和响应数据,提高应用程序的可靠性和安全性。

拦截器应用的场景
  1. 请求参数的校验:可以对请求中的参数进行非空、数据类型、长度等方面的校验,增强应用程序的健壮性。

  2. 权限认证:可以对用户的登录状态、权限、角色等方面进行认证和授权,保护应用程序的安全性。

  3. 日志记录:可以在请求进入和响应退出时记录相关的系统日志,方便开发人员进行问题排查和性能优化。

  4. 缓存处理:可以对某些请求进行缓存,避免重复查询数据库等操作,提高应用程序的性能。

  5. 数据加密:可以对请求和响应数据进行加密和解密,保护敏感数据的安全性。

  6. 异常处理:可以在请求处理发生异常时进行处理,返回特定的错误信息,避免系统崩溃或返回不友好的错误信息。

总之,拦截器可以应用于几乎所有的 Web 应用程序,可以对请求和响应数据进行各种处理和控制,从而提高应用程序的可靠性、安全性和性能。

过滤器与拦截器的区别

  1. 过滤器属于Servlet规范的一部分,拦截器则是SpringMVC框架的一部分。

  2. 过滤器的作用范围是Servlet,拦截器的作用范围是方法级别和类级别。

  3. 过滤器可以修改HTTP请求和响应,拦截器可以在执行方法之前、之后、异常抛出后等不同的阶段进行处理。

  4. 过滤器使用Servlet容器管理,拦截器则使用Spring容器管理。

  5. 过滤器可以防止恶意访问和跨站脚本攻击等,拦截器可以实现权限验证、日志记录等。

用户登录权限 

Spring-mvc

Spring-mvc.xml中配置多拦截器

 <!--&lt;!&ndash;    用户权限的请求拦截&ndash;&gt;-->
    <mvc:interceptors>
        <bean class="com.zhanghao.interceptor.LoginInterceptor"></bean>
    </mvc:interceptors>
 
    <mvc:interceptors>
        <!--2) 多拦截器(拦截器链)-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.zhanhao.interceptor.OneInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/mic/**"/>
            <bean class="com.zhanghao.interceptor.TwoInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
LoginInterceptor 

创造一个LoginInterceptor拦截器

package com.zhnaghao.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 {
    @Override
    public 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 mname = (String) request.getSession().getAttribute("mname");
        if (mname == null || "".equals(mname)){
            response.sendRedirect("/page/login");
            return false;
        }
        return true;
    }
 
    @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 {
 
    }
}

OneInterceptor
package com.zhanghao.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 {
    @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...");
    }
}
TwoInterceptor
package com.zhanghao.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 {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【TwoInterceptor】:preHandle...");
 
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("【TwoInterceptor】:postHandle...");
 
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("【TwoInterceptor】:afterCompletion...");
    }
}
jsp

接着创造一个新的jsp,用来写我们的登入页面代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户登入</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/login" method="post" enctype="multipart/form-data">
    <label>用户名称:</label><br/>
    <input type="text" name="mname"/><br/>
    <input type="submit" value="登入"/>
</form>
</body>
</html>

今天的分享就到这了 

更多推荐

Golang开发--计时器(Timer)和定时器(Ticker)

计时器(Timer)在Go中,可以使用time包提供的计时器(Timer)来执行定时任务。计时器允许你在指定的时间间隔后执行某个操作。time.Timer结构表示一个计时器,它会在指定的时间段后触发单次操作。创建计时器:使用time.NewTimer(duration)函数创建一个计时器,其中duration是一个ti

9月13-14日上课内容 第三章 ELK日志分析系统及部署实例

本章结构ELK日志分析系统简介ELK日志分析系统分为ElasticsearchLogstashKibana日志处理步骤1.将日志进行集中化管理2.将日志格式化(Logstash)并输出到Elasticsearch3.对格式化后的数据进行索引和存储(Elasticsearch)4.前端数据的展示(Kibana)Elast

python自(2)切片 字典 遍历删除添加修改查询定义函数函数返回值作用域序列化异常报错urllib使用一个类型六个方法下载 视频音频图片

切片##切片#s='helloword'##下标索引为0的#print(s[0])#h##左闭右开(左是下标开始的,右是几个索引值)例如从0开始算4个索引值#print(s[0:4])#hell##更改起始值的开始位置#print(s[1:])#elloword##下标结束位置#print(s[:5])#hello##

二叉搜索树(BST,Binary Search Tree)

文章目录1.二叉搜索树1.1二叉搜索树概念1.2二叉搜索树的查找1.3二叉搜索树的插入1.4二叉搜索树的删除2二叉搜索树的实现3二叉搜索树的应用3.1二叉搜索树的性能分析1.二叉搜索树1.1二叉搜索树概念二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有节点的值都

面试官:用Vue3.0 写过组件吗?如果想实现一个 Modal你会怎么设计?

🎬岸边的风:个人主页🔥个人专栏:《VUE》《javaScript》⛺️生活的理想,就是为了理想的生活!目录一、组件设计二、需求分析三、实现流程目录结构组件内容实现API形式事件处理其他完善一、组件设计组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式现在有一个场景,点击新增与编辑都弹框出

linux文件权限

借东风七星坛上卧龙登,一夜东风江水腾。不是孔明施巧计,周郎安得逞才能?基本权限文件权限设置:可以使某个用户或者某个组能够对文件进行某些操作权限对象:u===>属主g===>属组o===>其他人----------------基本权限类型r--->read读--->4w--->write写--->2x--->exec执行

Vue2+Vue3

文章目录Vue快速上手Vue是什么第一个Vue程序插值表达式Vue核心特性:响应式Vue指令v-htmlv-show与v-ifv-else与v-else-ifv-onv-bindv-forv-model指令修饰符计算属性watch侦听器(监视器)watch——简写watch——完整写法Vue生命周期和生命周期的四个阶段

【Linux学习笔记】权限

1.普通用户和root用户权限之间的切换2.权限的三个w2.1.什么是权限(what)2.1.1.用户角色2.1.2.文件属性2.2.怎么操作权限呢?(how)2.2.1.ugo+-rwx方案2.2.2.八进制方案2.2.3.文件权限的初始模样2.2.4.进入一个目录,需要什么权限呢?2.3.为什么要有权限呢?(why

计算机毕业设计 基于SSM+Vue的校园短期闲置资源置换平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟————————————————计算机毕业设计题目《10

强化学习从基础到进阶--案例与实践[7.1]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解项目实战

【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现专栏详细介绍:【强化学习原理+项目专栏】必看系列:单智能体、多智能体算法原理+项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现对于深度强化学习这块规划为:基础单智能算法教学(g

01-初识HTML

01-初识HTML学习目标:理解HTML的基本语法掌握排版标签实现标题等效果相对路径和绝对路径媒体标签(图片、音频、视频)超链接一、基础认知了解网页组成和五大浏览器明确Web标准的构成1.1认识网页以下网页有哪些部分组成文字、图片、音频、视频、超链接…那么这个网页背后本质是什么?前端的代码是通过什么软件转换成用户眼中的

热文推荐