SpringBoot入门建站全系列(三十三)集成validator校验接口数据

本文主要是介绍SpringBoot入门建站全系列(三十三)集成validator校验接口数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SpringBoot入门建站全系列(三十三)集成validator校验接口数据

一、概述

在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,如果我们直接将这些校验写死在代码里,将会遇到这种现象:

  1. 验证代码繁琐,重复劳动
  2. 方法内代码显得冗长
  3. 代码可读性不高

所以,我们可以使用hibernate validator来对字段的校验工作统一完成。

spring-boot-starter-web中默认引入了hibernate-validator,因此,在SpringBoot项目中,我们可以直接使用hibernate-validator的特性。

这一篇篇文章本应该放在SpringBoot入门建站全系列的前面章节讲述,这里权做对该系列的补充了。

首发地址:

  品茗IT: https://www.pomit.cn/p/2437125163256321

如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。

二、基础知识

首先,基础知识是必须要了解的,我这里整理了下最新的注解,比网上一下子搜到的博客更全面。

validator的功能是由hibernate-validator提供的,所以在Spring官方文档里是找不到关于它的说明的,需要到hibernate-validator官网查看:
https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-builtin-constraints

注解释义场景
@AssertFalse验证注解的元素值是falseBoolean, boolean
@AssertTrue验证注解的元素值是trueBoolean, boolean
@DecimalMax(value=x)验证注解的元素值小于等于@ DecimalMax指定的value值BigDecimal,BigInteger,CharSequence,byte,short,int,long和原始类型的相应的包装类;
@DecimalMin(value=x)验证注解的元素值小于等于@ DecimalMin指定的value值BigDecimal,BigInteger,CharSequence,byte,short,int,long和原始类型的相应的包装类;
@Digits(integer=整数位数, fraction=小数位数)验证注解的元素值的整数位数和小数位数上限BigDecimal的,BigInteger,CharSequence,byte,short,int,long和原始类型的相应的包装类;
@Future检查带注释的日期是否是将来java.util.Date,java.util.Calendar,java.time.Instant,java.time.LocalDate,java.time.LocalDateTime,java.time.LocalTime,java.time.MonthDay,java.time.OffsetDateTime,java.time.OffsetTime,java.time.Year,java.time.YearMonth,java.time.ZonedDateTime,java.time.chrono.HijrahDate,java.time.chrono.JapaneseDate,java.time.chrono.MinguoDate,java.time.chrono.ThaiBuddhistDate;
@FutureOrPresent检查带注释的日期是现在还是将来java.util.Date,java.util.Calendar,java.time.Instant,java.time.LocalDate,java.time.LocalDateTime,java.time.LocalTime,java.time.MonthDay,java.time.OffsetDateTime,java.time.OffsetTime,java.time.Year,java.time.YearMonth,java.time.ZonedDateTime,java.time.chrono.HijrahDate,java.time.chrono.JapaneseDate,java.time.chrono.MinguoDate,java.time.chrono.ThaiBuddhistDate;
@Max(value=x)验证注解的元素值小于等于@Max指定的value值BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类;
@Min(value=x)验证注解的元素值大于等于@Min指定的value值BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类;
@NotNull验证注解的元素值不是null任意
@Null验证注解的元素值是null任意
@Past检查带注释的日期是否是过去java.util.Date,java.util.Calendar,java.time.Instant,java.time.LocalDate,java.time.LocalDateTime,java.time.LocalTime,java.time.MonthDay,java.time.OffsetDateTime,java.time.OffsetTime,java.time.Year,java.time.YearMonth,java.time.ZonedDateTime,java.time.chrono.HijrahDate,java.time.chrono.JapaneseDate,java.time.chrono.MinguoDate,java.time.chrono.ThaiBuddhistDate;
@PastOrPresent检查带注释的日期是过去还是现在java.util.Date,java.util.Calendar,java.time.Instant,java.time.LocalDate,java.time.LocalDateTime,java.time.LocalTime,java.time.MonthDay,java.time.OffsetDateTime,java.time.OffsetTime,java.time.Year,java.time.YearMonth,java.time.ZonedDateTime,java.time.chrono.HijrahDate,java.time.chrono.JapaneseDate,java.time.chrono.MinguoDate,java.time.chrono.ThaiBuddhistDate;
@Pattern(regex=正则表达式, flag=)验证注解的元素值与指定的正则表达式匹配CharSequence
@Size(min=最小值, max=最大值)验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小CharSequence,Collection,Map和数组
@Valid验证关联的对象,如账户对象里有一个订单对象,指定验证订单对象Any non-primitive type(引用类型)
@NotEmpty验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)CharSequence,Collection,Map和数组
@Range(min=最小值, max=最大值)验证注解的元素值在最小值和最大值之间CharSequence, Collection, Map and Arrays,BigDecimal, BigInteger, CharSequence, byte, short, int, long and the respective wrappers of the primitive types
@NotBlank验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格CharSequence
@Length(min=下限, max=上限)验证注解的元素值长度在min和max区间内CharSequence
@Email验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式CharSequence
@Negative检查元素是否严格为负。零值被视为无效。BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类
@NegativeOrZero检查元素是负数还是零。BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类
@Positive检查元素是否严格为正。零值被视为无效。BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类
@NegativeOrZero检查元素是正数还是零。BigDecimal,BigInteger,byte,short,int,long和原始类型的相应的包装类
@URL(protocol=, host=, port=, regexp=, flags=)检查字符序列是否为有效URL。CharSequence
@CreditCardNumber检查带注释的字符序列是否通过了Luhn校验和测试。CharSequence
@Currency检查带注释的货币单位javax.money.MonetaryAmount是否为指定货币单位的一部分。CharSequence
@DurationMax检查带注释的java.time.Duration元素不大于由注释参数构造的元素。java.time.Duration
@DurationMin检查带注释的java.time.Duration元素不少于由注释参数构造的元素。java.time.Duration
@EAN检查带注释的字符序列是有效的EAN条形码。CharSequence
@ISBN检查带注释的字符序列是有效的ISBN。CharSequence
@CodePointLength验证带注释的字符序列的代码点长度在之间min并max包括在内。CharSequence
@LuhnCheck检查带注释的字符序列中的数字是否通过Luhn校验和算法CharSequence
@Mod10Check检查带注释的字符序列中的数字是否通过通用mod 10校验和算法。CharSequence
@Mod11Check检查带注释的字符序列中的数字是否通过了mod 11校验和算法。CharSequence
@SafeHtml检查带注释的值是否包含潜在的恶意片段,例如

