Подтвердить что ты не робот

Spring MVC - привязка поля даты

Для параметров запроса, представляющих строковые, числовые и логические значения, контейнер Spring MVC может связывать их с типизированными свойствами из коробки.

Как ваш контейнер Spring MVC связывает параметр запроса, представляющий дату?

Говоря о том, как MVC Spring определяет тип заданного параметра запроса?

Спасибо!

4b9b3361

Ответ 1

Как MVC Spring определяет тип данного параметра запроса?

Spring использует ServletRequestDataBinder для привязки его значений. Процесс можно описать следующим образом

/**
  * Bundled Mock request
  */
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("name", "Tom");
request.addParameter("age", "25");

/**
  * Spring create a new command object before processing the request
  *
  * By calling <COMMAND_CLASS>.class.newInstance(); 
  */
Person person = new Person();

...

/**
  * And Then with a ServletRequestDataBinder, it bind the submitted values
  * 
  * It makes use of Java reflection To bind its values
  */
ServletRequestDataBinder binder = ServletRequestDataBinder(person);
binder.bind(request);

За кулисами DataBinder экземпляры внутренне используют BeanWrapperImpl, который отвечает за настройку значений объекта команды. Используя метод getPropertyType, он получает тип свойства

Если вы видите представленный запрос выше (конечно, используя макет), Spring вызовет

BeanWrapperImpl beanWrapper = new BeanWrapperImpl(person);

Clazz requiredType = beanWrapper.getPropertyType("name");

И Затем

beanWrapper.convertIfNecessary("Tom", requiredType, methodParam)

Как контейнер Spring MVC связывает параметр запроса, представляющий дату?

Если у вас есть удобное для человека представление данных, которое требует специального преобразования, вы должны зарегистрировать PropertyEditor Например, java.util. Дата не знает, что такое 13/09/2010, поэтому вы скажете Spring

Spring, преобразуйте эту благоприятную для человека дату, используя следующий PropertyEditor

binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
    public void setAsText(String value) {
        try {
            setValue(new SimpleDateFormat("dd/MM/yyyy").parse(value));
        } catch(ParseException e) {
            setValue(null);
        }
    }

    public String getAsText() {
        return new SimpleDateFormat("dd/MM/yyyy").format((Date) getValue());
    }        

});

При вызове метода convertIfNecessary, Spring ищет любой зарегистрированный PropertyEditor, который выполняет преобразование представленного значения. Чтобы зарегистрировать свой PropertyEditor, вы можете либо

Spring 3.0

@InitBinder
public void binder(WebDataBinder binder) {
    // as shown above
}

Старый стиль Spring 2.x

@Override
public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
    // as shown above
}

Ответ 2

В дополнение к Артуру очень полный ответ: в случае простого поля Date вам не нужно реализовывать весь PropertyEditor. Вы можете просто использовать CustomDateEditor, к которому вы просто передаете формат даты для использования:

//put this in your Controller 
//(if you have a superclass for your controllers 
//and want to use the same date format throughout the app, put it there)
@InitBinder
private void dateBinder(WebDataBinder binder) {
            //The date format to parse or output your dates
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
            //Create a new CustomDateEditor
    CustomDateEditor editor = new CustomDateEditor(dateFormat, true);
            //Register it as custom editor for the Date type
    binder.registerCustomEditor(Date.class, editor);
}