Spring @InitBinder не вызывается при отображении формы => Пользовательские редакторы не определены - PullRequest
0 голосов
/ 14 апреля 2010

У меня есть следующий (упрощенный до костей) контроллер:

@Controller  
public class TestController  {

@RequestMapping(value = "/test.htm", method = RequestMethod.GET)
public String showForm(final ModelMap map) {
    final TestFilter filter = new TestFilter();
    filter.setStartDate(new Date(System.currentTimeMillis()));
    map.addAttribute("reportPerResourceForm", filter);
    return "test";
}

@InitBinder
public void initBinder(final WebDataBinder binder) {
    binder.registerCustomEditor(Date.class, null, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true));
}

}

JSP:

<form:form commandName="reportPerResourceForm" id="reportForm">
    <form:input path="startDate" />
</form:form>

Это контроллер, который я быстро создал, чтобы проверить проблему с другим view-контроллером. Как вы можете видеть в Controller, определяется CustomeDateEditor. В моем реальном контроллере этот редактор работает нормально; когда вы вводите, например, 01.11.2010 в поле формы, редактор корректно преобразует его в дату; также при возвращении к форме Дата снова была преобразована обратно в строку.

Однако, когда я (как в TestController) хочу установить в форме дату по умолчанию, тогда просто отображается Date.toString () в поле формы вместо использования возвращаемого значения из CustomDateEditor.getAsText ()! После некоторой отладки я узнал, что мой метод InitBinder не вызывается, когда RequestMethod == GET. Это нормально?

Я уверен, что мог бы обойти это, не используя

Спасибо за вашу помощь,
Стейн

Ответы [ 3 ]

2 голосов
/ 28 декабря 2010

используйте @ModelAttribute для настройки домена перед пересылкой на страницу.

осторожно использовать new, когда вы имеете дело с пружиной, он просто создаст новый экземпляр объекта вне контекста пружины, и вы не сможете использовать какие-либо возможности пружины (такие как привязка к сети, проверка и т. Д.).

пример:

@RequestMapping(value = "/test.htm", method = RequestMethod.GET)
public String showForm(@ModelAttribute yourDomain, final ModelMap map)

и на вашем домене вы можете использовать:

@DateTimeFormat(pattern="dd/MM/yyyy")
private Date balance = new Date(System.currentTimeMillis());
1 голос
/ 15 апреля 2010

Я не уверен, но второй аргумент в методе registerCustomEditor имеет значение null. Этот аргумент предназначен для установки имени поля, с которым вы хотите связать редактор, поэтому я не знаю точно, что это произойдет, когда для него установлено значение null. Если вы хотите использовать этот редактор со всеми полями определенного типа, существует тот же метод без этого параметра:

public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor)

Я бы попробовал с этим, хотя я не уверен, что это решит проблему.

binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true));

Надеюсь, это поможет.

0 голосов
/ 15 сентября 2011

Чтобы решить эту проблему, я сам имею следующий код в моем контроллере:



        @InitBinder
        public void initBinder(WebDataBinder binder) {
            binder.registerCustomEditor(Category.class, new CategoryEditor(categoryService));
        }

        @ModelAttribute("categoryList") // Populate reference-data (EG select-lists) in the view. (p. 390-

    391).
        public List<Category> populateCategoryList() {
            return categoryService.list();
        }

        // Note: without adding "BindingResult result" to the following prototype
        // (and preceding it with a @ModelAttribute("categoryList") -
        // my initBibder() method does not get called!
        // I discovered and added this hokum in response to the following links:
        // http://forum.springsource.org/showthread.php?46837-InitBinder-not-called
        // http://forum.springsource.org/showthread.php?46876-Custom-date-format-on-GET-requests&p=154820
        @RequestMapping("/site/list.htm")
        @ModelAttribute("sites")  // 20110819
        public ModelAndView listSite(
                @ModelAttribute("category") Category category,
                BindingResult result
                )
        {
    //        List<Site> sites = siteService.list();
            List<Site> sites = new ArrayList<Site>(); // = siteService.list();
            return new ModelAndView("siteList", "sites", sites);
        }
    }


Мои проблемы были с тем, что мой класс "Category" не был распознан, потому что @InitBinder не вызывался. «Секрет» заключался в том, чтобы изменить мой метод «@RequestMapping», чтобы включить - в его прототип - 2 параметра который мне не нужен
@ModelAttribute ("category") Категория категории,
BindingResult результат
Это решило все (я знаю, что это не волшебство, просто дым, зеркала и отражение Java - но я желаю в печатной и онлайновой литературе будут рассмотрены простые варианты использования, подобные этому).

Вот соответствующий код в моем соответствующем файле JSP:



        <div>
        Select a category: 
        <form:select path="category">
                    <form:options items="${categoryList}" itemValue="id" itemLabel="name" 

    />
        </form:select>
        </div>

...