JSF 中的 Web 过滤器
Posted
技术标签:
【中文标题】JSF 中的 Web 过滤器【英文标题】:Web Filter in JSF 【发布时间】:2012-12-30 13:43:15 【问题描述】:我正在通过引用this link实现网络过滤
我的代码是
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_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>project_name</display-name>
<welcome-file-list>
<welcome-file>/project_name/faces/jsp/HomePage.jsp</welcome-file>
</welcome-file-list>
<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>/faces/*</url-pattern>
</servlet-mapping>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.CONTROL_SKINNING</param-name>
<param-value>enable</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.LoadScriptStrategy</param-name>
<param-value>ALL</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.LoadStyleStrategy</param-name>
<param-value>ALL</param-value>
</context-param>
<context-param>
<param-name>org.ajax4jsf.DEFAULT_EXPIRE</param-name>
<param-value>2764800</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.ERROR_HANDLING</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>org.ajax4jsf.handleViewExpiredOnClient</param-name>
<param-value>true</param-value>
</context-param>
<filter>
<display-name>RichFaces Filter</display-name>
<filter-name>richfaces</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
<init-param>
<param-name>createTempFiles</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>maxRequestSize</param-name>
<param-value>20000000</param-value>
</init-param>
<init-param>
<param-name>enable-cache</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.common.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/faces/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>richfaces</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/primefaces_resource/*</url-pattern>
</servlet-mapping>
</web-app>
LoginFilter.class
public class LoginFilter implements Filter
@Override
public void init(FilterConfig config) throws ServletException
// If you have any <init-param> in web.xml, then you could get them
// here by config.getInitParameter("name") and assign it as field.
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
System.out.println("Inside Login Filter");
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
System.out.println("session..."+ session);
if (session == null || session.getAttribute(IConstants.HAS_USER_ID) == null)
response.sendRedirect(request.getContextPath() + "/faces/jsp/login.jsp"); // No logged-in user found, so redirect to login page.
else
chain.doFilter(req, res); // Logged-in user found, so just continue request.
@Override
public void destroy()
// If you have assigned any expensive resources as field of
// this Filter class, then you could clean/close them here.
登录成功后设置会话变量
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap()
.put(IConstants.HAS_USER_ID, IConstants.HAS_USER_ID);
但我面临的问题是我一直低于日志
Inside Login Filter
session...org.apache.catalina.session.StandardSessionFacade@1c134e1
在控制台和页面永远不会重定向到下一页或登录页面。
【问题讨论】:
你的网址格式是什么? @TechExchange localhost:8282/project_name/faces/jsp/MainHomePage.jsp 【参考方案1】:这是因为您的过滤器也匹配登录页面上的请求。它基本上是在无限循环中运行,重定向到登录页面。基本上有两种选择:
确保登录 URL 未被过滤器映射覆盖。将受限页面放在/secured/*
、/app/*
等文件夹中,并将过滤器映射到该 URL 模式,然后将登录页面放在外面。
如果当前未请求登录 URL,请检查过滤器。
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
boolean loggedIn = (session != null) ? session.getAttribute(IConstants.HAS_USER_ID) != null : false;
String loginURL = request.getContextPath() + "/faces/jsp/login.jsp";
if (!loggedIn && !request.getRequestURI().equals(loginURL))
response.sendRedirect(loginURL);
else
chain.doFilter(request, response);
【讨论】:
我的 request.getRequestURI 有问题。打印后我得到 /testproject/faces/a4j/g/3_3_1.GA/org/richfaces/ui.pack.js 和 /eapp_online/faces/ a4j/s/3_3_1.GAorg/richfaces/renderkit/html/css/basic_both.xcss/DATB/eAELXT5DOhSIAQ!sA18_和/eapp_online/faces/a4j/s/3_3_1.GAorg/richfaces/renderkit/html/css/extended_both.xcss /DATB/eAELXT5DOhSIAQ!sA18_ 为什么你认为它是错误的?您将过滤器映射到/faces/*
,因此它将在与该 URL 模式匹配的所有请求上运行,包括 JSF 资源文件(JS/CSS/图像文件)。您只需要进一步微调 URL 模式,或者检查请求 URI 是否不以 /faces/a4j/
开头,然后跳过它们被阻止。【参考方案2】:
我实现了一个缓存过滤器。这是代码。看看这是否有帮助
在您的 web.xml 中添加以下内容
<filter>
<filter-name>cache</filter-name>
<filter-class>au.com.webapp.config.CacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cache</filter-name>
<url-pattern>*.xhtml</url-pattern>
</filter-mapping>
在您的 au.com.webapp.config 包中创建一个类 CacheFilter,如下所示:
package au.com.webapp.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CacheFilter implements Filter
private static long maxAge = 86400 * 30; // 30 days in seconds
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
HttpServletResponse httpResponse = (HttpServletResponse) response;
String uri = ((HttpServletRequest) request).getRequestURI();
if (uri.contains(".js") || uri.contains(".css") || uri.contains(".svg") || uri.contains(".gif")
|| uri.contains(".woff") || uri.contains(".png"))
httpResponse.setHeader("Cache-Control", "max-age=" + maxAge);
chain.doFilter(request, response);
@Override
public void init(FilterConfig filterConfig) throws ServletException
System.out.println("Cache Filter started: ");
@Override
public void destroy()
【讨论】:
以上是关于JSF 中的 Web 过滤器的主要内容,如果未能解决你的问题,请参考以下文章