三、实体校验

假设当前有个实体叫userInfo

3.1 实体
package com.cff.springbootwork.validator.vo;import java.util.Date;
import java.util.List;import javax.validation.constraints.AssertFalse;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Email;
import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Negative;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Positive;
import javax.validation.constraints.Size;import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import org.hibernate.validator.constraints.URL;import com.fasterxml.jackson.annotation.JsonFormat;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserInfo {@Null(message = "创建时间不能填")@JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")private Date createTime;@NotEmpty(message = "用户名不能为空")private String userName;@NotBlank(message = "姓名不能为空或空字符串")private String name;@Negative(message = "冬天温度在0°以下")private Integer temperatureWinter;@Positive(message = "夏天温度在0°以上")private Integer temperatureSummer;@Digits(integer = 11, message = "手机号是11位整数哦", fraction = 0)private String mobile;@NotNull(message = "年龄不能为空")@Min(value = 10, message = "年龄太小了")@Max(value = 35, message = "年龄太大了")private Integer age;@Size(min = 0, max = 2, message = "你女朋友个数在0-2之间")private List<String> girlFrinds;@Range(min = 0, max = 100, message = "你钱包里的钱在0-2之间")private Integer money;@Length(min = 4, max = 64, message = "地址在4-64之间")private String address;@AssertTrue(message = "对象必须是人")private Boolean people;@AssertFalse(message = "不能上来就删除")private Boolean delete;@Pattern(regexp="[0-9]{6}",message = "密码格式错误")private String password;@Email(message = "email格式错误")private String email;@JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")@Future(message = "失效时间比当前时间晚")private Date expireTime;@JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")@Past(message = "出生日期比当前时间早")private Date birthDate;@URL(message = "url填写错误")private String url;
}
3.2 Web层数据接收

