Spring MVC, генерируя объект поддержки формы от запроса?

Исходя из того, что я понял, вот один из способов сделать это

select c.id customer_id, c.sur, c.fam, h.id horoscope_id, h.sur h_sur, 
h.fam h_fam, h.horoscope
FROM customer c join horoscope h
on (c.sur = h.sur and c.fam = h.fam)
or (h.sur is null and c.fam = h.fam and not exists 
      (select 1 from horoscope h1 where h1.sur = c.sur and h1.fam = c.fam)
   )


и результат

enter image description here

5
задан James McMahon 30 March 2009 в 17:40
поделиться

4 ответа

Один из основных недостатков использования Spring MVC + hibernate заключается в том, что естественным подходом является использование объекта домена hibernate в качестве объекта поддержки формы. Spring свяжет что-либо в запросе на основе имени DEFAULT. Это непреднамеренно включает такие вещи, как идентификатор или имя (обычно первичный ключ) или другие устанавливаемые свойства спящего режима. Это также делает вас уязвимыми для внедрения формы.

Чтобы быть в безопасности в этом сценарии, вы должны использовать что-то вроде:

protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) 
throws Exception {
 String[] allowedFields = {"name", "birthday"}
 binder.setAllowedFields(allowedFields);
}

и ЯВНО установите РАЗРЕШЕННЫЕ поля только на те, которые находятся в вашей форме, и исключите первичный ключ, иначе вы будете кончится беспорядком !!!

6
ответ дан 18 December 2019 в 14:51
поделиться

Ваша проблема может быть связана с Отделенными объектами. Поскольку Ваш ДАО был изменен вне Быть в спящем режиме сессии, необходимо повторно прикрепить объект к Быть в спящем режиме сессии перед сохранением. Можно сделать это любой путем явного обеспечения объекта в сессию прежде, чем сохранить Слияние использования () или обновление (). Эксперимент с обоими, и прочитал документацию для тех действий, поскольку они имеют различные эффекты в зависимости от структуры Ваших объектов данных.

1
ответ дан 18 December 2019 в 14:51
поделиться

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

  1. Каждый В спящем режиме, сессия открыта (давайте назовем ее сессией A) в formBackingObject
  2. Используя сессию A, Вы загружаете объект Штуки в formBackingObject
  3. Вы возвращаете объект Штуки как результат formBackingObject
  4. При возврате объекта Штуки сеанс A закрыт, но Штука все еще связана с ним
  5. Когда doSubmitAction назван, тот же экземпляр Thingie поддержка объекта передается как команда
  6. Новое В спящем режиме сессия (назовите ее сессией B), открыт
  7. Вы пытаетесь сохранить объект Штуки (первоначально открытый с сессией A) использование сессии B

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

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

Похоже, что у Вас уже есть образцовый класс для Вашей записи; я назову это Record класс в этом ответе). У Вас также есть ДАО для Record класс, который я назову RecordDao. Наконец, Вам нужен a UpdateRecordCommand класс, который будет Вашим объектом поддержки. UpdateRecordCommand должен быть определен со следующими полями и методами set/методами считывания:

public class UpdateRecordCommand {
  // Row ID of the record we want to update
  private int rowId;
  // New name
  private int String name;
  // New scheme
  private int String scheme;
  // New URL
  private int String url;
  // New enabled flag
  private int boolean enabled;

  // Getters and setters left out for brevity
}

Затем определите свою форму с помощью следующего кода:

<form:form commandName="update">
  <span>Name:</span>
  <span><form:input path="name" /></span><br/>
  <span>Scheme:</span>
  <span><form:input path="scheme" /></span><br/>
  <span>Url:</span>
  <span><form:input path="url" /></span><br/>
  <span>Enabled:</span>
  <span><form:checkbox path="enabled"/></span><br/>
  <form:hidden path="rowId"/>
  <input type="submit" value="Save Changes" />
</form:form>

Теперь Вы определяете свой контроллер формы, который заполнит форму в formBackingObject и обработайте запрос обновления в doSubmitAction.

public class UpdateRecordController extends SimpleFormController {

  private RecordDao recordDao;

  // Setter and getter for recordDao left out for brevity

  public UpdateRecordController() {    
      setCommandClass(UpdateRecordCommand.class);
      setCommandName("update");
  }

  @Override
  protected Object formBackingObject(HttpServletRequest request)
      throws Exception {
    // Use one of Spring's utility classes to cleanly fetch the rowId
    int rowId = ServletRequestUtils.getIntParameter(request, "rowId");

    // Load the record based on the rowId paramrter, using your DAO
    Record record = recordDao.load(rowId);

    // Populate the update command with information from the record
    UpdateRecordCommand command = new UpdateRecordCommand();

    command.setRowId(rowId);
    command.setName(record.getName());
    command.setScheme(record.getScheme());
    command.setUrl(record.getUrl());
    command.setEnabled(record.getEnabled());

    // Returning this will pre-populate the form fields
    return command;
  }

  @Override
  protected void doSubmitAction(Object command) throws Exception {
    // Load the record based on the rowId in the update command
    UpdateRecordCommand update = (UpdateRecordCommand) command;
    Record record = recordDao.load(update.getRowId());

    // Update the object we loaded from the data store
    record.setName(update.getName());
    record.setScheme(update.getScheme());
    record.setUrl(update.getUrl());
    record.setEnabled(update.setEnaled());

    // Finally, persist the data using the DAO
    recordDao.save(record);
  }
}
5
ответ дан 18 December 2019 в 14:51
поделиться

Что продолжалось, который является? name=rowId так или иначе портил сообщение формы. После того как я изменил это на имя, которое не отразило параметр в объекте, все хорошо работало. Никакое изменение в ДАО или необходимом коде контроллера.

Благодаря всем для Ваших ответов. Это помогло мне сузить то, что продолжалось.

1
ответ дан 18 December 2019 в 14:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: