SpringBoot controller参数校验方法详细讲解

目录
  • 单参数校验
  • 实体类校验
  • 分组校验
  • 嵌套校验
  • 自定义注解

参数校验主要使用两个标签@Validated和@Valid;

@Valid是Hibernate的注解校验,@Validated是spring的,是@Valid的增强;这两个标签也有一些不同之处,@Valid可以标注在成员属性上也可以嵌套校验,而@Validated不行,但是@Validated可以使用分组校验;

maven导入:

	<dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-validation</artifactId>
	    <version>2.7.5</version>
	</dependency>

通常用到的注解基本都在javax.validation.constraints包下,基本都有value(设定值)、message(设置错误消息)、groups(指定分组)属性:

  • @AssertFalse:必须为false,支持boolean和Boolean,null是有效的;
  • @AssertTrue:必须为true,支持boolean和Boolean,null是有效的;
  • @DecimalMax:必须是一个小于或者小于等于设定值的数字,可以用inclusive指定是否包含数字(默认true),并且value是String类型的,支持BigDecimal、BigInteger、CharSequence、byte / short / int / long以及它们的包装类(由于舍入原因不支持double和float),null是有效的;
  • @DecimalMin:必须是一个大于或者大于等于设定值的数字,其他同@DecimalMax;
  • @Digits:设定可接受范围内的数字,必须指定integer(整数位数)和fraction(小数位数),支持BigDecimal、BigInteger、CharSequence、byte / short / int / long以及它们的包装类,null是有效的;
  • @Email:必须是一个正确格式的邮箱,可以使用regexp指定正则表达式(默认是任意字符串),可以使用flags指定正则表达式的选项,null是有效的;
  • @Future:必须是一个未来的瞬间、日期或时间(Now是虚拟机默认的当前时区的时间),支持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,null是有效的;
  • @FutureOrPresent:必须是现在或未来的瞬间、日期或时间,其他同@Future;
  • @Max:必须是小于等于指定值的数字,value是long类型,支持BigDecimal、BigInteger、byte / short / int / long以及它们的包装类(不支持float和double),null是有效的;
  • @Min:必须是大于等于指定值的数字,其他同@Max;
  • @Negative:必须是一个严格的负数,0为无效值,支持BigDecimal、BigInteger、byte / short / int / long / float / double以及它们的包装类,null是有效的;
  • @NegativeOrZero,必须是负数或者0,其他同@Negative;
  • @NotBlank:不能为null,并且至少包含一个非空白字符,接受CharSequence;
  • @NotEmpty:不能为null或空(集合),支持CharSequence(字符序列长度)、Collection(集合size)、Map(map size)、Array(数组长度);
  • @NotNull:不能为null,支持所有类型;
  • @Null:必须为null,支持所有类型;
  • @Past:必须是一个过去的瞬间、日期或时间,其他同@Future;
  • @PastOrPresent:必须是现在或过去的瞬间、日期或时间,其他同@Future;
  • @Pattern:必须符合指定的正则表达式,必须使用regexp参数指定正则表达式;
  • @Positive:必须是一个严格的正数,0为无效值,其他同@Negative;
  • @PositiveOrZero:必须是正数或者0,其他同@Negative;
  • @Size:指定元素大小必须在指定范围内(包括边界值),使用min指定下边界(默认0),使用max指定上边界(默认Integer.MAX_VALUE),支持CharSequence、Collection、Map、Array,null是有效的;

单参数校验

在controller类上添加@Validated标签,在方法的参数前加验证标签,并且同一个参数可以添加多个标签;

启动类:(使用默认配置,端口8080)

package testspringboot.test6paramvalidation;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Test6Main {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SpringApplication.run(Test6Main.class, args);
	}
}

controller类:

package testspringboot.test6paramvalidation;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test6")
@Validated
public class Test6Controller {
	@RequestMapping("/a")
	public String a(@NotNull(message = "参数s不能为null") String s, @Min(5) @Max(value = 10) long a) {
		System.out.println(s);
		System.out.println(a);
		return String.format("s:%s a:%d", s, a);
	}
}

postman测试:

返回的错误msg也可以使用自定义设定,使用@RestControllerAdvice注释一个类,然后在类里定义各种错误msg,就像这样:

