java filter url匹配规则_java过滤器filter使用

本文围绕Java Filter展开,介绍了Filter需继承抽象类并实现相关方法,以及Servlet的编写。阐述了Servlet和Filter的注册方式,重点讲解了Filter的URL匹配规则,包括完全匹配、目录匹配、后缀名匹配等,还说明了多个过滤器作用于一个URL时的执行顺序,以及Filter在web.xml中的其他标签使用。

一:filter:过滤器,拦截servlet的请求和响应。

1、

1 package jd.com.filter;2

3 import javax.servlet.*;4 import java.io.IOException;5

6 public classMyFilter implements Filter {7 @Override8 public voiddestroy() {9

10 }11

12 @Override13 public voidinit(FilterConfig filterConfig) {14

15 }16

17 @Override18 public voiddoFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {19

20 try{21 System.out.println("请求到拦截器。");22 //放行请求和响应。

23 filterChain.doFilter(servletRequest,servletResponse);24 System.out.println("响应到拦截器。");25 }catch(Exception ex){26 ex.printStackTrace();27 throw new RuntimeException(ex+"run ereror");28 }29

30 }31 }

需要继承抽象类Filter,需要重写init和destory方法以及doFilter()方法。如果想放行请求和响应需要调用类FilterChain的方法doFilter(servletRequest,serletRespone)。

servlet:

1 package jd.com.filter;2

3 import javax.servlet.ServletException;4 import javax.servlet.annotation.WebServlet;5 import javax.servlet.http.HttpServlet;6 import javax.servlet.http.HttpServletRequest;7 import javax.servlet.http.HttpServletResponse;8 import java.io.IOException;9

10 @WebServlet(name = "ServletFilter")11 public classServletFilter extends HttpServlet {12 protected voiddoPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {13

14 }15

16 protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {17 System.out.println("请求到servlet。");18 }19 }

2、注册serlet和Filter。

1 <?xml version="1.0" encoding="UTF-8"?>

2

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

6 version="2.5">

7

8 ServletFilter

9 jd.com.filter.ServletFilter

10

11

12 ServletFilter

13 /test/

14

15

16 MyFilter

17 jd.com.filter.MyFilter

18

19

20 MyFilter

21 /test/

22

23

24

想flter过滤那个url需要在url-pattern里写那个url!

a595d70d32830eb065ebe8150afd5d11.png

图示:

2b1a2e282a6ab2b17cfbd9106e8b74ff.png

2、FilterChain 过滤链

当我们的jsp或者servlet被多个过滤器使用的时候,整个请求和响应形成的链叫做过滤链。

通过过滤链FilterChain的doFilter方法,将一个请求从一个过滤器放行到下一个过滤器,直到最后一个过滤器被调用放行的时候,才到达最后的servlet或者jsp。

doFilter()放行方法。区别于咱们重写抽象方法Filter的doFiltter()方法,一个是服务器调用一个是FilterChain调用。

3、多个过滤器作用一个url的执行顺序(filter-mapping在web.xml的顺序决定):

url匹配规则:

1)完全匹配 : 必须以"/"开头  例如:"/a"

2)目录匹配:  必须以"/"开头,以"*"结束,例如:"/a/*"

3)后缀名匹配: 以“*”开头,以"jsp、do、action"结束的。例如:“”*.jsp  *.do *.action“”

匹配规则:

以精确匹配>最长路径匹配>后缀名匹配>默认匹配

例1:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,不会去管servletB。

