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

Преобразование из String в пользовательский объект для Spring Форма MVC привязка данных?

Я использую Spring MVC SimpleFormController в сочетании с формой Spring MVC JTL, чтобы создать форму для редактирования универсального объекта.

В моей форме у меня есть раскрывающийся список, где пользователь может указать сервер через выпадающее меню.

<form:form commandName="generic">
    <form:select path="server">
        <form:options items="${servers}" itemValue="id" itemLabel="name"/>
    </form:select>
</form:form>

Здесь серверы распространяются вызовом базы данных для всех доступных серверов. сервер является ORM-сервером ORM, который является под-объектом другого ORM pojo (Generic), который служит в качестве объекта поддержки формы.

Моя цель здесь - изменить ссылку на общий сервер, которая представлена ​​на уровне базы данных в качестве внешнего ключа для таблицы сервера.

Я использую JPA как мой уровень персистентности и JPA сгенерированные классы сущностей в качестве моих ORM pojos.

К сожалению, это не похоже на обязательную привязку, когда моя форма отправляется, поскольку она не может переводить из String в Server.

Field error in object 'generic' on field 'server': rejected value [1]; codes [typeMismatch.generic.server,typeMismatch.server,typeMismatch.com.generic.orm.jpa.Server,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [generic.server,server]; arguments []; default message [server]]; default message [Failed to convert property value of type [java.lang.String] to required type [com.generic.orm.jpa.Server] for property 'server'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [com.generic.orm.jpa.Server] for property 'server': no matching editors or conversion strategy found], generic=com.generic.orm.jpa.generic[id=3]} and static attributes {}

Я искал пример того, как это сделать без везения. Я считаю, что мне нужно перезаписать что-то в SimpleFormController, как это было в этом вопросе, но Spring документация MVC освещена в деталях. Может ли кто-нибудь помочь мне здесь?

4b9b3361

Ответ 1

Я думаю, что ты прав. Вам необходимо зарегистрировать собственный редактор на вставке, как и раньше, чтобы преобразовать экземпляр String в экземпляр сервера. Ниже приведен пример пользовательского PropertyEditor здесь в справочных документах Spring, которые должны вас запустить.

Я согласен с тем, что документация MVC не самая лучшая. Мне пришлось делать много Googling и искать на форумах Spring.

Ответ 2

Как дополнение к отвечу Марка, вот что я сделал в своем контроллере.

@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
    binder.registerCustomEditor(Server.class, "serverId", new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            Server type = (Server) em.createNamedQuery("Server.findById")
                .setParameter("id", Short.parseShort(text)).getSingleResult();
            setValue(type);
        }
    });
}

Вы также можете сделать это, используя Spring инъекцию, в отличие от анонимных классов. Это указано ссылкой в ответе Марка.

Вы также можете расширить ClassEditor (см. ниже) вместо PropertyEditorSupport. Состояние Javadoc:

Редактор свойств для java.lang.Class, чтобы включить прямую совокупность свойства класса, не прибегая к использованию свойства имени класса String в качестве моста.

Не знаю, полностью ли я понимаю это преимущество, но что-то, о чем нужно помнить.

Полезные Javadocs

Ответ 3

Использование "server.id" может быть возможным решением. Таким образом, spring автоматически связывает выбранное значение или наоборот.

<form:form commandName="generic">
    <form:select path="server.id">
        <form:options items="${servers}" itemValue="id" itemLabel="name"/>
    </form:select>
</form:form>

Ответ 5

Аннотационная версия ответа в вашем контроллере:

@org.springframework.web.bind.annotation.InitBinder("yourFormName")
protected void initBinder(
             org.springframework.web.bind.WebDataBinder binder) {
    binder.registerCustomEditor(Server.class, "serverId", new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            Server s = ...; // do whatever needed to convert
            setValue(s);
        }
    });