package testspringboot.test6paramvalidation;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class ValidException {
	@ExceptionHandler(value = MethodArgumentNotValidException.class)
    public String handleValidException(MethodArgumentNotValidException e) {
        List<String> msgList = e.getBindingResult().getAllErrors()
        		.stream()
        		.map(ObjectError::getDefaultMessage)
        		.collect(Collectors.toList());
        return "MethodArgumentNotValidException: " + msgList.toString();
    }
    @ExceptionHandler(value = ConstraintViolationException.class)
    public String handleConstraintViolationException(ConstraintViolationException e) {
        List<String> msgList = e.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
            	.collect(Collectors.toList());
        return "ConstraintViolationException: " + msgList.toString();//返回错误描述
    }
}

再次测试结果:

默认验证所有参数,即使前面验证不通过也会继续验证,可以设置快速失败,使验证失败立即返回不继续验证;

自定义注入Validator类:

package testspringboot.test6paramvalidation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ValidatConfig {
	@Bean
	public Validator validator() {
		ValidatorFactory vfactory = Validation.byProvider(HibernateValidator.class)
				.configure()
				.failFast(true)//开启快速失败
				.buildValidatorFactory();
		return vfactory.getValidator();
	}
}

再次测试结果,只显示一个错误msg了:

实体类校验

只需要在controller类的方法实体类参数前加@Validated或者@Valid标签,实体类里的属性前加验证标签,controller类上可以不用@Validated标签也行;

实体类:

package testspringboot.test6paramvalidation;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
public class Bparam {
	@NotNull
	public String s;
	@Max(value = 10, message = "Bparam的x参数不能超过10")
	public int x;
	public String getS() {
		return s;
	}
	public void setS(String s) {
		this.s = s;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	@Override
	public String toString() {
		return "Bparam [s=" + s + ", x=" + x + "]";
	}
}

controller类里的方法:

	@RequestMapping("/b")
	public String b(@Valid Bparam b) {
		return b.toString();
	}

测试:

另外错误消息也可以在controller类的方法参数里接收,参数里使用BindingResult就可以处理:

	@RequestMapping("/b")
	public String b(@Valid Bparam b, BindingResult result) {
		if (result.hasErrors()) {
			List<String> errors = result.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.toList());
			return "BindingResult Errors: " + errors.toString();
		}
		return b.toString();
	}

使用post的消息体接收参数也一样,在参数前多加一个@RequestBody:

	@RequestMapping("/b")
	public String b(@RequestBody @Validated Bparam b, BindingResult result) {
		if (result.hasErrors()) {
			List<String> errors = result.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.toList());
			return "BindingResult Errors: " + errors.toString();
		}
		return b.toString();
	}

分组校验

可以为同一属性设置不同情况下应用不同的注解标签,需要在注解标签里使用groups参数,groups是一个class集合,一个标签可以设置多个group,在controller类里方法的参数前的@Validated标签里使用value指定要使用的group验证(可以指定多个group验证),没有设置groups的标签默认属于Default.class的group,设置group的class通常使用interface,可以写在外面或者直接写到实体类内部;

实体类:

package testspringboot.test6paramvalidation;
import javax.validation.constraints.AssertFalse;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class Cparam {
	@AssertTrue(message = "b应为true", groups = CparamBTrue.class)
	@AssertFalse(message = "b应为false", groups = CparamBFalse.class)
	public boolean b;
	@NotBlank
	@Size(min = 1, max = 5, message = "s的长度1~5")
	public String s;
	@Min(20)
	public int i;
//	interface CparamBTrue{}
//	interface CparamBFalse{}
}
interface CparamBTrue{}
interface CparamBFalse{}

controller方法:

	@RequestMapping("/c1")
	public String c1(@RequestBody @Validated(CparamBTrue.class) Cparam c, BindingResult result) {
		if (result.hasErrors()) {
			List<String> errors = result.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.toList());
			return "BindingResult Errors: " + errors.toString();
		}
		return "OK";
	}
	@RequestMapping("/c2")
	public String c2(@RequestBody @Validated(value = {CparamBFalse.class, Default.class}) Cparam c, BindingResult result) {
		if (result.hasErrors()) {
			List<String> errors = result.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.toList());
			return "BindingResult Errors: " + errors.toString();
		}
		return "OK";
	}

分组测试:

c1只验证了group是CparamBTrue的成员b,c2除了验证了group是CparamBFalse的成员b,也验证了没有设置groups的s和i;

