使用 Tuckey URL 重写时仅适用于 JSF 页面而非静态资源的过滤模式
Filter pattern for only JSF pages and not static resources when using Tuckey URL rewriting
我正在实施过滤器以将过期用户重定向到密码页面。
我也在使用 Tuckey URL 重写来隐藏 .xhtml 扩展名。
我现在的问题是如何设置过滤器以仅过滤 JSF 页面而不过滤静态资源?
在 web.xml
URL 重写过滤器和它也在 FORWARD
上明确调度。这样传入的请求 URL/URI 将只是原始请求。默认情况下,过滤器在 REQUEST
上调度,当链中之前的某个其他过滤器执行 RequestDispatcher#forward()
调用时,这将错过命中,就像 URL 重写过滤器所做的那样。
<!-- Should be placed *after* URL rewrite filter. -->
<filter-mapping>
<filter-name>yourLoginFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
为了使其更具体,您还可以将过滤器挂接到特定的 servlet 而不是 URL 模式。下面的示例假设您已将 FacesServlet
映射到 facesServlet
的 <servlet-name>
上(请注意,您仍然需要保留前向调度程序):
<!-- Should be placed *after* URL rewrite filter. -->
<filter-mapping>
<filter-name>yourLoginFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
无论哪种方式,请注意,如果您也希望允许原始 URL(因此您还没有配置 URL 重写过滤器以将它们重定向到重写的 URL), 那么你需要显式指定 REQUEST
dispatcher 以及上面显示的,否则当用户直接使用原始 [=45= 请求页面时,过滤器不会 运行 ].如果您不允许原始 URLs,只需删除 <dispatcher>REQUEST</dispatcher>
.
也就是说,术语 "static resources" 在这种情况下有些含糊不清。您当然是想说像 CSS/JS/image 资源,但上述过滤器仍将涵盖由 JSF 通过 <h:outputStylesheet>
、<h:outputScript>
等管理的那些,所有这些都具有 /javax.faces.resource/*
URL 模式。您最好在过滤器中对请求 URL 执行额外检查,如下所示:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
boolean facesResourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
if (facesResourceRequest)) {
chain.doFilter(request, response); // Skip JSF resources.
return;
}
// Your original filter code here.
}
另请参阅:
- Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same
我正在实施过滤器以将过期用户重定向到密码页面。
我也在使用 Tuckey URL 重写来隐藏 .xhtml 扩展名。
我现在的问题是如何设置过滤器以仅过滤 JSF 页面而不过滤静态资源?
在 web.xml
URL 重写过滤器和它也在 FORWARD
上明确调度。这样传入的请求 URL/URI 将只是原始请求。默认情况下,过滤器在 REQUEST
上调度,当链中之前的某个其他过滤器执行 RequestDispatcher#forward()
调用时,这将错过命中,就像 URL 重写过滤器所做的那样。
<!-- Should be placed *after* URL rewrite filter. -->
<filter-mapping>
<filter-name>yourLoginFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
为了使其更具体,您还可以将过滤器挂接到特定的 servlet 而不是 URL 模式。下面的示例假设您已将 FacesServlet
映射到 facesServlet
的 <servlet-name>
上(请注意,您仍然需要保留前向调度程序):
<!-- Should be placed *after* URL rewrite filter. -->
<filter-mapping>
<filter-name>yourLoginFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
无论哪种方式,请注意,如果您也希望允许原始 URL(因此您还没有配置 URL 重写过滤器以将它们重定向到重写的 URL), 那么你需要显式指定 REQUEST
dispatcher 以及上面显示的,否则当用户直接使用原始 [=45= 请求页面时,过滤器不会 运行 ].如果您不允许原始 URLs,只需删除 <dispatcher>REQUEST</dispatcher>
.
也就是说,术语 "static resources" 在这种情况下有些含糊不清。您当然是想说像 CSS/JS/image 资源,但上述过滤器仍将涵盖由 JSF 通过 <h:outputStylesheet>
、<h:outputScript>
等管理的那些,所有这些都具有 /javax.faces.resource/*
URL 模式。您最好在过滤器中对请求 URL 执行额外检查,如下所示:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
boolean facesResourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
if (facesResourceRequest)) {
chain.doFilter(request, response); // Skip JSF resources.
return;
}
// Your original filter code here.
}
另请参阅:
- Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same