有什么办法让filtermapping不包含子目录吗?过滤器映射url-pattern不包括子目录
例如。
我在我的上下文根中有.xhtml文件,我也有一个名为“test”的子文件夹,文件的扩展名相同。有没有可能将过滤器映射到上下文根中的文件而不是“test”目录中的文件?
有什么办法让filtermapping不包含子目录吗?过滤器映射url-pattern不包括子目录
例如。
我在我的上下文根中有.xhtml文件,我也有一个名为“test”的子文件夹,文件的扩展名相同。有没有可能将过滤器映射到上下文根中的文件而不是“test”目录中的文件?
url-pattern
确实是限制性的匹配。它只允许准确的,前缀或后缀matchnig。不是中间/整体/正则表达式匹配。所以例如/*.xhtml
你打算做什么是行不通的。
如果你想在/test
文件夹排除XHTML而已,那么你最好是一个真正的Filter
监听的*.xhtml
基本上做以下工作在doFilter()
方法的url-pattern
:
// First cast ServletRequest to HttpServletRequest.
HttpServletRequest hsr = (HttpServletRequest) request;
// Check if requested resource is not in /test folder.
if (!hsr.getServletPath().startsWith("/test/")) {
// Not in /test folder. Do your thing here.
}
的HttpServletRequest#getServletPath()
基本收益请求URI的部分来自上下文路径。
如有必要,您可以将值/test
配置为过滤器的<init-param>
,以便您可以从web.xml
而不是过滤器代码中控制该值。
某些容器(如树脂)定义了一个扩展来过滤web.xml中的映射定义,该扩展允许指定url-regexp
,它允许基于正则表达式匹配url。 (reference)。看看你的容器是否有这样的东西。
由于*.ext
风格映射包含子目录,因此使用标准servlet /过滤器可用的内容,没有直接排除子目录的方法。您可以通过声明另一个专门处理/test/*.xhtml
映射的过滤器并相应地处理该过滤器来解决此问题。
但一个映射/ *的过滤器仍然包括/ /下的所有东西它会不会? – 2010-08-12 12:58:43
这是正确的。我在想,第一个匹配的是使用的,但事实并非如此。相反,你可以在你的过滤器中添加一个url正则表达式检查 - 如果它匹配正则表达式,那么过滤器在委托给重新生成过滤器链之前执行它的工作。如果正则表达式不匹配,只是委托给过滤器链而不做任何工作。 – mdma 2010-08-12 14:42:07
的解决方案,基本上你需要自己的过滤器类,并定义排除网址为INIT-参数有关过滤
package test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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 LoginValidationFilter implements Filter {
private String loginPage = "";
private List<String> excludedURLs;
public void init(FilterConfig filterConfig) throws ServletException {
this.loginPage = filterConfig.getInitParameter("loginPage");
String[] excluded = filterConfig.getInitParameter("excludedURLs").split(";");
excludedURLs = new ArrayList<String>();
for (int i = 0; i < excluded.length; i++) {
excludedURLs.add(excluded[i]);
}
}
public void destroy() {
this.loginPage = "";
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,
ServletException {
HttpServletRequest httpRequest = request instanceof HttpServletRequest ? (HttpServletRequest) request : null;
HttpServletResponse httpResponse = response instanceof HttpServletResponse ? (HttpServletResponse) response
: null;
if (httpRequest == null || httpResponse == null) {
filterChain.doFilter(request, response);
return;
}
boolean isExcludedURL = false;
for (int i = 0; i < excludedURLs.size(); i++) {
if (httpRequest.getRequestURL().indexOf(excludedURLs.get(i)) > -1) {
isExcludedURL = true;
break;
}
}
if (isExcludedURL) {
filterChain.doFilter(request, response);
} else {
if (UserUtil.validateUserLogin(httpRequest)) {
filterChain.doFilter(request, response);
} else {
httpResponse.sendRedirect(httpRequest.getContextPath() + loginPage);
}
}
}
}
,并定义过滤器,映射和在web.xml中排除URL的
<filter>
<filter-name>LoginValidationFilter</filter-name>
<filter-class>test.LoginValidationFilter</filter-class>
<init-param>
<param-name>loginPage</param-name>
<param-value>/login.jsp</param-value>
</init-param>
<init-param>
<param-name>excludedURLs</param-name>
<param-value>/admin/;/assets/;/content/;/css/;/js/;/login.jsp;/login.cmd;/logout.cmd;forgot_password.jsp;pageName=</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LoginValidationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
对不起,这是我的第一篇文章,它花了我大约30分钟的时间来更正格式。解决方案,基本上你需要你自己的过滤器类,并定义排除网址作为过滤器的init-param。 – softskin 2014-01-20 17:11:57
您可以为上下文根中的每个文件添加一个url-mapping值,因此筛选器将应用于这些文件,但不会应用于测试文件夹中的文件(实际上它只适用于这些特定文件)。下面的工作对我来说
<url-pattern>/index.faces</url-pattern>
我首先想到在Filter中硬编码?但init-param很聪明。在这里学到了些东西。 – JoseK 2010-08-13 11:35:37
@Jose:不客气。 – BalusC 2010-08-13 11:58:22