目录
[1.1 什么是JSR303](#1.1 什么是JSR303)
[1.2 为什么要使用JSR303](#1.2 为什么要使用JSR303)
[1.3 常用注解](#1.3 常用注解)
[1.4 快速入门](#1.4 快速入门)
[1.4.1 导入依赖](#1.4.1 导入依赖)
[1.4.2 配置校验规则](#1.4.2 配置校验规则)
[1.4.3 入门案例](#1.4.3 入门案例)
[2.1 什么是拦截器](#2.1 什么是拦截器)
[2.1.1 定义](#2.1.1 定义)
[2.1.2 作用领域](#2.1.2 作用领域)
[2.2 过滤器](#2.2 过滤器)
[2.2.1 定义](#2.2.1 定义)
[2.2.2 作用领域](#2.2.2 作用领域)
[2.3 拦截器与过滤器的区别](#2.3 拦截器与过滤器的区别)
[2.4 应用场景](#2.4 应用场景)
[2.5 快速入门](#2.5 快速入门)
[2.5.1 入门案例](#2.5.1 入门案例)
[2.5.2 拦截器工作原理](#2.5.2 拦截器工作原理)
[2.6 拦截器链](#2.6 拦截器链)
[2.7 用户登录权限控制](#2.7 用户登录权限控制)
一、JSR303
1.1 什么是JSR303
JSR303是Java规范请求(Java Specification Request)的编号,它定义了Java Bean验证的标准。Java Bean验证是一种验证框架,可以验证Java Bean中的属性,以确保它们符合特定的规则和约束。该框架在Java EE 6中得到了官方支持,并在javax.validation包中实现。JSR303规范定义了验证注释,这些注释可以应用于Java Bean的属性上,以指示验证规则。这些验证规则可以检查属性是否为空、是否符合正则表达式、是否在指定范围内等等。通过使用JSR303,我们可以确保Java Bean的属性始终符合预期,并在出现错误时及时捕获并处理这些错误。
JSR303的定义:
JSR303是一种Java平台标准,也称为Bean Validation,用于验证JavaBean和其他Java对象的声明约束。JSR303使用注释标记属性的限制,并提供了一个验证引擎,该引擎可以在运行时执行验证以确保对象的有效性。它提供了一种轻松的方式来验证表单数据和其他用户输入,防止不良数据进入应用程序。JSR303旨在提供一致的验证机制,使Java应用程序更加健壮和可维护。
1.2 为什么要使用JSR303
JSR303是Java Validation API的规范,它提供了一种简单易用的验证框架,帮助我们在实体类属性上进行验证,对于确保数据的正确性和完整性非常有用。 使用JSR303可以带来以下好处:
易于维护和扩展:将验证规则注解到属性上,代码易于维护和扩展,避免了繁琐的手工验证。
提高代码可读性:验证规则注解到属性上,代码可读性大大提高。
减少重复代码:使用JSR303可以减少编写检验代码的重复工作,提高生产效率。
提高系统健壮性:通过JSR303验证规则的定义,可以确保数据的正确性和完整性,提高系统健壮性和稳定性。
1.3 常用注解
JSR303是Java中的Bean Validation规范,其中定义了许多注解用于对JavaBean中的属性进行验证。以下是常用的JSR303注解及其解释:
@NotNull:验证字段不为null。
@NotBlank:验证字段不为空,即长度大于0,去掉空格后长度大于0。
@NotEmpty:验证字段不为空,即长度大于0。
@Min:验证数字字段的最小值。
@Max:验证数字字段的最大值。
@Size:验证字段的大小范围。
@DecimalMin:验证十进制数字段的最小值。
@DecimalMax:验证十进制数字段的最大值。
@Pattern:验证字段匹配正则表达式。
@Email:验证字段为Email格式。
@Length:验证字段的长度。
@Range:验证字段的值在范围内。
@Valid:验证嵌套对象。
@AssertTrue:验证字段为true。
@AssertFalse:验证字段为false。
@Past:验证日期字段在当前时间之前。
@Future:验证日期字段在当前时间之后。
以上是常用的JSR303注解及其解释,开发者可以根据实际情况选择需要的注解。
注**@Validated与@Valid区别** ::
@Validated:
Spring提供的
支持分组校验
可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上
由于无法加在成员属性(字段)上,所以无法单独完成级联校验,需要配合@Valid
@Valid:
JDK提供的(标准JSR-303规范)
不支持分组校验
可以用在方法、构造函数、方法参数和成员属性(字段)上
可以加在成员属性(字段)上,能够独自完成级联校验
1.4 快速入门
1.4.1 导入依赖
XML
<!-- 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 配置校验规则
校验属性是否为空:
java
@NotNull(message = "歌曲编号不能为空")
private Integer mid;
@NotBlank(message = "歌曲名称不能为空")
private String mname;
@NotBlank(message = "歌曲专辑不能为空")
private String mtype;
@NotBlank(message = "歌曲歌词不能为空")
private String minfo;
@NotBlank(message = "歌曲图片不能为空")
private String mpic = "暂无图片";
1.4.3 入门案例
在MusicController类中添加以下方法:
java
// 给数据添加服务端校验
@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";
}
在服务端中进行校验,校验的模型的属性中出现错误,则将错误信息的属性进行遍历添加到map集合中并保存起来回显到前端,需要注意的是,注解@validated保存的是校验时的参数,最终校验的结果保存在BindingResult中.
1.4.4 结果测试
在没有进行后端效验前应该会报空指针异常。
但是在进行后端效验之后,就会将我们的错误信息反馈到前端的展示界面,如下:
控制台效果:
二、Java三大器之拦截器
2.1 什么是拦截器
2.1.1 定义
在Java编程中,拦截器(Interceptor)是一种常见的机制,它可以拦截方法的调用或者HTTP请求的处理过程,并在处理前后执行一些特定的操作或者逻辑。拦截器通常用于实现各种不同的功能,如权限控制、日志记录、事务管理等。
2.1.2 作用领域
在Java Web开发中,拦截器常用于拦截HTTP请求并进行处理,例如进行身份验证、拦截非法的请求、记录日志等。在Spring框架中,拦截器是一个非常重要的组件,可以通过实现HandlerInterceptor接口来定义拦截器,然后在配置文件中配置拦截器的拦截规则和执行顺序。在Struts2、Spring MVC等Web框架中也都有拦截器的支持。
2.2 Java三大器之过滤器
2.2.1 定义
Java中的过滤器(Filter)是一种用于拦截HTTP请求和响应的组件,它在请求到达Servlet之前拦截并验证HTTP请求,或在Servlet响应到达客户端前对响应进行处理。在Java Web应用中,过滤器是一个可配置的组件,它需要在web.xml文件中注册并配置相应的属性才能生效。可以通过编写实现javax.servlet.Filter接口的Java类来定义过滤器的功能。
2.2.2 作用领域
过滤器通常用于实现一些通用的处理逻辑,比如认证、日志记录、统计信息等,以提高代码复用性和可维护性。过滤器还可以用于跨站点脚本攻击(XSS)和跨站点请求伪造(CSRF)等安全机制的实现。
2.3 拦截器与过滤器的区别
图解如下:
拦截器和过滤器都是在Java Web开发中对请求进行拦截处理的一种工具,但是它们有以下区别:
执行顺序: 过滤器是在Servlet容器调用servlet之前或之后执行的,而拦截器是在servlet处理请求之前或之后执行的。
作用范围: 过滤器作用于所有的请求和响应,包括静态资源,而拦截器只拦截配置的路径及其子路径的请求。
功能范围: 过滤器可以在过滤器链中做一些额外的功能,如字符编码、请求转发和重定向等,而拦截器可以更好地控制业务流程,如权限控制、日志记录等。
API不同: 过滤器是使用Servlet API实现的,而拦截器是使用Spring MVC框架自身的接口实现的。
总的来说,过滤器更加通用,可以实现一些基本的请求过滤和处理操作,而拦截器则更加灵活,可以根据业务需求实现更加复杂的操作。在实际应用中,需要根据具体的需求选择使用过滤器还是拦截器。
2.4 应用场景
日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;
性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。
2.5 拦截器工作原理
2.6 用户登录权限控制
基本拦截器配置(在Java目录下新建一个interceptor包,创建拦截器类):
OneInterceptor:
java
package com.Kissship.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:
java
package com.Kissship.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...");
}
}
然后在Spring-mvc.xml中配置多拦截器,添加代码如下:
XML
<!--<!– 用户权限的请求拦截–>-->
<mvc:interceptors>
<bean class="com.Kissship.interceptor.LoginInterceptor"></bean>
</mvc:interceptors>
<mvc:interceptors>
<!--2) 多拦截器(拦截器链)-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.Kissship.interceptor.OneInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/mic/**"/>
<bean class="com.Kissship.interceptor.TwoInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
然后接下来创建一个名为LoginInterceptor的拦截器,如下:
java
package com.Kissship.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 {
}
}
接着创建一个新的jsp页面用来充当登录界面进行效果测试,login.jsp代码如下:
html
<%@ 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>
最后进行测试,效果如下:
最后SpringMVC之JSR303和拦截器就到这里,祝大家在敲代码的路上一路通畅!
感谢大家的观看 !