SpringMVC之繫結引數的型別轉換(Date/Double)
阿新 • • 發佈:2018-12-30
一、使用註解式控制器註冊PropertyEditor(針對具體的controller類處理)
1、使用WebDataBinder進行控制器級別的註冊PropertyEditor(控制器獨享)
Java程式碼- @InitBinder
- // 此處的引數也可以是ServletRequestDataBinder型別
- public void initBinder(WebDataBinder binder) throws Exception {
- // 註冊自定義的屬性編輯器
- // 1、日期
-
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"
- //CustomDateEditor類是系統內部自帶的類
- CustomDateEditor dateEditor = new CustomDateEditor(df, true);
- // 表示如果命令物件有Date型別的屬性,將使用該屬性編輯器進行型別轉換
- binder.registerCustomEditor(Date.class, dateEditor);
- // 自定義的電話號碼編輯器(和【4.16.1、資料型別轉換】一樣)
-
binder.registerCustomEditor(PhoneNumberModel.class
- }
備註:轉換物件必須要實現PropertyEditor介面,例如CustomDateEditor類
Java程式碼- package org.springframework.beans.propertyeditors;
- import java.beans.PropertyEditorSupport;
- import java.text.DateFormat;
- import java.text.ParseException;
- import java.util.Date;
-
import
- public class CustomDateEditor extends PropertyEditorSupport {
- private final DateFormat dateFormat;
- private final boolean allowEmpty;
- private final int exactDateLength;
- public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty) {
- this.dateFormat = dateFormat;
- this.allowEmpty = allowEmpty;
- exactDateLength = -1;
- }
- public CustomDateEditor(DateFormat dateFormat, boolean allowEmpty, int exactDateLength) {
- this.dateFormat = dateFormat;
- this.allowEmpty = allowEmpty;
- this.exactDateLength = exactDateLength;
- }
- public void setAsText(String text) throws IllegalArgumentException {
- if (allowEmpty && !StringUtils.hasText(text)) {
- setValue(null);
- } else {
- if (text != null && exactDateLength >= 0 && text.length() != exactDateLength)
- throw new IllegalArgumentException((new StringBuilder("Could not parse date: it is not exactly")).append(exactDateLength).append("characters long").toString());
- try {
- setValue(dateFormat.parse(text));
- } catch (ParseException ex) {
- throw new IllegalArgumentException((new StringBuilder("Could not parse date: ")).append(ex.getMessage()).toString(), ex);
- }
- }
- }
- public String getAsText() {
- Date value = (Date) getValue();
- return value == null ? "" : dateFormat.format(value);
- }
- }
二、使用xml配置實現型別轉換(系統全域性轉換器)
(1)註冊ConversionService實現和自定義的型別轉換器
Xml程式碼- <!-- ①註冊ConversionService -->
- <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
- <property name="converters">
- <list>
- <bean class="hb.base.convert.DateConverter">
- <constructor-arg value="yyyy-MM-dd"/>
- </bean>
- </list>
- </property>
- <!-- 格式化顯示的配置
- <property name="formatters">
- <list>
- <bean class="hb.base.convert.DateFormatter">
- <constructor-arg value="yyyy-MM-dd"/>
- </bean>
- </list>
- </property>
- -->
- </bean>
(2)使用 ConfigurableWebBindingInitializer 註冊conversionService
Xml程式碼- <!-- ②使用 ConfigurableWebBindingInitializer 註冊conversionService -->
- <bean id="webBindingInitializer"
- class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
- <property name="conversionService" ref="conversionService" />
- <property name="validator" ref="validator" />
- </bean>
(3)註冊ConfigurableWebBindingInitializer 到RequestMappingHandlerAdapter
Xml程式碼- <!--Spring3.1開始的註解 HandlerAdapter -->
- <bean
- class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
- <!--執行緒安全的訪問session -->
- <property name="synchronizeOnSession" value="true" />
- <property name="webBindingInitializer" ref="webBindingInitializer"/>
- </bean>
此時可能有人會問,如果我同時使用 PropertyEditor 和 ConversionService,執行順序是什麼呢?內部首先查詢PropertyEditor 進行型別轉換,如果沒有找到相應的 PropertyEditor 再通過 ConversionService進行轉換。
三、直接重寫WebBindingInitializer(系統全域性轉換器)
(1)實現WebBindingInitializer介面
package org.nercita.core.web.springmvc;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.core.convert.ConversionService;
import org.springframework.validation.BindingErrorProcessor;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.WebRequest;
/**
* Created by IntelliJ IDEA.
* Date:
* Time: 下午2:50.
*/
public class CustomBindInitializer implements WebBindingInitializer {
private String format = "yyyy-MM-dd";
private boolean autoGrowNestedPaths = true;
private boolean directFieldAccess = false;
private MessageCodesResolver messageCodesResolver;
private BindingErrorProcessor bindingErrorProcessor;
private Validator validator;
private ConversionService conversionService;
private PropertyEditorRegistrar[] propertyEditorRegistrars;
public void setAutoGrowNestedPaths(boolean autoGrowNestedPaths) {
this.autoGrowNestedPaths = autoGrowNestedPaths;
}
public boolean isAutoGrowNestedPaths() {
return this.autoGrowNestedPaths;
}
public final void setDirectFieldAccess(boolean directFieldAccess) {
this.directFieldAccess = directFieldAccess;
}
public boolean isDirectFieldAccess() {
return directFieldAccess;
}
public final void setMessageCodesResolver(MessageCodesResolver messageCodesResolver) {
this.messageCodesResolver = messageCodesResolver;
}
public final MessageCodesResolver getMessageCodesResolver() {
return this.messageCodesResolver;
}
public final void setBindingErrorProcessor(BindingErrorProcessor bindingErrorProcessor) {
this.bindingErrorProcessor = bindingErrorProcessor;
}
public final BindingErrorProcessor getBindingErrorProcessor() {
return this.bindingErrorProcessor;
}
public final void setValidator(Validator validator) {
this.validator = validator;
}
public final Validator getValidator() {
return this.validator;
}
public final void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
public final ConversionService getConversionService() {
return this.conversionService;
}
public final void setPropertyEditorRegistrar(PropertyEditorRegistrar propertyEditorRegistrar) {
this.propertyEditorRegistrars = new PropertyEditorRegistrar[]{propertyEditorRegistrar};
}
public final void setPropertyEditorRegistrars(PropertyEditorRegistrar[] propertyEditorRegistrars) {
this.propertyEditorRegistrars = propertyEditorRegistrars;
}
public final PropertyEditorRegistrar[] getPropertyEditorRegistrars() {
return this.propertyEditorRegistrars;
}
public void initBinder(WebDataBinder binder, WebRequest request) {
binder.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
SimpleDateFormat sf = new SimpleDateFormat(format);
sf.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(sf, true));
binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
binder.registerCustomEditor(Short.class, new CustomNumberEditor(Short.class, true));
binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, true));
binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, true));
binder.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, true));
binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class, true));
binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
binder.registerCustomEditor(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));
if (this.directFieldAccess) {
binder.initDirectFieldAccess();
}
if (this.messageCodesResolver != null) {
binder.setMessageCodesResolver(this.messageCodesResolver);
}
if (this.bindingErrorProcessor != null) {
binder.setBindingErrorProcessor(this.bindingErrorProcessor);
}
if ((this.validator != null) && (binder.getTarget() != null) &&
(this.validator.supports(binder.getTarget().getClass()))) {
binder.setValidator(this.validator);
}
if (this.conversionService != null) {
binder.setConversionService(this.conversionService);
}
if (this.propertyEditorRegistrars != null)
for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars)
propertyEditorRegistrar.registerCustomEditors(binder);
}
public void setFormat(String format) {
this.format = format;
}
}
(2)xml配置
<bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.nercita.core.web.springmvc.StringHttpMessageConverter" />
<ref bean="msgConverter"/>
</list>
</property>
<property name="webBindingInitializer">
<bean class="org.nercita.core.web.springmvc.CustomBindInitializer">
<property name="validator" ref="validator" />
<property name="conversionService" ref="conversionService" />
</bean>
</property>
</bean>