JSF Missing在url中获取参数

时间:2014-08-04 13:07:21

标签: jsf url parameters get

经过几天的谷歌搜索,我必须放弃并寻求帮助。我有带有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函数失败。如何防止这种行为??

2 个答案:

答案 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:linkh: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
        }
    }

}

通过这种方式,您可以使视图的过程透明,这只会访问页面控制器方法。