当前位置:首页 > 技术分析 > 正文内容

SpringBoot项目:接口参数空白值如何替换为null值

ruisui883个月前 (02-04)技术分析18

来源:
https://mp.weixin.qq.com/s/slPpOtqm5tvwxA4e_so4gQ

问题发生

我们公司代码生成的时候,查询列表统一都是使用了setEntity() ,查询写法如下:

查询的方法是Get方法:

前端是通过url加参数传过来的,如果有一个参数值为空的时候,由于setEntity() 并不过滤空白,执行sql的时候 会把""作为参数去当做查询条件,查询就出现了问题:

于是我就想把空白转换为null来解决这个问题了。

初始解决

一开始自然而然想到在setEntity之前先判断, 如果BasReservoirArea这个实例有字段的值是空白就设置为null

用到的工具类如下

问题解决了。

优化

由于感觉上面的解决方案不够专业,不够优雅,所以先寻找更好的解决办法,在后端接收参数值的时候,如果接收的是空白,直接设置为null, 这样就不需要再次转换了。

解决问题首先要考虑两种情况,一种是前端通过Get请求,路径上带参数;另一种是Post请求,带着Request报文。

Post请求报文体

由于笔者熟悉Post中报文体的转换,知道是MappingJackson2HttpMessageConverter结合Jackson实现报文体转换为实例的,而且也研究过Jackson, 所以解决办法如下

创建一个针对于String.class的Jackson的反序列类:

@ControllerAdvice
public?class?GlobalControllerAdiviceController?{
????//WebDataBinder是用来绑定请求参数到指定的属性编辑器,可以继承WebBindingInitializer
????//来实现一个全部controller共享的dataBiner?Java代码
????@InitBinder
????public?void?dataBind(WebDataBinder?binder)?{
????????///注册
????????binder.registerCustomEditor(String.class,?new?StringTrimmerEditor(true));
????}
}

创建一个MappingJackson2HttpMessageConverter Bean:

@Bean
@Primary
public?MappingJackson2HttpMessageConverter?mappingJackson2HttpMessageConverter()?{
?MappingJackson2HttpMessageConverter?jsonConverter?=?new?MappingJackson2HttpMessageConverter();
?//设置解析JSON工具类
?ObjectMapper?objectMapper?=?new?ObjectMapper();
?objectMapper.getSerializerProvider().setNullValueSerializer(
??new?JsonSerializer()?{
???@Override
???public?void?serialize(Object?value,?JsonGenerator?jsonGenerator,?SerializerProvider????????serializerProvider)?throws?IOException?{
?????jsonGenerator.writeString("");
???}
??}
?);
?
?SimpleModule?simpleModule?=?new?SimpleModule();
?simpleModule.addDeserializer(String.class,?new?StringDescrializer());
????//注册自定义的StringDescrializer
????//registerModules函数可以注册多个Module
?objectMapper.registerModule(simpleModule);

????//忽略未知属性?防止解析报错
????objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,?false);

????jsonConverter.setObjectMapper(objectMapper);
????List?list?=?new?ArrayList<>();
????list.add(MediaType.APPLICATION_JSON_UTF8);
????jsonConverter.setSupportedMediaTypes(list);
????return?jsonConverter;
}

对于Post报文体来说,测试成功了。

Get路径带参数

上面的解决方法不适用于Get方法路径带参数的情况,所以需要另外想办法了。

由于我使用过@InitBinder注解,知道可以注入自定义的PropertyEditor, 在Editor里面可以自定义格式或者返回值,于是,自定义一个StringEditor来处理空白的问题:

想要全局controller共享这个Databinder:

对于Get路径带参数来说,测试也成功了

思考

解决完问题后,还是觉得不够优雅,觉得spring 应该会考虑到这种情况,终于在spring 的文档中查阅到StringTrimmerEditor(https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-beans) 可以实现「Get」方法时参数去除空格:

只不过这个editor确实没有注册,需要手工注册。

@ControllerAdvice
public?class?GlobalControllerAdiviceController?{
????//WebDataBinder是用来绑定请求参数到指定的属性编辑器,可以继承WebBindingInitializer
????//来实现一个全部controller共享的dataBiner?Java代码
????@InitBinder
????public?void?dataBind(WebDataBinder?binder)?{
????????///注册
????????binder.registerCustomEditor(String.class,?new?StringTrimmerEditor(true));
????}
}

