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 Security常见问题及解决方案

《SpringSecurity常见问题及解决方案》SpringSecurity是Spring生态的安全框架,提供认证、授权及攻击防护,支持JWT、OAuth2集成,适用于保护Spring应用,需配置... 目录Spring Security 简介Spring Security 核心概念1. ​Securit

SpringBoot+EasyPOI轻松实现Excel和Word导出PDF

《SpringBoot+EasyPOI轻松实现Excel和Word导出PDF》在企业级开发中,将Excel和Word文档导出为PDF是常见需求,本文将结合​​EasyPOI和​​Aspose系列工具实... 目录一、环境准备与依赖配置1.1 方案选型1.2 依赖配置(商业库方案)二、Excel 导出 PDF

SpringBoot改造MCP服务器的详细说明(StreamableHTTP 类型)

《SpringBoot改造MCP服务器的详细说明(StreamableHTTP类型)》本文介绍了SpringBoot如何实现MCPStreamableHTTP服务器,并且使用CherryStudio... 目录SpringBoot改造MCP服务器(StreamableHTTP)1 项目说明2 使用说明2.1

spring中的@MapperScan注解属性解析

《spring中的@MapperScan注解属性解析》@MapperScan是Spring集成MyBatis时自动扫描Mapper接口的注解,简化配置并支持多数据源,通过属性控制扫描路径和过滤条件,利... 目录一、核心功能与作用二、注解属性解析三、底层实现原理四、使用场景与最佳实践五、注意事项与常见问题六

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对

Java中Arrays类和Collections类常用方法示例详解

《Java中Arrays类和Collections类常用方法示例详解》本文总结了Java中Arrays和Collections类的常用方法,涵盖数组填充、排序、搜索、复制、列表转换等操作,帮助开发者高... 目录Arrays.fill()相关用法Arrays.toString()Arrays.sort()A

Spring Boot Maven 插件如何构建可执行 JAR 的核心配置

《SpringBootMaven插件如何构建可执行JAR的核心配置》SpringBoot核心Maven插件,用于生成可执行JAR/WAR,内置服务器简化部署,支持热部署、多环境配置及依赖管理... 目录前言一、插件的核心功能与目标1.1 插件的定位1.2 插件的 Goals(目标)1.3 插件定位1.4 核

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习