Spring 5 Binder, @InitBinder, неправильное заполнение модели

Я обновляю веб-приложение Spring 2.5 до Spring 5.0.3. Я использую теги строковой формы. В моем контроллере есть:

@InitBinder
public void initBinder(WebDataBinder binder, HttpServletRequest request) {

    CapTypeEditor capTypeEditor = new CapTypeEditor(this.getDAOFactory());
    binder.registerCustomEditor(CapType.class, "order.capType.id", capTypeEditor);
}

Я вижу, что это вызывается дважды (почему?) При GET и дважды при POST. В GET request.getParameter ("order.capType.id") имеет значение null, то же самое в POST имеет правильный идентификатор. Но тогда в моем методе POST submit () capType не равен нулю, но у него заполнен только идентификатор, а не его имя:

@RequestMapping(value = "/es/orderinfo.html", method=RequestMethod.POST)
public ModelAndView submit(@RequestParam("id") long id,
        @ModelAttribute("command")OrderInfoBean bean, 
          BindingResult errors, ModelMap model,
          HttpServletRequest request) { 


    Order order = bean.getOrder();
    CapType ct = order.getCapType();
...
}

Мой редактор CapType никогда не вызывается:

public class CapTypeEditor extends PropertyEditorSupport {

DAOFactory daoFactory;

public CapTypeEditor(DAOFactory daoFactory){
    this.daoFactory = daoFactory;       
}

public void setAsText(String text){
    if (StringUtils.isBlank(text)||StringUtils.isEmpty(text) ){
        this.setValue(null);
        return;
    }
    Long id = Long.valueOf(text);
    CapType capType = daoFactory.getCapTypeDAO().read(id);
    this.setValue(capType);
}

public String getAsText(Object value){
    if (value == null) return StringUtils.EMPTY;
    CapType capType  = (CapType)value;
    return capType.getId().toString();
}
}

Мой JSP выглядит так:

<form:select path = "order.orderType.id" tabindex = "100" cssStyle = "width:149px">
    <form:option value = "">none</form:option>
    <form:options items = "${refData.orderTypes }" itemValue = "id" itemLabel = "typeName" />                                 
</form:select>
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
142
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы указываете неверный путь к свойству при регистрации настраиваемого редактора. Сделай это:

binder.registerCustomEditor(CapType.class, "capType", capTypeEditor);

Предположим, OrderInfoBean содержит поле capType.

binder.registerCustomEditor(CapType.class, "order.capType", capTypeEditor);

Как OrderInfoBean, так и Order, содержащий CapType.

А в JSP используйте capTypeorder.capType непосредственно как путь привязки.

Хорошо, я собираюсь попробовать это сейчас ... ... в моем приложении Spring 2.5 был командный класс OrderInfoBean, который имел (много свойств и) Order с CapType. Но нет сомнений, я собираюсь попробовать то, что вы думаете о том, где Order - это моя модель, а jsp <form: select path> - это просто capType или capType.id .... Будем следить за ним.

tom 27.10.2018 17:53

@tom Если это похоже на OrderInfoBean -> Order -> CapType, вам нужно сделать это: binder.registerCustomEditor(CapType.class, "order.capType", capTypeEditor);

Minar Mahmud 27.10.2018 17:57

спасибо @minarmahmud. попробую ... все еще нормально иметь JSP <form: select path = "order.capType.id">? Мне пришлось сделать это, чтобы выбрать значения по умолчанию, см. stackoverflow.com/questions/53016491/…

tom 27.10.2018 21:24

@tom Для работы редактора свойств необходимо сделать: <form:select path = "order.capType"> (без id)

Minar Mahmud 28.10.2018 06:29

интересно @minarmahmud. возможно, вы можете помочь мне с stackoverflow.com/questions/53016491/… ... без идентификатора значения в форме: select не выбраны для текущих значений в модели.

tom 28.10.2018 17:40

согласно этому сообщению ankeetmaini.wordpress.com/2012/08/01/…, с весны 3 возникла необходимость сопоставить JSP <form: select path> с идентификатором объекта ... странно, что я не могу вызвать свои старые редакторы или предлагаемые средства форматирования .. ..

tom 28.10.2018 19:56
Ответ принят как подходящий

На самом деле мои старые редакторы, зарегистрированные в @InitBinder, были в порядке. И @minarmahmud был прав насчет того, что у .id не было .id в. Как только я добавил правильную функцию equals и hashcode в мои классы моделей с отображением в спящем режиме (например, CapType), все заработало, как значения по умолчанию в представлении HTML, так и полное автоматическое сопоставление моих моделей вместе в POST. Итак, в Model CapType:

@Override
public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    final CapType capType = (CapType) o;
    return Objects.equals(id, capType.id) &&
    Objects.equals(typeName, capType.getTypeName());
}
@Override
public int hashCode() {
    return Objects.hash(id, typeName);
}

Другие вопросы по теме