空字元串轉為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對象綁定時自定義名稱對應關系
- SpringMVC源碼分析和一些常用最佳實踐