web.xml - Java Servlet 过滤器 - 在处理 JSP 页面之前未运行(在 Tomcat 上)
Posted
技术标签:
【中文标题】web.xml - Java Servlet 过滤器 - 在处理 JSP 页面之前未运行(在 Tomcat 上)【英文标题】:web.xml - Java Servlet Filters - Not being run before processing the JSP page (on Tomcat) 【发布时间】:2010-12-15 19:03:45 【问题描述】:我对 Servlet 过滤器相当陌生,基本上加入了一个使用它们的项目,并在 web.xml
文件中添加了一个额外的过滤器(部署在 Tomcat 5.5 上)。
我有 95% 的把握在某些时候它工作正常,但现在在调试时,如果我将断点放在我试图查看的 JSP 页面的顶部 (login.jsp
),它是模板页面 (page.jsp
)并在配置的过滤器的doFilter()
方法中;它贯穿整个login.jsp
页面(从上到下),然后是page.jsp
并开始处理过滤器。
我需要它首先运行过滤器,因为其中一个决定了页面应该显示的语言(检查 cookie、数据库设置和浏览器设置),然后应该应用于login.jsp
。
有没有人对可能出现的问题提出任何建议?
我可以发布很多代码,但我不相信它们会有任何用处,因为它们都以错误的顺序工作。
来自 web.xml 的片段:
<web-app>
...
<filter>
<filter-name>SetSecurityContextFilter</filter-name>
<filter-class>
com.section2.SecurityContextServletFilter
</filter-class>
</filter>
<filter>
<filter-name>SetLocaleFilter</filter-name>
<filter-class>
com.section2.locale.LocaleServletFilter
</filter-class>
</filter>
<filter>
<filter-name>trinidad</filter-name>
<filter-class>org.apache.myfaces.trinidad.webapp.TrinidadFilter</filter-class>
</filter>
<filter>
<filter-name>ActiveUserFilter</filter-name>
<filter-class>com.section2.ActiveUserFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>trinidad</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>SetSecurityContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SetLocaleFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>ActiveUserFilter</filter-name>
<url-pattern>/pages/section2/user/*</url-pattern>
</filter-mapping>
...
</web-app>
提前致谢。
【问题讨论】:
您看过java.sun.com/products/servlet/Filters.html 和tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/… 吗?在不知道自己在做什么的情况下,很难想象出了什么问题。您是否尝试过另一个 servlet 容器,例如 jetty? 【参考方案1】:一个明显的错误是在特立尼达过滤器映射中。它不应该有一个 servlet-name,而是一个 url-pattern。
【讨论】:
完全有效。这仅意味着特定过滤器与相关的 servlet 耦合,因此仅在相同的 url-pattern 上调用。【参考方案2】:Filter
代码是如何组织的?您是否可能先调用FilterChain#doFilter()
,然后才执行所需的逻辑?
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
// Any code here will be executed BEFORE passing request through JSP/Servlet.
chain.doFilter(request, response);
// Any code here will be executed AFTER passing request through JSP/Servlet.
【讨论】:
【参考方案3】:感谢您的回复 - 我现在已经完全理解了这个问题......它只发生在 login.jsp 页面,没有其他页面。在我的例子中,login .jsp
页面是一个特例,因为它通常被视为重定向的结果。
在web.xml
:
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login.jsp?error=true</form-error-page>
</form-login-config>
</login-config>
因此我认为过滤器没有按通常的顺序命中!从登录页面添加了一个调用来执行过滤器所做的事情,一切都很好。
再次感谢。
【讨论】:
【参考方案4】:没有为 login.jsp 调用过滤器的原因是 Tomcat 对规范的解释是身份验证是容器的一部分,而不是 webapp 的一部分,因此发生在过滤器的角色之外。因此过滤器不适用于登录页面(在本例中为 login.jsp)或 j_security_check。
ref:https://issues.apache.org/bugzilla/show_bug.cgi?id=21795 - 标题仅引用 j_security_check,但讨论涵盖了整个基于表单的身份验证机制。
【讨论】:
【参考方案5】:我写的时候也遇到了同样的问题:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
if(...)
response.sendRedirect(url);
chain.doFilter(request, response);
改为
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
if(...)
response.sendRedirect(url);
return;
chain.doFilter(request, response);
【讨论】:
以上是关于web.xml - Java Servlet 过滤器 - 在处理 JSP 页面之前未运行(在 Tomcat 上)的主要内容,如果未能解决你的问题,请参考以下文章
servlet 过滤器是不是必须在 web.xml 文件中指定?