如何将页面上呈现的当前用户的ID传递给JSF 2中的操作处理程序方法?

时间:2011-07-22 16:49:11

标签: jsf jsf-2

我有一个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传递当前在页面上呈现的用户的ID。

然而看起来userController是一个请求范围的bean,它具有一个@PostConstruct方法,用于将新用户分配给用户字段,因此总是将0作为一个ID传递给action方法。用户的新实例是null,显然会转换为0。

如何在不更改控制器范围的情况下修复此控制器/页面,以将正确的ID传递给编辑操作?这是控制器的代码:

@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 :(得分:0)

这种方法很奇怪,但我可以想象你什么时候需要这个。 (例如,您没有用于写入会话的魔杖,并且闪存范围在分布式环境中不起作用等)。 BTW如果你不能使用会话范围考虑使用flash范围。

除了方法的正确性之外,尝试向bean添加aditional字段:

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}" />

然后在操作中,您可以从上一个视图中获取用户ID,只需访问this.currentId即可。 顺便说一下,尝试从其他地方加载用户,而不是int @PostConstruct。如果您在@PostConstruct中创建用户,那么当您处于编辑方法时,currentId将来自上一个视图,而user.id将来自@PostConstruct。因此,如果您不希望将用户存储在会话范围中,但仅使用请求范围,则必须在创建后立即将其保留(例如,在数据库中)。在编辑方法中,您必须使用currentId将其恢复。