另外也可以设置动态组校验,根据某些条件和情况设置验证的groups,需要在实体类上添加@GroupSequenceProvider标签指定实现了DefaultGroupSequenceProvider接口并实现接口里getValidationGroups方法的class,getValidationGroups方法返回List<Class<?>>,即为当前请求需要使用的groups(返回值相当于controller类方法参数前@Validated标签里的value的作用);

例如根据实体类内boolean值指定int值使用正负数:

实体类:

package testspringboot.test6paramvalidation;
import javax.validation.constraints.Negative;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import org.hibernate.validator.group.GroupSequenceProvider;
@GroupSequenceProvider(value = C3paramGroupProvider.class)
public class C3param {
	@NotNull(message = "b不能为null")
	public boolean b;
	@NotNull
	@Positive(message = "b为true时i应大于0", groups = BTrue.class)
	@Negative(message = "b为false时i应小于0", groups = BFalse.class)
	public int i;
	@Override
	public String toString() {
		return "C3param [b=" + b + ", i=" + i + "]";
	}
	interface BTrue{}
	interface BFalse{}
}

GroupProvider:

package testspringboot.test6paramvalidation;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;
public class C3paramGroupProvider implements DefaultGroupSequenceProvider<C3param> {
	@Override
	public List<Class<?>> getValidationGroups(C3param object) {
		System.out.println("obj:" + object);
		List<Class<?>> groupList = new ArrayList<>();
		groupList.add(C3param.class);//实体类需要加入
		if (object != null) {//该方法会调用多次,object可能为null
			//b为true时使用BTrue.class组,b为false时使用BFalse.class组
			groupList.add(object.b ? C3param.BTrue.class : C3param.BFalse.class);
		}
		return groupList;
	}
}

controller方法:

	@RequestMapping("/c3")
	public String c3(@RequestBody @Validated C3param c3, BindingResult result) {
		System.out.println("param:" + c3);
		if (result.hasErrors()) {
			List<String> errors = result.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.toList());
			return "BindingResult Errors: " + errors.toString();
		}
		return "OK";
	}

测试:

嵌套校验

实体类成员为另一个级联的类时,需要在成员前使用@Valid标签(支持嵌套),并且提供该级联的成员属性的get方法,另外级联类内部也需要提供需要验证的成员属性的get方法(不验证的成员不用get方法)

第一层实体类:

package testspringboot.test6paramvalidation;
import javax.validation.Valid;
import javax.validation.constraints.AssertTrue;
public class D1param {
	@AssertTrue(message = "D1param.b必须为true")
	public boolean b;
	@Valid
	public D2param d2;
	public D2param getD2() {//级联对象需要get方法
		return d2;
	}
}

第二层实体类:

package testspringboot.test6paramvalidation;
import javax.validation.Valid;
import javax.validation.constraints.Positive;
public class D2param {
	@Positive(message = "D2param.i必须为正数")
	public int i;
	public String s;//不验证,不需get方法
	@Valid
	public D3param d3;
	public int getI() {//成员需要get方法
		return i;
	}
	public D3param getD3() {//级联对象需要get方法
		return d3;
	}
}

第三层实体类:

package testspringboot.test6paramvalidation;
import javax.validation.constraints.NotNull;
public class D3param {
	@NotNull(message = "D3param.s不能为null")
	public String s;
	public String getS() {//成员需要get方法
		return s;
	}
}

controller方法:

	@RequestMapping("/d")
	public String d(@RequestBody @Validated D1param d1, BindingResult result) {
		if (result.hasErrors()) {
			List<String> errors = result.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.toList());
			return "BindingResult Errors: " + errors.toString();
		}
		return "OK";
	}

测试:

自定义注解

定义一个注解,使用@Retention、@Target、@Constraint标签注释,并携带三个方法message()、groups()、payload(),并在@Constraint标签里使用validatedBy属性指定自定义验证类,自定义验证类实现ConstraintValidator<A extends Annotation, T>接口的boolean isValid(T value, ConstraintValidatorContext context)方法,判断验证是否通过;

自定义注解:(功能:验证是偶数)

package testspringboot.test6paramvalidation;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Retention(RUNTIME)
@Target(FIELD)
@Constraint(validatedBy = EValidator.class)
public @interface EAnnotation {
	String message() default "应该是偶数";
	Class<?>[] groups() default {};
	Class<? extends Payload>[] payload() default {};
}

对应的验证类:

package testspringboot.test6paramvalidation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class EValidator implements ConstraintValidator<EAnnotation, Integer> {
	@Override
	public boolean isValid(Integer value, ConstraintValidatorContext context) {
		return value % 2 == 0;
	}
}

实体类:

package testspringboot.test6paramvalidation;
public class Eparam {
	@EAnnotation
	public int i;
}

controller方法:

	@RequestMapping("/e")
	public String e(@RequestBody @Validated Eparam e, BindingResult result) {
		if (result.hasErrors()) {
			List<String> errors = result.getAllErrors().stream().map(x -> x.getDefaultMessage()).collect(Collectors.toList());
			return "BindingResult Errors: " + errors.toString();
		}
		return "OK";
	}

测试:

到此这篇关于SpringBoot controller参数校验方法详细讲解的文章就介绍到这了,更多相关SpringBoot controller 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot开发详解之Controller接收参数及参数校验

    目录 Controller 中注解使用 传输参数的几种Method 获取参数的几种常用注解 使用对象直接获取参数 使用@Valid对参数进行校验 总结 Controller 中注解使用 接受参数的几种传输方式以及几种注解: 在上一篇中,我们使用了JDBC链接数据库,完成了简单的后端开发.但正如我在上文中抛出的问题,我们能不能更好的优化我们在Controller中接受参数的方式呢?这一篇中我们就来聊一聊怎么更有效的接收Json参数. 传输参数的几种Method 在定义一个Rest接口时,我们通常会

  • springboot中的controller注意事项说明

    关于controller注意事项 spring boot的controller水深无比,经过学习,我总结一些tips,以便以后参照,减少错误: 1.controller主要有两个标签 @Controller和@RestController,两个标签无法同时发挥作用,前者标注的类只能返回静态文件,后者标注的类用于返回数据类型如json字符串 2.使用@Controller标签时 templates下的文件并不能被识别(自己试验过,发现和网上很多说法都不一样),只有static文件夹下文件能直接被读

  • SpringBoot在Controller层接收参数的n种姿势(超详细)

    目录 前言 接收get请求 接收post请求 前言 在工作中,比如要实现一个功能,前端传什么参数,后端的controller层中怎么接收参数 ,封装成了什么实体对象,有些参数是在URL上使用,有些参数是在body上使用,service层中做了什么逻辑,调用dao层的sql怎么写的,前端传的参数,后端用controller中的一个方法来接收请求这些都是我们需要思考的逻辑! 下面重点讲下SpringBoot接收请求的n种姿势,建议收藏哦- 接收get请求 (1)get请求无参数 @RestContr

  • SpringBoot中controller深层详细讲解

    在基于spring框架的项目开发中,必然会遇到controller层,它可以很方便的对外提供数据接口服务,也是非常关键的出口,所以非常有必要进行规范统一,使其既简洁又优雅. controller层的职责为负责接收和响应请求,一般不负责具体的逻辑业务的实现.controller主要工作如下: 接收请求并解析参数: 调用service层执行具体的业务逻辑(可能包含参数校验): 捕获业务异常做出反馈: 业务逻辑执行成功做出响应: 目前controller层代码会存在的问题: 参数校验过多地耦合了业务代

  • SpringBoot Controller中的常用注解

    目录 概述 常用注解简介 1.@Controller 2.@RestController 3.@RequestMapping 4.@RequestBody 5.@RequestParam 6.@PathVariable 总结 概述 Controller是Spring接受并处理网页请求的组件,是整个应用的入口,因此学会Controller的常用注解对理解一个应用是重中之重.SpringBoot的Controller中经常会用到注解@Controller.@RestController.@Reque

  • SpringBoot如何配置Controller实现Web请求处理

    目录 Controller处理请求 创建Controller 类 @Controller注解 标识方法@RequestMapping 测试 Controller处理请求 由于 在建立 SpringBoot项目时选择的 Web > Spring Web , Maven会导入 SpringMVC 框架 依赖, 做为 Web处理框架 在 SpringMVC框架中 , 通过 Controller类中的方法 来处理请求, 产生响应 在方法中 要解决以下问题 标识方法 转页 接收请求时传递信息 封装响应信息

  • SpringBoot配置文件加载方法详细讲解

    目录 配置文件的读取顺序 多坏境的配置文件 个性化配置 自定义配置文件名称和路径 加载yml文件 配置文件的读取顺序 根目录/config/application.properties 根目录/config/application.yml 根目录/application.properties 根目录/application.yml classpath目录/config/application.properties classpath目录/config/application.yml classp

  • SpringBoot进行参数校验的方法详解

    目录 介绍 1.SpringBoot中集成参数校验 1.1引入依赖 1.2定义参数实体类 1.3定义校验类进行测试 1.4打开接口文档模拟提交数据 2.参数异常加入全局异常处理器 3.自定义参数校验 3.1创建自定义注解 3.2自定义校验逻辑 3.3在字段上增加注解 3.4体验效果 4.分组校验 4.1定义分组接口 4.2在模型中给参数分配分组 4.3体现效果 介绍 在日常的接口开发中,为了防止非法参数对业务造成影响,经常需要对接口的参数进行校验,例如登录的时候需要校验用户名和密码是否为空,添加

  • SpringBoot整合Mybatis与MybatisPlus方法详细讲解

    目录 一.整合MyBatis操作 1.配置模式 2.注解模式 3.混合模式 二.整合 MyBatis-Plus 完成CRUD 1.什么是MyBatis-Plus 2.整合MyBatis-Plus 3.CRUD功能 一.整合MyBatis操作 官网:MyBatis · GitHub SpringBoot官方的Starter:spring-boot-starter-* 第三方的starter的格式: *-spring-boot-starter <dependency> <groupId>

  • 使用@Valid+BindingResult进行controller参数校验方式

    目录 @Valid+BindingResult进行controller参数校验 Controller层方法的参数校验 全局统一异常拦截器 @Valid+BindingResult进行controller参数校验 由于controller是调用的第一层,经常参数校验将在这里完成,常见有非空校验.类型校验等,常见写法为以下伪代码: public void round(Object a){ if(a.getLogin() == null){ return "手机号不能为空!"; } } 但是

  • SpringBoot各种参数校验的实例教程

    目录 简单使用 引入依赖 requestBody参数校验 requestParam/PathVariable参数校验 统一异常处理 进阶使用 分组校验 嵌套校验 集合校验 自定义校验 编程式校验 快速失败(Fail Fast) @Valid和@Validated区别 实现原理 requestBody参数校验实现原理 方法级别的参数校验实现原理 总结 简单使用 Java API规范(JSR303)定义了Bean校验的标准validation-api,但没有提供实现.hibernate valida

  • ThreadPoolExecutor中的submit()方法详细讲解

    目录 submmit()参数解析 submit()的返回值Future FutureTask的get()的实现 submit()使用案例 在使用线程池的时候,发现除了execute()方法可以执行任务外,还发现有一个方法submit()可以执行任务. submit()有3个参数不一的方法,这些方法都是在ExecutorService接口中声明的,在AbstractExecutorService中实现,而ThreadPoolExecutor继承AbstractExecutorService. <T

  • springboot接口参数校验JSR303的实现

    目录 一.在controller接口处理校验异常 二.统一异常处理 三.错误码枚举类 四.自定义参数校验注解 在 javax.validation.constraints包中定义了非常多的校验注解,引入依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependenc

  • SpringBoot封装响应处理超详细讲解

    目录 背景 报文基本格式 创建枚举类 定义统一返回结果实体类 定义返回工具类 统一报文封装在接口中的使用 统一异常处理 小结 背景 越来越多的项目开始基于前后端分离的模式进行开发,这对后端接口的报文格式便有了一定的要求.通常,我们会采用JSON格式作为前后端交换数据格式,从而减少沟通成本等. 报文基本格式 一般报文格式通常会包含状态码.状态描述(或错误提示信息).业务数据等信息. 在此基础上,不同的架构师.项目搭建者可能会有所调整. 但从整体上来说,基本上都是大同小异. 在SpringBoot项

  • laravel请求参数校验方法

    对于后端开发而言,前端request请求中的参数校验是一个必不可少的环节.无论传来的参数是id还是email还是其他的参数,我们都要对参数的类型.大小.格式等等做这样或者那样的校验,然后才进行逻辑处理,以确保逻辑处理时万无一失,不会出现异样.于是乎,在controller层中就会出现一大坨的校验代码,这些校验代码甚至有时候都超过了正常的逻辑代码的数量,对于程序的扩展和维护很不利的. 但是,laravel为我们提供了一个很好的服务去解决参数校验这个问题,它就是----Validate. 首先,我们

  • java、spring、springboot中整合Redis的详细讲解

    java整合Redis 1.引入依赖或者导入jar包 <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> 2.代码实现 public class JedisTest { public static void main(String[]

随机推荐