JSF在url中缺少get参数
在谷歌搜索了几天之后,我必须放弃并寻求帮助。我有一个带有jsf标记的xhtml页面。整个页面由PageController.java控制。重要的是,控制器从url参数中获取项目Id和页码。除此之外,我还有一个小表单,其中包含当前登录的用户信息或用户名和密码输入(如果没有人登录)。我想有可能登录或注销用户使用该表单。但当我从用户控制器调用user logIn()或logOut()函数时,url中的参数就丢失了。我已经尝试过使用h:commandbutton和h:commandlink。我设法通过f:param标记发送参数,但它们仍然从url中丢失(这是个问题,因为我需要在这里添加书签)。不能使用诸如h:link、h:button或h:outputLink之类的标记,因为它们不允许我在单击时调用控制器函数。 谢谢你的帮助 编辑: 我忘了提到,我试图通过f:ajax解决这个问题。问题是在登录后,我无法在不刷新页面的情况下注销。这与其他方向相同 编辑二: 我将展示示例代码来说明这个问题。在我的项目中,我有template.html,它是一个简单的页面模板,包含页眉、页脚、旁白菜单和主要内容。它可能对我遇到的问题没有影响。我的代码如下所示:JSF在url中缺少get参数,jsf,url,parameters,get,Jsf,Url,Parameters,Get,在谷歌搜索了几天之后,我必须放弃并寻求帮助。我有一个带有jsf标记的xhtml页面。整个页面由PageController.java控制。重要的是,控制器从url参数中获取项目Id和页码。除此之外,我还有一个小表单,其中包含当前登录的用户信息或用户名和密码输入(如果没有人登录)。我想有可能登录或注销用户使用该表单。但当我从用户控制器调用user logIn()或logOut()函数时,url中的参数就丢失了。我已经尝试过使用h:commandbutton和h:commandlink。我设法通过f
<?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>
但userController对它们一无所知,也不知道我们当前显示的页面。所以函数登录和注销不能返回url。两个函数都返回void。问题是,当我在重新加载页面后启动这些函数时,我的地址url从
/Project/faces/groups/Page.xhtml?groupId=534?pageNumber=1
到
然后初始化函数失败。如何防止这种行为???尝试在
f:metadata
标记中使用f:viewParams
:
<f:metadata>
<f:viewParam name="orderId" value="${PageController.groupId}"/>
<f:viewParam name="page" value="${PageController.PageNumber}"/>
</f:metadata>
并将
?includeViewParams=true
附加到由userController.login()
和userController.logout()返回的url。这将自动将视图参数附加到url。h:link
和h:button
创建javascript链接,没有机会使用它们调用服务器端方法。您需要的是使用用户凭据发布服务器,然后在登录过程正确的情况下调用重定向。最好是为当前视图使用页面控制器,并为登录用户使用具有会话信息的用户控制器。您可以轻松地将一个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
}
}
}
通过这种方式,您可以使流程对视图透明,而视图只能访问页面控制器方法。您可以提供一些代码吗?似乎你试图在一个问题中提到很多问题……有没有办法不用commandbutton或commandlink调用java函数onclick??例如,使用h:link或h:button?哪个是页面和用户控制器的作用域?如果返回void
,则Login
方法的行为是预期的。PageController是会话范围(无论如何应该是请求),UserController也是会话。我已尝试返回无效和空字符串。我知道这会将视图设置为当前页面。我试图通过附加到commandbutton/commandlink的f:param标记传递GET参数。这两个都不适合我。h:link和h:button按预期工作正常,但我不能在单击时调用登录和注销功能。虽然登录和注销功能不返回任何url,但我在那里输入了代码:return“?includeViewParams=true”;这会导致以下错误:无法找到操作“#{userscocontroller.login()}”的从视图id“/groups/Page.xhtml”与结果“?includeViewParams=true”匹配的导航大小写,请尝试返回“#?includeViewParams=true”。相同的错误消息。即使在以下情况下:返回getCurrentPageUri()+“?includeViewParams=true”;和:私有字符串getCurrentPageUri(){String s=((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getQueryString();返回((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRequestURI();}此外,我还有一个错误,元数据组件需要嵌套在f:metadata标记中。建议:在for code中包含必要的组件:当某些属性存在时,返回“#?includeViewParams”确实无法按预期工作,很抱歉给出了错误的建议。如果您的操作不需要任何导航案例,您可以使用ajax来调用它,例如使用或嵌套实例中的。在这两种情况下,都不应触碰url。如果你以后需要更新页面,我会使用。我考虑过类似的东西,但觉得太乱了。。。看来我错了。我会这样尝试:)我认为这比在同一个视图中访问两个控制器要好得多,你不这么认为吗?我必须承认我对jsf和java都是新手。我了解到这取决于您的需要,您在视图中使用了多少控制器。我还认为这是一个好主意,因为我可以在我需要的每一页上都放上这段代码,而不必在这些页的每个控制器中实现相同的包装函数。这就是我的方法。无论如何,像您这样从会话范围的bean执行隐式导航应该不会有问题。您可以按照现在的方式进行操作,只要通过视图传递参数:{userscoontroller.login(orderId,page)}
,假设EL2可用。然而,这涉及到在用户控制器中混合这样一个与视图相关的参数……好的,我在pageController中包装了登录和注销功能。为了简化,我从当前上下文中获取用户控制器(托管属性当然更好)。它确实有效。还是不太相信,但是非常感谢。我将使用此代码一段时间:)
<f:metadata>
<f:viewParam name="orderId" value="${PageController.groupId}"/>
<f:viewParam name="page" value="${PageController.PageNumber}"/>
</f:metadata>
@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
}
}
}