只需要加上@Valid注解即可,然后通过BindingResult来接收校验错误。

	@RequestMapping(value = "/test")public List<String> set(@Valid @RequestBody UserInfo userInfo, BindingResult bindingResult) {if (bindingResult.hasErrors()) {List<String> errorMsg = bindingResult.getAllErrors().stream().map(s -> s.getDefaultMessage()).collect(Collectors.toList());return errorMsg;}return Collections.singletonList("0000");}

这里,是打印了所有错误结果,如果只校验是否错误,抛出第一个错误,这样写即可:

@RequestMapping(value = "/test")public List<String> set(@Valid @RequestBody UserInfo userInfo, BindingResult bindingResult) {if (bindingResult.hasErrors()) {String errorMsg = bindingResult.getAllErrors().get(0).getDefaultMessage();return Collections.singletonList(errorMsg);}return Collections.singletonList("0000");}
3.3 校验不通过测试
请求参数:
{"createTime":"2018-08-09","userName": "","name": "  ","age": 9,"mobile": "123123123","girlFrinds": ["1号","2号","3号"],"money": 101,"temperatureWinter": 0,"temperatureSummer": -1,"address": "12","people": false,"delete": true,"password": "123","email": "11@","expireTime":"2019-11-11","birthDate":"2020-11-11","url":"qwe"
}返回结果:
["你女朋友个数在0-2之间","地址在4-64之间","密码格式错误","email格式错误","创建时间不能填","你钱包里的钱在0-2之间","对象必须是人","出生日期比当前时间早","冬天温度在0°以下","年龄太小了","失效时间比当前时间晚","url填写错误","夏天温度在0°以上","不能上来就删除","姓名不能为空或空字符串","用户名不能为空"
]
3.4 校验通过测试
请求参数:
{"createTime":"","userName": " ","name": "cff","age": 11,"mobile": "13333333333","girlFrinds": ["1号","2号"],"money": 100,"temperatureWinter": -1,"temperatureSummer": 12,"address": "12345","people": true,"delete": false,"password": "123456","email": "11@qq.com","expireTime":"2020-11-11","birthDate":"2019-11-11","url":"http://www.pomit.cn"
}返回结果:
["0000"
]

四、级联校验

如果一个对象持有另一个对象的引用,可以使用@Valid注解进行级联校验。 如下所示:

4.1 实体
package com.cff.springbootwork.validator.vo;import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserRole {@NotEmpty(message = "用户名不能为空")private String userName;@NotNull(message = "roleId不能为空")private Integer roleId;@Validprivate UserInfo userInfo;
}
4.2 测试Web
@RequestMapping(value = "/test1")public List<String> test1(@Valid @RequestBody UserRole userRole, BindingResult bindingResult) {if (bindingResult.hasErrors()) {List<String> errorMsg = bindingResult.getAllErrors().stream().map(s -> s.getDefaultMessage()).collect(Collectors.toList());return errorMsg;}return Collections.singletonList("0000");}
4.3 测试结果
请求数据:
{"userName": "","roleId": 1,"userInfo":{"createTime":"2018-08-09","userName": "","name": "  ","age": 9,"mobile": "123123123","girlFrinds": ["1号","2号","3号"],"money": 101,"temperatureWinter": 0,"temperatureSummer": -1,"address": "12","people": false,"delete": true,"password": "123","email": "11@","expireTime":"2019-11-11","birthDate":"2020-11-11","url":"qwe"}
}返回结果:
["失效时间比当前时间晚","用户名不能为空","用户名不能为空","你女朋友个数在0-2之间","密码格式错误","你钱包里的钱在0-2之间","姓名不能为空或空字符串","url填写错误","冬天温度在0°以下","对象必须是人","email格式错误","不能上来就删除","年龄太小了","夏天温度在0°以上","地址在4-64之间","创建时间不能填","出生日期比当前时间早"
]

