解决Valid在@RequestParam场景不生效的问题

2024-04-23 07:20

本文主要是介绍解决Valid在@RequestParam场景不生效的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

项目场景:

最近帮同事在看一个后端接口数据关于类型、长度、字符内容规范化的任务,想到了使用Valid注解的方式来完成,但是在实际使用的时候,发现前后端数据在不同场景下交互方式的差异,会导致Valid注解使用不生效。


问题描述

@RequestParam数据校验不生效:

public JsonResult createApplication( @NotBlank @Size(min = 1, max = 500) @RequestParam String filePath,……}

原因分析:

Spring在解析不同入参时,使用不同的解析器,有的解析器会触发Valid逻辑,有的不会。

@RequestParam等非body注解解析器不提供valid逻辑,详见org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver

@Override@Nullablepublic final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);MethodParameter nestedParameter = parameter.nestedIfOptional();Object resolvedName = resolveEmbeddedValuesAndExpressions(namedValueInfo.name);if (resolvedName == null) {throw new IllegalArgumentException("Specified name must not resolve to null: [" + namedValueInfo.name + "]");}Object arg = resolveName(resolvedName.toString(), nestedParameter, webRequest);if (arg == null) {if (namedValueInfo.defaultValue != null) {arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);}else if (namedValueInfo.required && !nestedParameter.isOptional()) {handleMissingValue(namedValueInfo.name, nestedParameter, webRequest);}arg = handleNullValue(namedValueInfo.name, arg, nestedParameter.getNestedParameterType());}else if ("".equals(arg) && namedValueInfo.defaultValue != null) {arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);}if (binderFactory != null) {WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);try {arg = binder.convertIfNecessary(arg, parameter.getParameterType(), parameter);}catch (ConversionNotSupportedException ex) {throw new MethodArgumentConversionNotSupportedException(arg, ex.getRequiredType(),namedValueInfo.name, parameter, ex.getCause());}catch (TypeMismatchException ex) {throw new MethodArgumentTypeMismatchException(arg, ex.getRequiredType(),namedValueInfo.name, parameter, ex.getCause());}// Check for null value after conversion of incoming argument valueif (arg == null && namedValueInfo.defaultValue == null &&namedValueInfo.required && !nestedParameter.isOptional()) {handleMissingValueAfterConversion(namedValueInfo.name, nestedParameter, webRequest);}}handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);return arg;}

@RequestBody注解解析器会调用valid逻辑,详见org.springframework.web.method.annotation.ModelAttributeMethodProcessor#validateIfApplicable

protected void validateValueIfApplicable(WebDataBinder binder, MethodParameter parameter,Class<?> targetType, String fieldName, @Nullable Object value) {for (Annotation ann : parameter.getParameterAnnotations()) {Object[] validationHints = ValidationAnnotationUtils.determineValidationHints(ann);if (validationHints != null) {for (Validator validator : binder.getValidators()) {if (validator instanceof SmartValidator) {try {((SmartValidator) validator).validateValue(targetType, fieldName, value,binder.getBindingResult(), validationHints);}catch (IllegalArgumentException ex) {// No corresponding field on the target class...}}}break;}}}

解决方案:

Spring解析参数的逻辑没办法调整,只能在方法调用时进行更改。

如果要在方法层面使用valid注解,就需要添加一个bean:org.springframework.validation.beanvalidation.MethodValidationPostProcessor

@Configuration
@EnableAutoConfiguration
public class ConfigurationFactory {@Beanpublic MethodValidationPostProcessor methodValidationPostProcessor(){return new MethodValidationPostProcessor();}}

然后再添加一个全局异常捕获就好了。

@Slf4j
@RestControllerAdvice
public class GlobalException {@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler({HandlerMethodValidationException.class})public Result handlerMethodValidationException(HandlerMethodValidationException e) {// 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息if (!StringUtils.isEmpty(e.getMessage())) {return ResultUtil.failureMsg(e.getMessage());}return ResultUtil.failure(ResultEnum.SERVICE_FAILURE);}
}

这篇关于解决Valid在@RequestParam场景不生效的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

mybatis和mybatis-plus设置值为null不起作用问题及解决

《mybatis和mybatis-plus设置值为null不起作用问题及解决》Mybatis-Plus的FieldStrategy主要用于控制新增、更新和查询时对空值的处理策略,通过配置不同的策略类型... 目录MyBATis-plusFieldStrategy作用FieldStrategy类型每种策略的作

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Python Jupyter Notebook导包报错问题及解决

《PythonJupyterNotebook导包报错问题及解决》在conda环境中安装包后,JupyterNotebook导入时出现ImportError,可能是由于包版本不对应或版本太高,解决方... 目录问题解决方法重新安装Jupyter NoteBook 更改Kernel总结问题在conda上安装了

pip install jupyterlab失败的原因问题及探索

《pipinstalljupyterlab失败的原因问题及探索》在学习Yolo模型时,尝试安装JupyterLab但遇到错误,错误提示缺少Rust和Cargo编译环境,因为pywinpty包需要它... 目录背景问题解决方案总结背景最近在学习Yolo模型,然后其中要下载jupyter(有点LSVmu像一个

Goland debug失效详细解决步骤(合集)

《Golanddebug失效详细解决步骤(合集)》今天用Goland开发时,打断点,以debug方式运行,发现程序并没有断住,程序跳过了断点,直接运行结束,网上搜寻了大量文章,最后得以解决,特此在这... 目录Bug:Goland debug失效详细解决步骤【合集】情况一:Go或Goland架构不对情况二:

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

如何解决Pycharm编辑内容时有光标的问题

《如何解决Pycharm编辑内容时有光标的问题》文章介绍了如何在PyCharm中配置VimEmulator插件,包括检查插件是否已安装、下载插件以及安装IdeaVim插件的步骤... 目录Pycharm编辑内容时有光标1.如果Vim Emulator前面有对勾2.www.chinasem.cn如果tools工

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动