如何使用 PrimeFaces 在 JSF 上重定向?
Posted
技术标签:
【中文标题】如何使用 PrimeFaces 在 JSF 上重定向?【英文标题】:How to redirect on JSF using PrimeFaces? 【发布时间】:2012-05-02 21:53:45 【问题描述】:我正在尝试在 JSF 上做一个基本的安全系统,如果用户没有登录并尝试访问受限页面,他将被重定向到 login.xhtml。这是在 servlet 过滤器中完成的。
我的问题是当使用 resp.sendRedirect("login.xhtml");登录页面丢失所有资源、css、脚本等,所以页面显示没有任何样式。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<filter>
<filter-name>restrict</filter-name>
<filter-class>br.com.jetcar.filter.RestrictionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>restrict</filter-name>
<url-pattern>*.xhtml</url-pattern>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
</web-app>
模板.xhtml
<!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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<h:outputScript library="primefaces" name="jquery/jquery.js"/>
<h:outputStylesheet library="css" name="template.css" />
<h:outputScript name="clock.js" library="js"></h:outputScript>
<title><ui:insert name="title">Bem-Vindo</ui:insert></title>
</h:head>
<body>
<p:growl id="messages"/>
<div id="header">
<ui:insert name="header">
<div id="headerTitle">JetCar</div>
<div id="clock"></div>
</ui:insert>
</div>
<div id="menu">
<ui:insert name="menu">
<ui:include src="menu.xhtml" />
</ui:insert>
</div>
<div id="content">
<ui:insert name="content">
</ui:insert>
</div>
<div id="footer">
<ui:insert name="footer">
<p>Desenvolvido por</p>
<p>Rodrigo Cavalcante de Souza</p>
<p>Jorge Luis</p>
</ui:insert>
</div>
</body>
</html>
login.xhtml
<?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">
<ui:composition template="resources/template/template.xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<ui:define name="title">Login</ui:define>
<ui:define name="content">
</ui:define>
</ui:composition>
index.xhtml 看起来和登录一样,因为我还在测试,可能是什么问题?
来自 chrome 控制台的错误
GET http://localhost:8080/JetCar/javax.faces.resource/growl/assets/login.xhtml 404 (Not Found)
login.xhtml:3GET http://localhost:8080/JetCar/javax.faces.resource/themes/sam/login.xhtml 404 (Not Found)
login.xhtml:6GET http://localhost:8080/JetCar/javax.faces.resource/jquery/login.xhtml 404 (Not Found)
login.xhtml:6GET http://localhost:8080/JetCar/javax.faces.resource/login.xhtml 404 (Not Found)
login.xhtml:6GET http://localhost:8080/JetCar/javax.faces.resource/core/login.xhtml 404 (Not Found)
login.xhtml:4GET http://localhost:8080/JetCar/javax.faces.resource/login.xhtml 404 (Not Found)
login.xhtml:6GET http://localhost:8080/JetCar/javax.faces.resource/growl/login.xhtml 404 (Not Found)
login.xhtml:10Uncaught ReferenceError: jQuery is not defined
chrome-extension://ffdcfjdljhbehggjdkdioajnknjcpbjb/js/sbc_cookies_mon.js:1Uncaught TypeError: Cannot read property 'tagName' of null
我正在使用 primefaces 2.2.1、glassfish 3.1、JSF 2.0
编辑:我刚刚注意到资源也使用 .xhtml 扩展名,因此它干扰了过滤器。
修复:if(req.getSession().getAttribute("func") == null && !pageRequested.contains("login.xhtml") && !pageRequested.contains("/javax.faces.resource"))
resp.sendRedirect("login.xhtml");
【问题讨论】:
【参考方案1】:我经常使用这种方式直接从Java Bean重定向它:
FacesContext.getCurrentInstance().getExternalContext().redirect(Url);
【讨论】:
【参考方案2】:在 JSF 2 中特别是在 JSF 上重定向页面的正确方法是从方法调用中返回视图的名称:
例如:
public String doLogin()
//apply the login logic.
return "name/of/the/view?facesRedirect=true"
【讨论】:
【参考方案3】:您的过滤器也将 HTTP 请求重定向到 JSF 资源。您需要更改过滤器逻辑以添加检查当前请求是否不是 JSF 资源请求。您可以通过检查请求 URI 在上下文路径后是否不以 ResourceHandler.RESOURCE_IDENTIFIER
开头来做到这一点。
if (request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER))
chain.doFilter(request, response);
else
response.sendRedirect(request.getContextPath() + "/login.xhtml");
【讨论】:
以上是关于如何使用 PrimeFaces 在 JSF 上重定向?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Primefaces+JSF2 中显示用户点击的 url
在 PrimeFaces 中添加 Angular Js - JSF
如何在 JSF 上延迟 Primefaces AjaxStatus?