Как передать идентификатор текущего пользователя, отображаемого на странице, в метод обработчика действий в JSF 2? - PullRequest
1 голос
/ 22 июля 2011

У меня есть страница JSF, на которой я показываю детали данного пользователя:

<h:form>

    <p>
    <h:outputLabel value="User Name" for="userName" />
    <h:outputText id="userName" value="#{userController.user.name}" />
    </p>

    <p>
    <h:outputLabel value="Email" for="email" />
    <h:outputText id="email" value="#{userController.user.email}" />
    </p>

    <p>
        <h:commandLink value="Edit" action="#{userController.edit(userController.user.id)}" />
    </p>
</h:form>

Это отлично работает, за исключением Edit commandLink.Когда я нажимаю на нее, я ожидаю, что userController.edit будет передан идентификатор пользователя, который в данный момент отображается на странице.

Однако выглядит так, как userController - это bean-объект в области запросов, имеющий @PostConstructметод, который назначает нового пользователя для пользовательского поля, всегда передается 0 в метод действия, поскольку идентификатор нового экземпляра пользователя равен null, который, по-видимому, преобразуется в 0.

Как я могу исправитьэтот контроллер / страницу, не изменяя область действия контроллера, чтобы передать правильный идентификатор действию редактирования?Вот код для контроллера:

@Model
public class UserController {

    @Inject
    @UserRepository
    private EntityManager entityManager;

    @Inject
    private UserTransaction tx;

    private User user;

    public String edit(Long id) {
        System.out.println("id = " + id);
        // fetch the user with id from the db
        return "edit";
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @PostConstruct
    private void init() {
        user = new User();
    }
}

1 Ответ

0 голосов
/ 23 июля 2011

Подход странный, но я могу себе представить, когда вам это нужно. (например, вы не пишете в сеанс, а флеш-область не работает в распределенной среде и т. д.). Кстати, если вы не можете использовать область видимости сеанса, подумайте об использовании области видимости flash.

Помимо правильности подхода, попробуйте добавить дополнительное поле к бобу:

protected Long currentId;

public Long getCurrentId() {
    return currentId == null ? user.getId() : currentId;//or simply return it, I don't know how you play with the user field
}

public void setCurrentId(Long currentId) {
    this.currentId = currentId;
}

Удалите параметр из действия edit и используйте поле currentId, и, на ваш взгляд, добавьте параметр (скрытое поле здесь не будет работать):

<f:viewParam name="id" value="#{userController.currentId}" />

Затем в действии вы можете получить идентификатор пользователя из предыдущего представления, просто открывая this.currentId. И кстати, попробуйте загрузить вашего пользователя из другого места, а не int @PostConstruct. Если вы создаете пользователя в @PostConstruct, то когда вы находитесь в методе редактирования, currentId будет из предыдущего представления, а user.id будет из @PostConstruct. Поэтому, если вы не хотите хранить пользователя в области действия сеанса, а используете только область запроса, вы должны сохранить ее сразу после создания (например, в базе данных). В методе редактирования вы должны вернуть его, используя currentId.

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