我有一个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();
}
}
答案 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将其恢复。