Date type of data binding in Spring MVC
Data Binding is one of the features of Spring MVC ~ It is easy to use and powerful, greatly simplifying the receipt and conversion of user input data by our programmers.
In earlier versions of Spring, data binding is based entirely on PropertyEditor. Converter is introduced in Spring3 to replace PropertyEditor for type conversion.
In this order, let's talk about how to bind date data based on the traditional PropertyEditor.
In Spring MVC, we can use WebDataBinder to register a custom PropertyEditor and add the corresponding request parameter binding. There are two methods:
1. Use the @ InitBinder annotation in @ Controller. 2. Customize WebBindingInitializer to provide a global data binding rule.
1. Use the @ InitBinder Annotation
@InitBinderpublic void initBinder(WebDataBinder binder){binder.registerCustomEditor(Date.class, new DateEditor());}
public class DateEditor extends PropertyEditorSupport {@Overridepublic void setAsText(String text) throws IllegalArgumentException {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = null;try {date = format.parse(text);} catch (ParseException e) {format = new SimpleDateFormat("yyyy-MM-dd");try {date = format.parse(text);} catch (ParseException e1) {e1.printStackTrace();}}setValue(date);}}
Here we will encapsulate DateEditor into a class to facilitate reuse.
In addition, there is a try... the catch function is to parse user input parameters in the form of "yyyy-MM-dd HH: mm: ss, if the resolution fails, it is resolved in the form of "yyyy-MM-dd. This logic can process date data in the format of "yyyy-MM-dd HH: mm: ss" and "yyyy-MM-dd" at the same time, I think in general Chinese systems, these two forms should be the most commonly used.
After the preceding code is added, the Controller of @ InitBinder can automatically bind data of the date type. However, this only takes effect in the Controller. To make it take effect globally, you can define the Controller where the @ InitBinder annotation is located as a BaseController, and other controllers inherit the Controller. Of course, there are other methods. If you are interested, please refer to 2.
2. Customize WebBindingInitializer
public class MyWebBindingInitializer implements WebBindingInitializer {@Overridepublic void initBinder(WebDataBinder binder, WebRequest request) {binder.registerCustomEditor(Date.class, new DateEditor());}}
The DateEditor was written earlier. We met again so quickly, but the registration location changed. The PropertyEditor registered in WebBindingInitializer is shared globally.
However, it is not enough to inject WebBindingInitializer into AnnotationMethodHandlerAdapter.
If you use The above configuration does not work, and the mvc namespace does not provide such fine-grained configuration. What should I do?
Don't be afraid. There are still some methods. We can use a custom PostBeanProcessor to handle them:
@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {if (bean instanceof RequestMappingHandlerAdapter) {RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean;adapter.setWebBindingInitializer(new MyWebBindingInitializer());}return bean;}
But actually By default, we provide a WebBindingInitializer -- ConfigurableWebBindingInitializer
The above method will overwrite the default ConfigurableWebBindingInitializer. In fact, we can directly use this Bean to register our PropertyEditor:
@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {if(bean instanceof ConfigurableWebBindingInitializer){ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) bean;initializer.setPropertyEditorRegistrar(new PropertyEditorRegistrar() {@Overridepublic void registerCustomEditors(PropertyEditorRegistry registry) {registry.registerCustomEditor(Date.class, new DateEditor());}});}return bean;}
It should be noted that in WebBindingInitializer, not only PropertyEditor can be registered, but Converter can also be registered, that is, the following 3
3. Use ConverstionService
Spring3 introduces the Converter system, while ConversionService is a Facade class that encapsulates underlying implementations and provides convenient type conversion. So here we cannot reuse the DateEditor between them, but the general logic is the same. In addition, Converter PROCESSES conversions between any two types, while Formatter processes conversions between strings and other types. It can be seen that Formatter is a special Converter and is more suitable for processing data binding than Converter. So here we will use Formatter to do:
public class DateFormatter implements Formatter
{@Overridepublic String print(Date object, Locale locale) {return null;}@Overridepublic Date parse(String text, Locale locale) throws ParseException {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = null;try {date = format.parse(text);} catch (Exception e) {format = new SimpleDateFormat("yyyy-MM-dd");date = format.parse(text);}return date;}}
Here we only write the logic from String to Date. Register DateFormatter to a ConversionService, and then register ConversionService to Spring MVC.
If you use As simple:
Not used You need to define a WebBindingInitializer (or use ableablewebbindinginitializer) and inject it into RequestMappingHandlerAdapter:
At this point, someone may ask, if both PropertyEditor and ConversionService are used, what is the execution order? Internally, find the PropertyEditor for type conversion. If the corresponding PropertyEditor is not found, convert it through ConversionService.
4. Automatic Registration of PropertyEditor
By the way, I will mention the automatic registration of PropertyEditor here. I only need to put the JavaBean and JavaBean names + Editor classes under the same package, then the basic structure of the JavaBeans will automatically find the PropertyEditor class, you do not need to register manually ~