一.JSR303
JSR 303 是 Java 规范的一部分,全称为 Bean Validation 框架。它定义了一组基于标注的验证注解,用于验证 Java 对象的属性值的合法性。JSR 303 可以用于验证用户输入、数据持久化前的数据校验等场景。
JSR 303 是一种后端验证(服务器端验证)的解决方案。它在后端应用程序中用于验证用户提交的数据或其他对象的合法性。
与后端验证相对应的是前端验证(客户端验证),前端验证是在用户浏览器中进行的验证过程,通过JavaScript等前端技术实现。前端验证主要用于提供无效请求即时反馈和减少的网络流量,但不能完全依赖前端验证来确保数据的安全性和合法性。因此,后端验证仍然是必要的,并且JSR 303 提供了一种便捷的后端验证解决方案。所以我们一般都是前端一套校验,后端在一套校验,这样安全性就能够大大得到提升了。
二.JSR常用的注解
这些注解都是别人已经写好的了,我们直接用就行,但是如果要是我们要用的注解没有怎么办?之后我会和大家讲解如何去制作一个注解,自定义注解
注解 | 说明 |
@Null | 用于验证对象为null |
@NotNull | 用于对象不能为null,无法查检长度为0的字符串 |
@NotBlank | 只用于String类型上,不能为null且trim()之后的size>0 |
@NotEmpty | 用于集合类、String类不能为null,且size>0。但是带有空格的字符串校验不出来 |
@Size | 用于对象(Array,Collection,Map,String)长度是否在给定的范围之内 |
@Length | 用于String对象的大小必须在指定的范围内 |
@Pattern | 用于String对象是否符合正则表达式的规则 |
用于String对象是否符合邮箱格式 | |
@Min | 用于Number和String对象是否大等于指定的值 |
@Max | 用于Number和String对象是否小等于指定的值 |
@AssertTrue | 用于Boolean对象是否为true |
@AssertFalse | 用于Boolean对象是否为false |
三.JSR快速入门
首先,我们要先导入JSR的pom依赖
<!-- 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>
在实体类的属性上面写上如果为空就提示的信息语句
接下来需要校验上方的注解
// 给数据添加服务端校验 @RequestMapping("/valiAdd") public String valiAdd(@Validated Struts struts, 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.strutsBiz.insertSelective(struts); return "redirect:list"; } return "edit"; }
接下来需要设置提示词
这样一个JSR的注解判断就完成了,接下来我们看看结果吧!
四.拦截器
拦截器(Interceptor)是一种在软件系统中用于拦截、处理和转发请求和响应的组件或模块。它可以在请求到达目标处理程序之前或响应返回给客户端之前对其进行处理。
以下是拦截器的主要作用:
- 身份验证和权限控制:拦截器可以用来验证请求的身份和权限,例如跳转到登录页面或拒绝访问。
- 日志记录和跟踪:拦截器可以记录请求和响应的详细日志,包括请求的参数、执行时间、错误信息等。这有助于开发人员在系统中追踪问题和进行故障排除。
- 缓存和性能优化:拦截器可以实现结果缓存,将频繁请求的结果缓存在内存或其他存储中,减少对后端资源的访问。这有助于提高系统的性能和响应速度。
- 异常处理:拦截器可以捕获系统中的异常,例如返回自定义错误页面或发送错误报告。
- 请求和响应的处理和修改:拦截器可以对请求和响应进行修改和处理,例如添加、删除或修改请求参数、设置响应头、处理响应结果等。
⭐⭐⭐有人可能会问,拦截器和过滤器有什么不一样,或者它们的区别是什么??
- 过滤器(filter)
1.filter属于Servlet技术,只要是web工程都可以使用
2.filter主要由于对所有请求过滤
3.filter的执行时机早于Interceptor- 拦截器(interceptor)
1.interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用
2.interceptor通常由于对处理器Controller进行拦截
3.interceptor只能拦截dispatcherServlet处理的请求
五.拦截器快速入门--登录的案例
所谓拦截器,首先当然是要写一个拦截器方法
package com.yinzi.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author yinzi * @create 2023-09-12 13:02 */ 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 uname = (String) request.getSession().getAttribute("uname"); if (uname == null || "".equals(uname)){ 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 { } }
接着,在spring-mvc中进行配置‘
<!--配置拦截器--> <mvc:interceptors> <bean class="com.yinzi.interceptor.LoginInterceptor"></bean> </mvc:interceptors>
写一个登录的方法
package com.yinzi.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * @author yinzi * @create 2023-09-12 13:03 */ @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:/list"; } @RequestMapping("/logout") public String logout(HttpServletRequest req){ req.getSession().invalidate(); return "redirect:/list"; } }
最后,就是前端代码
<%@ 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>
结果:
它会经过拦截器进行判断