五、手动校验

有时候,不用使用@Valid 自动校验,需要手动调起validator进行校验,可以使用validator.validate(roleInfo);进行校验:

5.1 实体
package com.cff.springbootwork.validator.vo;import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class RoleInfo {@NotNull(message = "roleId不能为空")private Integer roleId;@NotEmpty(message = "roleName不能为空")private String roleName;
}
5.2 测试

Validator(import javax.validation.Validator;) 在SpringBoot中,可以作为bean之间被注入。

@Autowired
Validator validator;@RequestMapping(value = "/test2")
public List<String> test2(@RequestParam("roleId") Integer roleId, @RequestParam("roleName") String roleName) {RoleInfo roleInfo = new RoleInfo(roleId, roleName);Set<ConstraintViolation<RoleInfo>> sets = validator.validate(roleInfo);if(sets.isEmpty())return Collections.singletonList("0000");List<String> errorMsg = sets.stream().map(s -> s.getMessage()).collect(Collectors.toList());return errorMsg;
}

六、分组校验

分组校验就是处理特殊情况下的校验,使不同的调用走不同的校验组。

如,一个对象A持有另一个对象B的引用,对象B中某些字段不想在对象A校验的时候被校验到,可以使用分组校验。

6.1 实体

假设有两个实体:

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserRoleInfo {@NotEmpty(message = "用户名不能为空")private String userName;@NotNull(message = "roleId不能为空")private Integer roleId;@Validprivate RoleInfo roleInfo;
}
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class RoleInfo {@NotNull(message = "roleId不能为空", groups=RoleGroup.class)private Integer roleId;@NotEmpty(message = "roleName不能为空", groups=RoleGroup.class)private String roleName;
}

注意,这里的groups必须是接口。接口内容任意,只是个标识而已。

public interface RoleGroup {}

Default.class(javax.validation.groups.Default)是默认分组,不需要自己建立.

6.2 测试不带分组
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.groups.Default;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import com.cff.springbootwork.validator.vo.RoleGroup;
import com.cff.springbootwork.validator.vo.RoleInfo;
import com.cff.springbootwork.validator.vo.UserRoleInfo;@RestController
@RequestMapping("/valid")
public class ValidatorRest {@AutowiredValidator validator;@RequestMapping(value = "/test3")public List<String> test3(@RequestParam("roleId") Integer roleId, @RequestParam("userName") String userName,@RequestParam("roleName") String roleName) {UserRoleInfo userRoleInfo = new UserRoleInfo();userRoleInfo.setRoleId(roleId);userRoleInfo.setUserName(userName);RoleInfo roleInfo = new RoleInfo(roleId, roleName);userRoleInfo.setRoleInfo(roleInfo);Set<ConstraintViolation<UserRoleInfo>> sets = validator.validate(userRoleInfo);if (sets.isEmpty())return Collections.singletonList("0000");List<String> errorMsg = sets.stream().map(s -> s.getMessage()).collect(Collectors.toList());return errorMsg;}
}

结果:

请求参数:
roleId:1
userName:
roleName:返回结果:
["用户名不能为空"
]
6.2 测试带分组

注意,Default.class是默认分组。

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.groups.Default;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import com.cff.springbootwork.validator.vo.RoleGroup;
import com.cff.springbootwork.validator.vo.RoleInfo;
import com.cff.springbootwork.validator.vo.UserRoleInfo;@RestController
@RequestMapping("/valid")
public class ValidatorRest {@AutowiredValidator validator;@RequestMapping(value = "/test3")public List<String> test3(@RequestParam("roleId") Integer roleId, @RequestParam("userName") String userName,@RequestParam("roleName") String roleName) {UserRoleInfo userRoleInfo = new UserRoleInfo();userRoleInfo.setRoleId(roleId);userRoleInfo.setUserName(userName);RoleInfo roleInfo = new RoleInfo(roleId, roleName);userRoleInfo.setRoleInfo(roleInfo);Set<ConstraintViolation<UserRoleInfo>> sets = validator.validate(userRoleInfo, RoleGroup.class, Default.class);if (sets.isEmpty())return Collections.singletonList("0000");List<String> errorMsg = sets.stream().map(s -> s.getMessage()).collect(Collectors.toList());return errorMsg;}
}

