我正在尝试使用Servlet的过滤器(javax.servlet.Filter
)编写一个简单的urlrewriter。过滤器根据URL检查所有请求和重新路由到servlet(或JSP)。
示例:http://server/app/person/Roscoe将被翻译为http://server/app/person.jsp?name=Roscoe
我的Filter
doFilter
检查了请求,如果模式匹配,则创建一个新HttpServletRequest
并将其传递给chain.doFilter
。新的HttpServletRequest
扩展javax.servlet.http.HttpServletRequestWrapper
并覆盖参数,URI,URL,查询字符串和servlet路径,使其看起来像新JSP(/person.jsp?name=Roscoe
)。我认为通过将新请求传递给chain.doFilter
,它会重定向到JSP。除了将person.jsp
的内容返回给浏览器之外,这种方式有用。 person.jsp
从不执行内容以纯文本(Content-Type: text/plain
)返回。
我的web.xml
有过滤器和过滤器映射:
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
这是正确的是使用Servlet过滤器来重写请求吗?
我知道现有的urlrewriters(例如Tuckey),但仍然想写我自己的,主要是为了学习和更好的控制。
跟进:我也尝试通过执行重定向而不是chain.doFilter
(其中req
是包装请求):
config.getServletContext().getRequestDispatcher("/person.jsp").forward(req, resp);
效果更好,但我的CSS文件(styles.css
)仍然相对于原始网址http://server/app/person/styles.css,而应该是http://server/app/styles.css
后续行动2 :路径问题由this question涵盖。
答案 0 :(得分:2)
仅包装请求并更改其状态是不够的。您需要转发/重定向到适当的资源。过滤器和servlet映射到URL模式。您正在执行的链是基于传入请求的URL的模式构建的。更改请求中的URL并将其传递给链中的下一个项目不会重建链以考虑新URL。这就是前进/重定向的目的。