以前总以为filter就是一种特殊servlet,所以他们在web.xml中配置因该是一样的,但是事实并非如此!
请看下文:
看Servelt规范:
简要翻译下:
filter是一个可以复用的代码片段,可以用来转换HTTP请求、响应和头信息。Filter不像Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求,或者修改从某一的响应。
再在看Filter的继承体系(不继承Servlet接口):
- public interface Filter
所以第一个结论:Servlet和Filter没有关系!但是2者可以很好的协同工作。
还有不同的就是, servlet容器对url匹配过程
当一個请求发送到servlet容器中,容器就会將减去上下文的路径作为匹配servlet的映射url 。
比如 我我访问的是http://localhost:8088/test/aa.html. servlet容器就谁去掉上下文test
得到/aa.html 这个就是servlet的映射url。 这个映射的过程还是有顺序的(这就和filter不同了下面会体会到)。
当一個servlet匹配成功后就不会在往下去匹配了, 。 其他还有其他的匹配规则:
1, 精确路径的匹配;例子:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先 进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,也不会去理会其他的servlet了。
2, 最长路径的匹配:例子:servletA的url-pattern为/test/*,而servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。
3. 扩展匹配,如果url最后一段包含扩展,容器将会根据扩展选择合适的servlet。例子:servletA的url-pattern:*.action
4 ,对于filter ,它没有映射的路径,在配置文件中不需要写url,只需要写filter类就好了,不会像servlet那样只匹配一个servlet,因为filter的集合是一个链,所以只要考虑执行的顺序就可以,而不会出现只选择一个filter,写的每个filter都会执行。Filter的处理顺序和filter-mapping在web.xml中定义的顺序相同。