Spring MVC - привязка поля даты - PullRequest
43 голосов
/ 14 сентября 2010

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

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

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

Спасибо!

Ответы [ 2 ]

63 голосов
/ 14 сентября 2010

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

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.Date не знает, что такое 13/09/2010, поэтому вы говорите Весна

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());
    }        

});

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

Пружина 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
}
31 голосов
/ 27 декабря 2012

В дополнение к очень полному ответу Артура: в случае простого поля 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...