注意,StringTrimmerEditor构造方法中有一个参数,如果传入true,则会将空白转换为null. 这样前面写的StringEditor就不用了,spring 已经帮我们写好了。

对于「Post」报文体来说,实际上我只需要改变的是「Jackson ObjectMapper」,不需要自定义整个MappingJackson2HttpMessageConverter ,只需要自定义Jackson ObjectMapper.百度了一下,果然有同学已经有了解决方案:

@Bean
public?Jackson2ObjectMapperBuilderCustomizer?jackson2ObjectMapperBuilderCustomizer()?{
????return?new?Jackson2ObjectMapperBuilderCustomizer()?{
????????@Override
????????public?void?customize(Jackson2ObjectMapperBuilder?jacksonObjectMapperBuilder)?{
????????????jacksonObjectMapperBuilder
????????????????????.deserializerByType(String.class,?new?StdScalarDeserializer(String.class)?{
????????????????????????@Override
????????????????????????public?String?deserialize(JsonParser?jsonParser,?DeserializationContext?ctx)
????????????????????????????????throws?IOException?{
????????????????????????????//?重点在这儿:如果为空白则返回null
????????????????????????????String?value?=?jsonParser.getValueAsString();
????????????????????????????if?(value?==?null?||?"".equals(value.trim()))?{
????????????????????????????????return?null;
????????????????????????????}
????????????????????????????return?value;
????????????????????????}
????????????????????});
????????}
????};
}

把上面的自定义StringDescrializer和MappingJackson2HttpMessageConverter去掉, 只保留上面的就行。

后记

好多问题,其实spring 都已经提供了解决方案,但是spring体系目前太庞大了,所以好多API和功能都不为人知。所以碰上问题就记录下来是个很好的习惯

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/1667.html

标签: objectmapper
分享给朋友:

“SpringBoot项目:接口参数空白值如何替换为null值” 的相关文章

总结了Vue3的七种组件通信方式,别再说不会组件通信了

写在前面本篇文章是全部采用的<script setup>这种组合式API写法,相对于选项式来说,组合式API这种写法更加自由,具体可以参考Vue文档对两种方式的描述。本篇文章将介绍如下七种组件通信方式:propsemitv-modelrefsprovide/injecteventBusv...

vue中如何在自定义组件上使用v-model和.sync

自定义事件tips推荐始终使用 kebab-case 的事件名。(v-on会将事件名自动转换为小写,避免匹配不到)changeData ×change-data √自定义组件的v-model用法:父组件定义数据源(不需要定义修改数据的方法),在子组件标签上通过v-model="data...

Windows 下 Git 拉 Gitlab 代码

读者提问:『阿常你好,Windows 下 Git 拉 Gitlab 代码的操作步骤可以分享一下吗?』阿常回答:好的,总共分为五个步骤。一、Windows 下安装 Git官网下载链接:https://git-scm.com/download/winStandalone Installer(安装版)注意...

「Git迁移」三行命令迁移Git包含提交历史,分支,tag标签等信息

问题描述:公司需要将一个git远程服务器的全部已有项目迁移到一台新服务器的Gitlab中,其中需要包含全部的提交纪录,已有的全部分支与全部打tag标签,目前此工作已全部迁移完毕,特此记录一下操作步骤环境描述:1. 要迁移的远程Git:Gitblit2. 迁移目的Git:Gitlab3. 暂存代码的P...

再来一波黑科技工具,低调使用

静读天下静读天下是一个特别优秀的电子书阅读器。它上面有多个在线书库,像古登堡计划,很多种优秀的书杂志,都可以下载来阅读。它还能智能识别章节功能,还支持外置的语音阅读功能。它支持多种文本格式,比如说txt,pdf,epub,mobi等等。为了便于阅读它还有10 种配色方式,还有夜间模式。不过免费版有广...

虚幻引擎5.5现已发布 手游开发、动画制作重大改进

Epic在今天发布了虚幻引擎5.5,现可通过Epic Launcher下载。此版本在动画创作、渲染、虚拟制片、移动端游戏开发和开发人员迭代工具集等方面做出了重大改进。 官方博客:虚幻引擎5.5现已发布,在动画创作、虚拟制作和移动游戏开发方面取得了显著进步,渲染、摄像机内视觉特效和开发人员迭代等领域的...