Преобразование из строки в пользовательский объект для формы Spring MVC Привязка данных? - PullRequest
22 голосов
/ 26 мая 2009

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

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

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

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

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

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

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

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 не содержит подробностей. Может ли кто-нибудь помочь мне здесь?

Ответы [ 5 ]

21 голосов
/ 28 мая 2009

Так же, как дополнение к ответу Марка, вот что я закончил делать в моем контроллере.

@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, чтобы включить прямое заполнение свойства Class без необходимости использовать свойство имени класса String в качестве моста.

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

Полезные Javadocs

18 голосов
/ 20 апреля 2012

Использование «server.id» может быть возможным решением. Поэтому пружина автоматически связывает выбранное значение или наоборот.

<form:form commandName="generic">
    <form:select path="server.id">
        <form:options items="${servers}" itemValue="id" itemLabel="name"/>
    </form:select>
</form:form>
5 голосов
/ 27 мая 2009

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

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

2 голосов
/ 30 января 2012
1 голос
/ 22 марта 2017

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

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