>我有这个登录表单:
<h:form>
<h:panelGrid columns="2" >
<h:outputLabel for="username" value="Login:"/>
<h:inputText id="username" value="#{userController.userName}" required="true"/>
<h:outputLabel for="password" value="#{msg.password}"/>
<h:inputSecret id="password" value="#{userController.password}" required="true"/>
<h:column/>
<h:commandButton value="#{msg.login}" action="#{userController.login}"/>
</h:panelGrid>
</h:form>
有了这个支持豆:
@ManagedBean(name = "userController")
@SessionScoped
public class UserController {
private String userName = "";
private String password = "";
//getter, setters
public String login(){
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
try {
request.login(userName, password);
} catch (ServletException e) {
}
return "next-page.xhtml"; //if login processes is proper, i redirect to next page
}
}
我在 JSF 中的最佳实践中读到:模型、操作、getter、导航、相位侦听器
我总是回发到同一个视图(返回 null 或 void,然后有条件地渲染/包含结果。对于页面到页面的导航,我不使用 POST 请求(对于导航情况是强制性的),仅仅是因为这对 UX(用户体验;浏览器后退按钮的行为没有达到应有的状态,浏览器地址栏中的 URL 总是落后一步,因为它默认是转发,而不是重定向)和 SEO(搜索引擎优化;搜索机器人不索引 POST 请求)。我只是使用输出链接甚至纯HTML元素进行页面到页面导航。
那么,当我的登录正确并且我想立即重定向到next-page.xhtml
时,我该怎么办?
在try
结束时,使用 ?faces-redirect=true
执行导航,以便执行重定向。在 catch
中,返回 null
以使其保留在同一页中。
try {
request.login(userName, password);
return "next-page.xhtml?faces-redirect=true";
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("Unknown login"));
return null;
}
为了完整起见,我在登录失败时添加了一条人脸消息,否则最终用户将不知道为什么页面似乎在没有任何形式的反馈的情况下重新加载。此消息将显示在<h:messages globalOnly="true">
中。
另请参阅:
- 使用 j_security_check 在 Java EE/JSF 中执行用户身份验证(答案的后半部分)
- 如何在 JSF 中导航?如何使URL反映当前页面(而不是上一个页面)