SpringMVC空字符串转为null
空字符串转为null
现在我遇到这样一个需求,那就是我想要吧前端传过来的值变为空,因为所谓前端的校验,其实都不是校验,如果前端传给后台一个表单,可是表单未填入值,我们后台进行判断的时候 既需要判断null,同时需要判断是否为""
, 并且如果你不希望数据库插入的是空字符串,而是null
,那么转换和插入的就很麻烦
if (manager.getUsername().equals("") || manager.getUsername() == null) {
throw new ErrorException("用户名未填写");
}
if (manager.getPassword().equals("") || manager.getPassword() == null) {
throw new ErrorException("密码未填写");
}
可是如果你在SpringMVC进行参数赋值处理之前就能把""
转换为null
,那么你就只需要进行如下判断,并且插入数据库的一直是空值
if (manager.getUsername() == null) {
throw new ErrorException("用户名未填写");
}
if (manager.getPassword() == null) {
throw new ErrorException("密码未填写");
}
实现方式
- 可以使用过滤器/拦截器把空字符串设置成null(未尝试)
- 注册一个SpringMVC
HandlerAdapter
来进行处理
使用SpringMVC时,所有的请求都是最先经过DispatcherServlet的,然后由DispatcherServlet选择合适的HandlerMapping和HandlerAdapter来处理请求,HandlerMapping的作用就是找到请求所对应的方法,而HandlerAdapter则来处理和请求相关的的各种事情。我们这里要讲的请求参数绑定也是HandlerAdapter来做的。
参数处理器
我们需要写一个自定义的请求参数处理器,然后把这个处理器放到HandlerAdapter中,这样我们的处理器就可以被拿来处理请求了。
public class EmptyStringToNullModelAttributeMethodProcessor extends ServletModelAttributeMethodProcessor implements ApplicationContextAware {
ApplicationContext applicationContext;
public EmptyStringToNullModelAttributeMethodProcessor(boolean annotationNotRequired) {
super(annotationNotRequired);
}
@Override
protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
EmptyStringToNullRequestDataBinder toNullRequestDataBinderBinder = new EmptyStringToNullRequestDataBinder(binder.getTarget(), binder.getObjectName());
RequestMappingHandlerAdapter requestMappingHandlerAdapter = applicationContext.getBean(RequestMappingHandlerAdapter.class);
requestMappingHandlerAdapter.getWebBindingInitializer().initBinder(toNullRequestDataBinderBinder, request);
toNullRequestDataBinderBinder.bind(request.getNativeRequest(ServletRequest.class));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
DataBinder
继承自ExtendedServletRequestDataBinder
,主要用来自定义数据绑定处理
public class EmptyStringToNullRequestDataBinder extends ExtendedServletRequestDataBinder {
public EmptyStringToNullRequestDataBinder(Object target, String objectName) {
super(target, objectName);
}
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
super.addBindValues(mpvs, request);
for (PropertyValue propertyValue : mpvs.getPropertyValueList()) {
if (propertyValue.getValue().equals(""))
propertyValue.setConvertedValue(null);
}
}
}
注册器
话要从HandlerAdapter里系统自带的处理器说起。我这边系统默认带了24个处理器,其中有两个ServletModelAttributeMethodProcessor,也就是我们自定义处理器继承的系统处理器。SpringMVC处理请求参数是轮询每一个处理器,看是否支持,也就是supportsParameter方法, 如果返回true,就交给你出来,并不会问下面的处理器。这就导致了如果我们简单的把我们的自定义处理器加到HandlerAdapter的Resolver列中是不行的,需要加到第一个去。
public class EmptyStringToNullProcessorRegistry implements ApplicationContextAware, BeanFactoryPostProcessor {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
RequestMappingHandlerAdapter requestMappingHandlerAdapter = applicationContext.getBean(RequestMappingHandlerAdapter.class);
List<HandlerMethodArgumentResolver> resolvers = requestMappingHandlerAdapter.getArgumentResolvers();
List<HandlerMethodArgumentResolver> newResolvers = new ArrayList<HandlerMethodArgumentResolver>();
for (HandlerMethodArgumentResolver resolver : resolvers) {
newResolvers.add(resolver);
}
EmptyStringToNullModelAttributeMethodProcessor processor = new EmptyStringToNullModelAttributeMethodProcessor(true);
processor.setApplicationContext(applicationContext);
newResolvers.add(0, processor);
requestMappingHandlerAdapter.setArgumentResolvers(Collections.unmodifiableList(newResolvers));
}
}
XML配置
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="studio.geek.databind.EmptyStringToNullModelAttributeMethodProcessor">
<constructor-arg name="annotationNotRequired" value="true"/>
</bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
最后就可以完成将空字符串转为null
参考文档
SpringMVC空字符串转为null的更多相关文章
- Java空字符串与null的区别和判断字符串是否为空的方法
Java空字符串与null的区别: 1.类型null表示的是一个对象的值,而并不是一个字符串.例如声明一个对象的引用,String a = null ;""表示的是一个空字符串,也 ...
- Oracle坑之-空字符串与NULL
空字符串与NULL 首先有如下代码 SELECT * FROM Pdc_DataDomain DD INNER JOIN Pdc_DD_Table DDT ON DD.DataDomainID = D ...
- Java进阶(二十一)java 空字符串与null区别
java 空字符串与null区别 1.类型 null表示的是一个对象的值,而并不是一个字符串.例如声明一个对象的引用,String a = null ; ""表示的是一个空字符串, ...
- Access空字符串和Null值
什么是空字符串和Null值: Microsoft Access可以区分两种类型的空值.因为在某些情况下,字段为空,可能是因为信息目前无法获得,或者字段不适用于某一特定的记录.例如,表中有一个“电话号码 ...
- postgresql与Oracle:空字符串与null
空字符串:两个单引号,中间无空格等任何内容 在postgresql中,空字符串与null是不同的:而oracle中,空字符串与null等同.测试如下: postgresql中: postgres=# ...
- 3-java中String值为空字符串与null的判断方法
java中String值为空字符串与null的判断方法 2018年01月21日 14:53:45 阅读数:1189 Java空字符串与null的区别 1.类型 null表示的是一个对象的值,而不是一个 ...
- 解决CsvWriter:中文乱码、末尾行多一行空格(/r)、非第一列空字符串""显示null问题
一:主要内容 解决CsvWriter存csv,csv文件打开后中文乱码问题 解决CsvWriter存csv,csv文件最后一行总是多一行空行的问题 解决CsvWriter存csv,csv文件不是第一列 ...
- 空字符串(“”)和null和空格字符串(" ")的区别
1.类型 null表示的是一个对象的值,而并不是一个字符串.例如声明一个对象的引用,String a = null ;""表示的是一个空字符串,也就是说它的长度为0,但它是一个字符 ...
- vue 之 后端返回空字符串用 null 和 “”以及 undefind 判断不到的问题
原文: <!-- <span v-if="scope.row.buyer_credit_score != '' || scope.row.buyer_credit_score ! ...
随机推荐
- LVS集群ipvsadm命令和调度算法(6)
一.ipvsadm命令参考 为了更好的让大家理解这份命令手册,将手册里面用到的几个术语先简单的介绍一下: 术语解释: 1.virtual-service-address:是指虚拟服务器的ip地址2.r ...
- OGG的孩子-有损音频编码opus
Opus是一个有损声音编码的格式,由Xiph.Org基金会开发,之后由互联网工程任务组(IETF)进行标准化,目标用希望用单一格式包含声音和语音, 取代Speex和Vorbis,且适用于网络上低延迟的 ...
- VS工程中添加c/c++工程中外部头文件及库的基本步骤
转载自 在VS工程中,添加c/c++工程中外部头文件及库的基本步骤: 1.添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录. 2.添加 ...
- Python之排序算法:快速排序与冒泡排序
Python之排序算法:快速排序与冒泡排序 转载请注明源地址:http://www.cnblogs.com/funnyzpc/p/7828610.html 入坑(简称IT)这一行也有些年头了,但自老师 ...
- BZOJ:4827: [Hnoi2017]礼物
[问题描述] 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度. 但是在她生日的 ...
- hihoCoder #1053 : 居民迁移(贪心,二分搜索,google在线技术笔试模拟)
#1053 : 居民迁移 时间限制:3000ms 单点时限:1000ms 内存限制:256MB 描述 公元2411年,人类开始在地球以外的行星建立居住点.在第1326号殖民星上,N个居住点分布在一条直 ...
- [bzoj1369] [Baltic2003]Gem
结论题...一棵树里用到的颜色数不超过logn.. f[i][j]表示以i为根的子树里,i的颜色是j的方案数. g[i][j]表示max{f[i][k]},(k!=j #include<cstd ...
- java的finalize()方法与C++的析构函数
---<java编程思想> 读书笔记 --- 2017/3/15 读<java编程思想>读到初始化与清理一章,文中提及java的finalize()方法,联想到了C++的析构函 ...
- JXLS 2.4.0系列教程(二)——循环导出一个链表的数据
请务必先看上一篇文章,本文在上一篇文章的代码基础上修改而成. JXLS 2.4.0系列教程(一)--最简单的模板导出 上一篇文章我们介绍了JXLS和模板导出最简单的应用,现在我们要更进一步,介绍在模板 ...
- Linux文件链接hard link与symbolic link
Linux中文件链接有两种方式,一种是hard link,又称为硬链接:另一种是symbolic link,又称为符号链接.要区分两者的不同要回顾Linux常用的ext2文件系统.这种文件系统使用in ...