按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
*。do
具体效果请参考 07…03 的例子,index。jsp 中有四个链接,分别指向/a1。do;
/a2。do; /xx/b1。do; /xx/yy/c1。do。
web。xml 中的ControllerServlet 会接收以。do 结尾的请求,并使用
forward 将请求转发到/test。jsp。
点击/a1。do 的情况。
73 / 148
…………………………………………………………Page 74……………………………………………………………
点击/xx/yy/c1。do 的情况。
这样做的一个好处是语义更清楚,只要看到以。do 结尾的请求就知道肯定
是交给 ControllerServlet 处理了,不管这个请求是在根路径还是子路径
下,都会准确无误的找到对应的 servlet。
缺点就是不同路径之间进行 forward,jsp 里就不能再使用相对路径了,
所以我们在 test。jsp 中使用request。getContextPath()获得当前应用在
服务器中的位置(例子中是/07…03)将相对路径都组装成绝对路径,这种
用法在以后也会经常用到。
返回
最后需要注意的是,这种请求映射就不能指定某一路径了,它必须是以星
号(*)开始字母结尾,不能写成/*。do 的形式。
现在咱们也发现 java 的请求映射有多傻了,灵活配置根本是不可能的任务。
想要获得所有以 user 开头。do 结尾的请求吗?user*。do 在 url…pattern 是无法
识别的,只能配置成*。do,再去 servlet 中对请求进行筛选。
想要让一个 servlet 负责多个请求吗?/user/*;/admin/*;*。do 写在一起
url…pattern 也不认识,只能配成多个 servlet…mapping。
74 / 148
…………………………………………………………Page 75……………………………………………………………
ControllerServlet
/user/*
ControllerServlet
/admin/*
ControllerServlet
*。do
java 的复杂性在此处显露无疑。实际使用时,最好不要依赖web。xml 中的配置,
在自己的类中实现灵活配置才是正途。
7。3。2。 过滤链
其实在 07…02 这个例子里,我们使用了两个过滤器,EncodingFilter 负责设置
编码,SecurityFilter 负责控制权限,那这两个过滤器是怎么起作用的呢?它
们两个同时过滤一个请求时谁先谁后呢?
下面这个图会告诉我们答案。
所有的奥秘就在 Filter 中的FilterChain 中。服务器会按照web。xml 中过滤器
定义的先后循序组装成一条链,然后一次执行其中的 doFilter()方法。执行的
顺序就如上图所示,执行第一个过滤器的 chain。doFilter()之前的代码,第二
个过滤器的 chain。doFilter()之前的代码,请求的资源,第二个过滤器的
75 / 148
…………………………………………………………Page 76……………………………………………………………
chain。doFilter()之后的代码,第一个过滤器的 chain。doFilter()之后的代码,
最后返回响应。
因此在 07…02 中执行的代码顺序是:
1。 执行 EncodingFilter。doFilter()中 chain。doFilter()之前的部分:
request。setCharacterEncoding(〃gb2312〃);
2。 执行 SecurityFilter。doFilter()中 chain。doFilter()之前的部分:判断
用户是否已登录。
如果用户已登录,则访问请求的资源:/admin/index。jsp。
如果用户未登录,则页面重定向到:/failure。jsp。
3。 执行 SecurityFilter。doFilter()中 chain。doFilter()之后的部分:这里
没有代码。
4。 执行 EncodingFilter。doFilter()中 chain。doFilter()之后的部分:这里
也没有代码。
过滤链的好处是,执行过程中任何时候都可以打断,只要不执行
chain。doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,
就要特别注意过滤链的执行顺序问题,像 EncodingFilter 就一定要放在所有
Filter 之前,这样才能确保在使用请求中的数据前设置正确的编码。
7。4。 filter 的详细配置
我们已经了解了 filter 的基本用法,还有一些细节配置在特殊情况下起作用。
在 servlet…2。3 中,Filter 会过滤一切请求,包括服务器内部使用 forward 转
发请求和的情况。
到了 servlet…2。4 中Filter 默认下只拦截外部提交的请求,forward 和 include
这些内部转发都不会被过滤,但是有时候我们需要 forward 的时候也用到
Filter,这样就需要如下配置。
TestFilter
anni。TestFilter
TestFilter
/*
REQUEST
FORWARD
76 / 148
…………………………………………………………Page 77……………………………………………………………
INCLUDE
EXCEPTION
这样 TestFilter 就会过滤所有状态下的请求。如果我们没有进行设置,默认使
用的就是 REQUEST。而EXCEPTION 是在 isErrorPage=〃true〃的情况下出现的,这
个用处不多,看一下即可。
这里 FORWARD 是解决request。getDispatcher(〃index。jsp〃)。forward(request;
response);无法触发 Filter 的关键,配置上这个以后再进行 forward 的时候就
可以触发过滤器了。
Filter 还有一个有趣的用法,在 filter…mapping 中我们可以直接指定
servlet…mapping,让过滤器只处理一个定义在web。xml 中的 servlet。
TestFilter
TestServlet
TestServlet
anni。TestServlet