Spring MVC, один контроллер для «добавления» и «обновления» при использовании setDisallowedFields? - PullRequest
3 голосов
/ 05 мая 2009

Итак, у меня есть простая форма, с помощью которой я могу либо «добавить» новую вещь, либо «обновить» существующую вещь.

Я хотел бы иметь один контроллер, который может обрабатывать как добавление, так и обновление. Вначале это кажется достаточно простым, пока я не рассмотрю проблему использования setDisallowedFields в моем InitBinder, так что поле "id" не допускается при добавлении нового Thing.

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

Есть предложения или советы? (Я открыт для аргумента, что я должен также поддерживать два контроллера, если вы можете дать мне веские причины)

Ответы [ 3 ]

3 голосов
/ 11 февраля 2010

На самом деле, вы должны запретить поле "id" как при добавлении, так и при обновлении. В противном случае злоумышленник может изменить значение параметра запроса «id» в запросе на обновление и тем самым обновить другую запись, указанную в форме (при условии, что ACL-списки или другая защита на уровне домена) отсутствуют.

Однако, если вы просто запретите поле «id», контроллер будет обрабатывать идентификатор как нулевой, который будет работать при вставке, но не при обновлении (например, он может попытаться вставить новую запись вместо обновления, в зависимости от того, что механизм персистентности вы используете). Таким образом, вы хотите, чтобы контроллер запоминал не редактируемые значения вашего объекта домена (не только идентификаторы, но все запрещенные поля) между запросами, чтобы он мог отправлять все правильные значения на уровень обслуживания или другую бизнес-логику. Это делается с помощью аннотации @SessionAttributes уровня типа следующим образом (другие аннотации для ясности опущены):

@SessionAttributes("thing") // the name of your domain object in the model
public class ThingController {

    public void setDisallowedFields(WebDataBinder binder) {
        binder.setDisallowedFields("id", "someOtherUneditableField");
    }

    // request handling methods go here as before
}

Для еще большей безопасности установите разрешенные поля, а не запрещенные. В любом случае вам нужна аннотация @SessionAttributes для заполнения любых существующих значений полей, игнорируемых в запросе.

2 голосов
/ 05 мая 2009

Подпись метода к initBinder принимает HttpServletRequest:

protected void initBinder(HttpServletRequest request, 
    ServletRequestDataBinder binder)

Так что, возможно, вы можете initBinder() проверить параметры запроса, чтобы определить, следует ли вам условно установить setDisallowedFields?

(Если это не поможет, возможно, я неправильно понимаю проблему ...)

1 голос
/ 06 мая 2009

Способ, которым я делаю это с одним контроллером, заключается в том, чтобы на моем объекте команды было указано логическое значение, указывающее, является ли это новым объектом или нет. Затем в onSubmit я могу проверить логическое значение, чтобы узнать, нужно ли мне выполнить действие добавления или обновления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...