Вівторок, 1 вересня 2009 р.

Spring MVC: не очевидное

Есть ряд совершенно не очевидных вещей внутри Spring MVC, например
1) чтобы форма работала и обрабатывалась нормально нужно, чтобы у нее обязательно были прописаны id и name. и то, и другое, одновременно. иначе возможны сбои
2) чтобы механизм автоматического binding'а элементов формы работал, нужно, чтобы имена полей формы совпадали с именами полей класса, в который они байндятся. Т.е.

Java class:
public class BackingBean {
private long id;
private String name;

public void setId(long id) {
this.id = id;
}

public long getId() {
return id;
}

public void setName(String name) {
this.name = name;
}

public long get() {
return name;
}
}

JSP:
<form id="foo" name"foo" method="post" action="/somewhere-on-server">
<spring:bind path="backingBean.id">
<input type="text" name="id"/>
</spring:bind>
<spring:bind path="backingBean.name">
<input type="text" name="name"/>
</spring:bind>
</form>

5) метод formBackingObject всегда создает новый экземпляр объекта, если его перегрузить таким образом, чтобы он делал проверку наличия уже созданного объекта в аттрибутах запроса, это позволит уменьшить количество объектов в памяти и сократить время, необходимое для создания этого объекта
4) в Spring Portlet MVC метод onSubmitRender вызывается только в том случае, когда состояние формы было изменено. поэтому в этом методе нельзя реализовывать обработку RenderRequest's, общих для всего контроллера. для обработки общих запросов можно использовать методы showForm, handleRenderRequestInternal, handleRenderRequest
p.s. а в многом остальном Spring MVC прекрасен, как и весь Spring пожалуй

5 коментарі:

  1. 1. без ид формы все и так работает прекрасно
    2. это очевидно. вообще то имя поля здесь не причем. Все дело в именах методов.
    3. используйте сессионные контролы.

    ВідповістиВидалити
  2. 2. нет, это не очевидно, хотя бы потому, что есть тег <spring-bind>, который вобщем-то особенно ничего не делает. а так, конечно дело в commons-beanutils и логике этой либы по-умолчанию.
    3. прекрасный совет. неужели Вы думаете, что я пропустил главу про сессионные контролы? наверное, коль скоро я их не использую, они по какой-то причине мне не подходят.

    ВідповістиВидалити
  3. у меня к Вам вопрос:
    как мне вывести на форму поля вложенного объекта?
    например, есть два класса
    Person {
    Long id;
    String name;
    Address address;
    //setters and getters here
    }
    Address {
    Long id;
    String city;
    String street;
    //setters and getters here
    }

    и на форме должно быть:
    name -
    city -
    street -

    Помогите разобраться, буду очень благодарна :)

    ВідповістиВидалити
  4. @svetik, это очень просто, предположим, что объект Peson присутствует в определении Вашей формы как form object. тогда Ваши поля будут такие
    <form:input name="name"/>
    <form:input name="address.city"/>
    <form:input name="address.street"/>
    для объекта Person, который просто сохранен аттрибутом реквеста с именем, скажем, person, поля будут несколько другие
    <input name="name" value="${person.name}"/>
    <input name="address.city" value="${person.address.city}"/>
    <input name="address.street" value="${person.address.street}"/>;
    такова основная идея, разумеется имена полей и переменных могут быть другими.

    ВідповістиВидалити
  5. спасибо большое за помощь, заработало :)

    ВідповістиВидалити