例2:比如servletA的url-pattern为/test/*,而servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。

例3: 比如servletA的url-pattern:*.action ,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test.action,这个时候容器就会优先进行路径匹配,而不是去匹配扩展名,这样就去调用servletB。

filter匹配规则:

例子:Afilter urlpattern:/*

Bfilter urlpattern::/a/c

servlet的url为:/a/c的时候,如上filter都会被使用,那Afilterr和Bfilter执行顺序是什么呢?

web.xml注册顺序:

FilterA

jd.com.mapFilter.FilterA

FilterA

/*

FilterB

jd.com.mapFilter.FilterB

FilterB

/a/c

实际输出结果:

7f77894aedbed7dd13824ee5659b6ed3.png(响应回来的时候先经过B在经过A)

也就是说,执行filter的顺序是按照,在web.xml中的filter-mapping的顺序来决定,我们的这个2个顺序调换,看下输出:

1

2 FilterA

3 jd.com.mapFilter.FilterA

4

5

6 FilterB

7 /a/c

8

9

10 FilterA

11 /*12 13 14 FilterB15 jd.com.mapFilter.FilterB16

f44275483382ec914406c6454abd061b.png

4)filter在web.xml其他标签:

1、Servletdemo1位置 内表示匹配那个servlet。是servletname不是相对路径。

4b41b374c6968fb37f64c90a164d3676.png

注意:

如果一个filter-mapping其中已经存在url-pattern 不要在存在servlet-name,在不同的版本中会重复执行2次过滤器!!

2、 dispatch filter作用那种请求。

请求(3和4了解):1、REQUEST:从浏览器发送过来的请求,这个filter的默认作用请求。

2、FORWARD:转发过来的请求。

3、ERROR:因为服务器错误而发送过来的请求。

4、INCLUDE:包含过来的请求。

1)默认情况(request)

demo1:

1 package jd.com.otherTag;2

3 import javax.servlet.ServletException;4 import javax.servlet.annotation.WebServlet;5 import javax.servlet.http.HttpServlet;6 import javax.servlet.http.HttpServletRequest;7 import javax.servlet.http.HttpServletResponse;8 import java.io.IOException;9

10 @WebServlet(name = "Servletdemo1")11 public classServletdemo1 extends HttpServlet {12 protected voiddoPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {13

14 }15

16 protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {17 System.out.println("请求进入Servletdemo1");18 request.getRequestDispatcher("/a/b").forward(request,response);19 }20 }

demo2:

1 package jd.com.otherTag;2

3 import javax.servlet.ServletException;4 import javax.servlet.annotation.WebServlet;5 import javax.servlet.http.HttpServlet;6 import javax.servlet.http.HttpServletRequest;7 import javax.servlet.http.HttpServletResponse;8 import java.io.IOException;9

10 @WebServlet(name = "Servletdemo2")11 public classServletdemo2 extends HttpServlet {12 protected voiddoPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {13

14 }15

16 protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {17 System.out.println("进入Servletdemo2 请求");18 }19 }

web.xml

1

2 Servletdemo1

3 jd.com.otherTag.Servletdemo1

4

5

6 Servletdemo1

7 /a

8

9

10 demoFilter

11 jd.com.otherTag.demoFilter

12

13

14 demoFilter

15 /*16 17 18 Servletdemo219 jd.com.otherTag.Servletdemo220 21 22 Servletdemo223 /a/b24

d9942ee06838515babaef00cbe11a17d.png

注意:

因为filter的匹配url为/*所有 如果匹配的不是所有的话 需要注意的是filter的url和其他2个demo的url是包含关系。

1

2 Servletdemo1

3 jd.com.otherTag.Servletdemo1

4

5

6 Servletdemo1

7 /a/c

8

9

10 demoFilter

11 jd.com.otherTag.demoFilter

12

13

14 demoFilter

15 /a/*16 17 18 Servletdemo219 jd.com.otherTag.Servletdemo220 21 22 Servletdemo223 /a/b24

结果:

3825ff2167106b5a1c4cbaec1ca7d634.png

在转发的时候,没有经过demofilter,直接转发到servletdemo2.

解决方法:

默认情况下走的是请求是REQUEST,所以需要添加FORWARD的请求。注意需要写REQUEST请求,因为如果写其他请求默认请求不会生效。

1

2 demoFilter

3 jd.com.otherTag.demoFilter

4

5

6 demoFilter

7 /a/*8 REQUEST9 FORWARD10

结果:

3d1702cd0fd926d07b5dc24ea5f3764f.png

2)设置错误页。

1

2 ServletError

3 jd.com.coding.ServletError

4

5

6 ServletError

7 /c

8

9

10 404

11 /c

12

1 package jd.com.coding;2

3 import javax.servlet.ServletException;4 import javax.servlet.annotation.WebServlet;5 import javax.servlet.http.HttpServlet;6 import javax.servlet.http.HttpServletRequest;7 import javax.servlet.http.HttpServletResponse;8 import java.io.IOException;9

10 @WebServlet(name = "ServletError")11 public classServletError extends HttpServlet {12 protected voiddoPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {13

14 }15

16 protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {17 response.setContentType("text/html;charset=UTF-8");18 response.getWriter().print("亲访问的资源不存在!");19 }20 }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值