经过几天的谷歌搜索,我必须放弃并寻求帮助。我有带有jsf标签的xhtml页面。整个页面由PageController.java控制。重要的是控制器从url参数中获取项目ID和页码。除此之外,我有一个小表单,其中包含当前登录的用户信息或用户名和密码输入,如果没有人登录。我希望有可能使用该表单登录或注销用户。但是当我从用户控制器参数调用用户logIn()或logOut()函数时,只是缺少url。我已经尝试过使用h:commandbutton和h:commandlink了。我设法通过f:param标签发送参数,但它们仍然从url中丢失(这是问题,因为我需要在这里添加书签)。标签如h:link,h:button或h:不能使用outputLink,因为它们不允许我在点击时调用控制器功能。 谢谢你的帮助。
编辑: 我忘了提,我试图通过f:ajax来解决这个问题。问题是登录后我没有刷新页面就无法注销。这与其他方向相同。
编辑II: 我将展示说明问题的示例代码。在我的项目中,我有template.html,这是一个简单的页面模板,包含页眉,页脚,旁边菜单和主要内容。它可能对我遇到的问题没有影响。我的代码看起来像这样:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<f:metadata>
<f:event type="preRenderComponent" listener="#{PageController.init()}"/>
</f:metadata>
<ui:composition template="/template.xhtml">
<ui:define name="aside-menu">
<h:form id = "sidemenuform">
<h:panelGrid rendered="#{usersController.isLoggedIn()}" columns="1">
<h:commandLink value="LogOut" >
<f:param name="orderId" value="${PageController.groupId}"/>
<f:param name="page" value="${PageController.PageNumber}"/>
</h:commandLink>
</h:panelGrid>
<h:panelGrid rendered="#{!usersController.isLoggedIn()}" columns="1">
<h:outputLabel for="usernameInput" value="#{bundle.LogginUsernameLabel}: "/>
<h:inputText id="usernameInput" value="#{usersController.username}"/>
<h:outputLabel for="passwordInput" value="#{bundle.LogginPasswordLabel}:">
</h:outputLabel>
<h:inputSecret id="passwordInput" value="#{usersController.password}"/>
<h:commandButton action="#{usersController.login()}">
<f:param name="orderId" value="${PageController.GroupNumber}"/>
<f:param name="page" value="${PageController.PageNumber}"/>
</h:commandButton>
</h:panelGrid>
</h:form>
</ui:define>
<ui:define name="body">
<div id="navBar">
<ul>
<li class="previousPage">
<h:commandLink action="#{PageController.previous}" rendered="#{PageController.pagination.hasPreviousPage}">
</h:commandLink>
</li>
<li class="nextPage">
<h:commandLink action="#{PageController.next}" rendered="#{PageController.pagination.hasNextPage}">
</h:commandLink>
</li>
</ul>
</div>
<ui:repeat value="#{PageController.items}" var="item" varStatus="status">
<!-- List of items in group divided into pages -->
</ui:repeat>
</ui:define>
</ui:composition>
PageController.previous和PageController.next函数运行良好,因为它们将带有GET参数的url作为字符串返回,如下所示:
Page?groupId=1&PageNumber=2&faces-redirect=true
但是userController对它们一无所知,也不知道我们当前显示的页面。因此登录和注销功能无法返回url。这两个函数都返回void。问题是当我在页面重新加载后触发这些功能时,我的地址URL已从
更改/Project/faces/groups/Page.xhtml?groupId=534?pageNumber=1
要
/Project/faces/groups/Page.xhtml
然后init函数失败。如何防止这种行为??
答案 0 :(得分:0)
尝试在f:viewParams
代码中使用f:metadata
:
<f:metadata>
<f:viewParam name="orderId" value="${PageController.groupId}"/>
<f:viewParam name="page" value="${PageController.PageNumber}"/>
</f:metadata>
并将?includeViewParams=true
附加到userController.login()
和userController.logout()
返回的网址。这应该会自动将视图参数附加到网址。
答案 1 :(得分:0)
h:link
和h:button
创建javascript链接,没有机会使用它们来调用服务器端方法。您需要的是使用用户凭据 POST 服务器,如果登录过程正确,则稍后调用 REDIRECT 。最好的方法是使用页面控制器作为当前视图,还有一个用户控制器,它具有已登录用户的会话信息。您可以轻松地将一个bean注入另一个bean:
@ManagedBean
@SessionScoped
public class UserController{
public boolean doLogin(String email, String password){
//Do your internal request here
}
}
@ManagedBean
@ViewScoped
public class PageController{
//You'll need a setter for this
@ManagedProperty(value=#{userController})
private UserController userController;
public String doLogin(){
if (userController.doLogin(email, password)){
return "page?groupId=" + groupId + "PageNumber=" +
pageNumber +"faces-redirect=true";
}
else{
//Add some faces message describing the error
}
}
}
通过这种方式,您可以使视图的过程透明,这只会访问页面控制器方法。