结果:

请求参数:
roleId:1
userName:
roleName:返回结果:
["roleName不能为空","用户名不能为空"
]

七、自定义注解校验

有时候,我们仍需要自定义校验注解,如,我这里定义一个只校验0或1数据的验证器。

7.1 自定义注解
package com.cff.springbootwork.validator.custom;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;import javax.validation.Constraint;
import javax.validation.Payload;/*** 自定义类校验注解* 作用于类,用以校验0/1类型数据* @author cff**/
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=TypeZeroOneValidator.class)
public @interface ZeroOne {String message() default "参数有误";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}
7.2 自定义Validator
package com.cff.springbootwork.validator.custom;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;public class TypeZeroOneValidator implements ConstraintValidator<ZeroOne, Object> {@Overridepublic void initialize(ZeroOne constraintAnnotation) {}@Overridepublic boolean isValid(Object obj, ConstraintValidatorContext context) {if (obj == null)return true;int curNum = 0;if (obj instanceof String) {String s = (String) obj;curNum = Integer.parseInt(s);} else if (obj instanceof Boolean) {boolean b = ((Boolean) obj).booleanValue();if (b) {curNum = 1;}} else if (obj instanceof Long) {curNum = ((Long) obj).intValue();} else {curNum = ((Integer) obj).intValue();}if (curNum == 0 || curNum == 1)return true;return false;}}
7.3 测试实体
package com.cff.springbootwork.validator.vo;import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;import com.cff.springbootwork.validator.custom.ZeroOne;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class RoleInfoZeroOne {@NotNull(message = "roleId不能为空")private Integer roleId;@NotEmpty(message = "roleName不能为空")private String roleName;@ZeroOne(message = "deleted只能为0/1")private Integer deleted;
}
7.4 测试Web

跟普通使用方法一样,无需更改。

@RequestMapping(value = "/test4")public List<String> test4(@Valid @RequestBody RoleInfoZeroOne roleInfoZeroOne, BindingResult bindingResult) {if (bindingResult.hasErrors()) {List<String> errorMsg = bindingResult.getAllErrors().stream().map(s -> s.getDefaultMessage()).collect(Collectors.toList());return errorMsg;}return Collections.singletonList("0000");}
7.5 测试结果
请求参数:
{"roleId":1,"deleted":3,"roleName": "cff"
}
返回结果:
["deleted只能为0/1"
]

品茗IT-博客专题:https://www.pomit.cn/lecture.html汇总了Spring专题、Springboot专题、SpringCloud专题、web基础配置专题。

快速构建项目

Spring项目快速开发工具:

一键快速构建Spring项目工具

一键快速构建SpringBoot项目工具

一键快速构建SpringCloud项目工具

一站式Springboot项目生成

Mysql一键生成Mybatis注解Mapper

Spring组件化构建

SpringBoot组件化构建

SpringCloud服务化构建

喜欢这篇文章么,喜欢就加入我们一起讨论Java Web吧!
品茗IT交流群

这篇关于SpringBoot入门建站全系列(三十三)集成validator校验接口数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/777161

相关文章

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

MySQL DQL从入门到精通

《MySQLDQL从入门到精通》通过DQL,我们可以从数据库中检索出所需的数据,进行各种复杂的数据分析和处理,本文将深入探讨MySQLDQL的各个方面,帮助你全面掌握这一重要技能,感兴趣的朋友跟随小... 目录一、DQL 基础:SELECT 语句入门二、数据过滤:WHERE 子句的使用三、结果排序:ORDE

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Java Spring ApplicationEvent 代码示例解析

《JavaSpringApplicationEvent代码示例解析》本文解析了Spring事件机制,涵盖核心概念(发布-订阅/观察者模式)、代码实现(事件定义、发布、监听)及高级应用(异步处理、... 目录一、Spring 事件机制核心概念1. 事件驱动架构模型2. 核心组件二、代码示例解析1. 事件定义

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor