Rumah> Java> javaTutorial> teks badan

Bagaimanakah SpringBoot melakukan pengesahan parameter?

WBOY
Lepaskan: 2023-05-18 15:52:36
ke hadapan
1234 orang telah melayarinya

Pengenalan

Dalam pembangunan antara muka harian, untuk mengelakkan parameter yang menyalahi undang-undang daripada menjejaskan perniagaan, selalunya perlu untuk mengesahkan parameter antara muka Sebagai contoh, semasa log masuk, adalah perlu untuk mengesahkan sama ada nama pengguna dan kata laluan kosong Apabila menambah pengguna, sahkan sama ada format alamat e-mel dan nombor telefon mudah alih pengguna adalah betul. Ia akan menjadi terlalu rumit untuk bergantung pada kod untuk mengesahkan parameter antara muka satu demi satu, dan kebolehbacaan kod akan menjadi sangat lemah.

ValidatorRangka kerja direka untuk membantu pembangun menulis kurang kod semasa pembangunan dan meningkatkan kecekapan pembangunan Pengesah digunakan khas untuk mengesahkan parameter antara muka, seperti pengesahan biasa yang diperlukan, pengesahan format e-mel, Nama pengguna mestilah antara; 6 dan 12 dsb.

Seterusnya mari kita lihat cara menyepadukan rangka kerja pengesahan parameter dalam SpringbBoot.

1. Pengesahan parameter bersepadu dalam SpringBoot

1.1 Memperkenalkan kebergantungan

 org.springframework.boot spring-boot-starter-validation 
Salin selepas log masuk

1.2 Mentakrifkan kelas entiti parameter

package com.didiplus.modules.sys.domain; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/25 * Desc: 字典类型领域模型 */ @Data @ApiModel(value = "字典类型") public class SysDictType { @ApiModelProperty("ID") private String id; @NotBlank(message = "字典名称必填项") @ApiModelProperty(value = "字典名称",example = "用户ID") private String typeName; @NotBlank(message = "字典编码不能为空") @ApiModelProperty(value = "字典编码") private String typeCode; @Email(message = "请填写正确的邮箱地址") @ApiModelProperty(value = "字典编码") private String email; @ApiModelProperty(value = "字典描述") private String description; @NotBlank(message = "字典状态不能为空") @ApiModelProperty(value = "字典状态") private String enable; }
Salin selepas log masuk

Anotasi kekangan biasa adalah seperti berikut: >

1.3定义校验类进行测试

package com.didiplus.modules.sys.controller; import com.didiplus.modules.sys.domain.SysDictType; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.annotations.parameters.RequestBody; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/25 * Desc: 数据字典控制器 */ @RestController @Api(tags = "数据字典") @RequestMapping("/api/sys/dictType") public class SysDictTypeController { @ApiOperation("字典添加") @PostMapping("/add") public SysDictType add(@Validated @RequestBody SysDictType sysDictType) { return sysDictType; } @ApiOperation("字典修改") @PutMapping("/edit") public SysDictType edit(@Validated @RequestBody SysDictType sysDictType) { return sysDictType; } }
Salin selepas log masuk

这里我们先定义两个方法add,edit,都是使用了@RequestBody注解,用于接受前端发送的json数据。

1.4打开接口文档模拟提交数据

Bagaimanakah SpringBoot melakukan pengesahan parameter?

通过接口文档看到前三个字段都是必填项。

Bagaimanakah SpringBoot melakukan pengesahan parameter?

由于email的格式不对就被拦截了,提示是因为邮箱地址不对。

2.参数异常加入全局异常处理器

虽然我们之前定义了全局异常拦截器,也看到了拦截器确实生效了,但是Validator校验框架返回的错误提示太臃肿了,不便于阅读,为了方便前端提示,我们需要将其简化一下。

直接修改之前定义的RestExceptionHandler,单独拦截参数校验的三个异常:

javax.validation.ConstraintViolationException

org.springframework.validation.BindException

org.springframework.web.bind.MethodArgumentNotValidException

代码如下:

package com.didiplus.common.web.response.Handler; import com.didiplus.common.web.response.Result; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; 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; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.ValidationException; import java.util.stream.Collectors; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/24 * Desc: 默认全局异常处理。 */ @RestControllerAdvice public class RestExceptionHandler { /** * 默认全局异常处理。 * @param e the e * @return ResultData */ @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class}) public ResponseEntity> handleValidatedException(Exception e) { Result result = null; if (e instanceof MethodArgumentNotValidException) { MethodArgumentNotValidException ex =(MethodArgumentNotValidException) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getBindingResult().getAllErrors().stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.joining(";")) ); } else if (e instanceof ConstraintViolationException){ ConstraintViolationException ex = (ConstraintViolationException) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getConstraintViolations().stream() .map(ConstraintViolation::getMessage) .collect(Collectors.joining(";")) ); }else if (e instanceof BindException) { BindException ex = (BindException ) e; result = Result.failure(HttpStatus.BAD_REQUEST.value(), ex.getAllErrors().stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.joining(";")) ); } return new ResponseEntity<>(result,HttpStatus.BAD_REQUEST); } }
Salin selepas log masuk

美化之后错误信息提示更加友好

Bagaimanakah SpringBoot melakukan pengesahan parameter?

3.自定义参数校验

虽然Spring Validation 提供的注解基本上够用,但是面对复杂的定义,我们还是需要自己定义相关注解来实现自动校验。
比如上面实体类中添加的sex性别属性,只允许前端传递传 M,F 这2个枚举值,如何实现呢?

3.1创建自定义注解

package com.didiplus.common.annotation; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Retention(RUNTIME) @Repeatable(EnumString.List.class) @Documented @Constraint(validatedBy = EnumStringValidator.class)//标明由哪个类执行校验逻辑 public @interface EnumString { String message() default "value not in enum values."; Class[] groups() default {}; Class[] palyload() default {}; /** * @return date must in this value array */ String[] value(); /** * Defines several {@link EnumString} annotations on the same element. * * @see EnumString */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) @Retention(RUNTIME) @Documented @interface List { EnumString[] value(); } }
Salin selepas log masuk

3.2自定义校验逻辑

package com.didiplus.common.annotation; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.Arrays; import java.util.List; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ public class EnumStringValidator implements ConstraintValidator { private List enumStringList; @Override public void initialize(EnumString constraintAnnotation) { enumStringList = Arrays.asList(constraintAnnotation.value()); } @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { if(value == null) { return true; } return enumStringList.contains(value); } }
Salin selepas log masuk

3.3在字段上增加注解

@ApiModelProperty(value = "性别") @EnumString(value = {"F","M"}, message="性别只允许为F或M") private String sex;
Salin selepas log masuk

3.4体验效果

Bagaimanakah SpringBoot melakukan pengesahan parameter?

4.分组校验

一个对象在新增的时候某些字段是必填,在更新是有非必填。如上面的SysDictTypeid属性在新增操作时都是必填。面对这种场景你会怎么处理呢?

其实Validator校验框架已经考虑到了这种场景并且提供了解决方案,就是分组校验。要使用分组校验,只需要三个步骤:

4.1定义分组接口

package com.didiplus.common.base; import javax.validation.groups.Default; /** * Author: didiplus * Email: 972479352@qq.com * CreateTime: 2022/4/26 * Desc: */ public interface ValidGroup extends Default { interface Crud extends ValidGroup{ interface Create extends Crud{ } interface Update extends Crud{ } interface Query extends Crud{ } interface Delete extends Crud{ } } }
Salin selepas log masuk

4.2在模型中给参数分配分组

@Null(groups = ValidGroup.Crud.Create.class) @NotNull(groups = ValidGroup.Crud.Update.class,message = "字典ID不能为空") @ApiModelProperty("ID") private String id;
Salin selepas log masuk

4.3体现效果

Bagaimanakah SpringBoot melakukan pengesahan parameter?

Bagaimanakah SpringBoot melakukan pengesahan parameter?

Atas ialah kandungan terperinci Bagaimanakah SpringBoot melakukan pengesahan parameter?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!