源码剖析@ApiImplicitParam对@RequestParam的required属性的侵入性 (4)

官网的例子是在指定的Controller类中使用@InitBinder注解,影响范围仅限该Controller类,示例如下:

@InitBinder public void initBinder(WebDataBinder binder) { /* * 注册对于String类型参数对象的属性进行trim操作的编辑器, * 构造参数代表空串是否转为null,false,则将null转为空串。 */ binder.registerCustomEditor(String.class, new StringTrimmerEditor(false)); // 这里我还添加了其他类型的属性编辑器,true表示允许使用"",并且将""处理为空,false表示不允许使用"" binder.registerCustomEditor(Short.class, new CustomNumberEditor(Short.class, false)); binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, false)); binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, false)); binder.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, false)); binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class, false)); binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, false)); binder.registerCustomEditor(BigInteger.class, new CustomNumberEditor(BigInteger.class, false)); }

由于此次面临的问题是全模块@RequestParam的值的问题,需要做一个全局的配置,此时需要新增一个类,并使用@ControllerAdvice注解,代码如下:

@ControllerAdvice public class CustomWebBindingInitializer implements WebBindingInitializer { @InitBinder @Override public void initBinder(WebDataBinder binder) { /* * 注册对于String类型参数对象的属性进行trim操作的编辑器, * 构造参数代表空串是否转为null,false,则将null转为空串。 */ binder.registerCustomEditor(String.class, new StringTrimmerEditor(false)); // 这里我还添加了其他类型的属性编辑器,true表示允许使用"",并且将""处理为空,false表示不允许使用"" binder.registerCustomEditor(Short.class, new CustomNumberEditor(Short.class, false)); binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, false)); binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, false)); binder.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, false)); binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class, false)); binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, false)); binder.registerCustomEditor(BigInteger.class, new CustomNumberEditor(BigInteger.class, false)); } }

注意一下CustomNumberEditor实例初始化的传的false参数。

重启应用,看一下效果:

扩展DataBinder后相关源码阅读

都已经到这儿了,再加把劲把相关的源码看一下,还是在org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver类的resolveArgument方法的后半段:

@Override @Nullable public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { // 前面省略 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()); } } handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest); return arg; }

从binder.convertIfNecessary方法一路跟下去,中间省略一些调用,最终到达org.springframework.beans.propertyeditors.CustomNumberEditor类的setAsText方法:

/** * Parse the Number from the given text, using the specified NumberFormat. */ @Override public void setAsText(String text) throws IllegalArgumentException { if (this.allowEmpty && !StringUtils.hasText(text)) { // Treat empty String as null value. setValue(null); } else if (this.numberFormat != null) { // Use given NumberFormat for parsing text. setValue(NumberUtils.parseNumber(text, this.numberClass, this.numberFormat)); } else { // Use default valueOf methods for parsing text. setValue(NumberUtils.parseNumber(text, this.numberClass)); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfyzp.html