javaWeb三剑客:
1. Servlet:接收请求,处理请求(单例,也就是说,多个用户请求的的servlet是同一个对象)2. Filter:拦截请求(单例->也就是说,多个用户请求的的filter是同一个对象)
3. Listem: 监听用户/服务器行为,javaWeb三剑客:
过滤器的实现
1.编写一个类实现Filter接口
init dofilter destory ->过滤器的生命周期方法
2.在web.xml文件中进行配置(也可以使用注解的方式替换xml配置)
过滤器
init destory生命周期方法只会执行一次
dofilter方法
filter包下:AFilter类->生命周期方法,请求被该过滤器拦截,执行该方法(请求多次,执行多次这个方法)
public class AFilter implements Filter{
public void init(){
sout("AFliter创建了");
}
public void filter(){
sout("AFilter拦截了");
}
public void destory(){
sout("AFilter销毁了");
}
}
web.xml配置Filter
<filter>
<filter-name>AFilter</filter-name>
<filter-class>com.huse.filter.AFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AFilter</filter-name>
<url-pattern>/*</url-pattern>//拦截所有请求
</filter-mapping>
webapp目录下
index.jsp
<%page%>
<h1>首页界面</h1>
<img src="/image/demo.jpg" />
访问失败
filter生命周期
tomcat服务器启动的时候就创建了,调用了init()方法 并且该请求是被该Filter拦截,执行doFilter()方法,在服务器关闭之前销毁Fillter对象,销毁Filter对象之前调用destory()方法
怎么实现放行请求呢
对于过滤器链,只要有一个不放行你就访问不到目标资源 由多个过滤器组成的链条
这个方法,调用FilterChain的doFilter(),表示该过滤器放行 我这部分让你过了,后面还有!!你过不过还待定
public class AFilter implements Filter{
public void init(){
sout("AFliter创建了");
}
public void filter(ServletRequest request,ServletResponse response,){
sout("AFilter拦截了");
filterChain.doFiter(ServletRequest,ServletResponse);
}
public void destory(){
sout("AFilter销毁了");
}
}
成功
过滤器的执行顺序
由Filter的<filter-mapping>在web.xml配置顺序决定 谁在前谁先执行
注解方式
使用WebFilter替换之前的xml配置
使用注解方式
讲xml里面的配置全部注释
@WebFilter("/*")
public class AFilter implements Filter{
public void init(){
sout("AFliter创建了");
}
public void filter(ServletRequest request,ServletResponse response,){
sout("AFilter拦截了");
filterChain.doFiter(ServletRequest,ServletResponse);
}
public void destory(){
sout("AFilter销毁了");
}
}
@WebFilter("/*)
public class BFilter implements Filter{
public void init(){
sout("BFliter创建了");
}
public void filter(ServletRequest request,ServletResponse response,){
sout("BFilter拦截了");
filterChain.doFiter(ServletRequest,ServletResponse);
}
public void destory(){
sout("BFilter销毁了");
}
}
使用注解改变过滤器执行顺序?;此时才会先执行AOFilter过滤器
推荐过滤器配置,基于xml配置
拦截方式(了解)
针对与访问资源方式,
- 重定向方式:直接访问方式:重定向,地址栏输入地址,超链接,
- 转发方式:请求转发
- error访问
- include包含
- DispatcherType拦截方式:
REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;默认值FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、- jsp:forward标签都是转发访问;INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、
- jsp:include标签都是包含访问;ERROR:当目标资源在web.xml中配置为<error-page>中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。
实现访问资源不存在时展示error自定义界面?
web.xml
<web-app>
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
<error-page>
</web-app>
使用过滤器实现编码处理优化,使得不用每个处理请求的servlet都要重复去处理编码问题!!!
1.全局编码处理
把请求编码,响应编码统一到过滤器处理
浏览器缓存:需要需要你手动清除缓存 ctrl F5
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");移入到过滤器当中
使用过滤器实现编码处理优化
create EncodingFilter.java in com.huse.filter
全局编码处理器 拦截/*
WebFilter(filterName = "EncodingFilter",value="/*)
public class EncodingFilter implements Filter {
init(){
}
doFilter(){
HttpServeltRequest request = (HttpServeltRequest)req;
HttpServeltResponse response = (HttpServeltResponse)resp;
if(request.getMethod().equals("POST")){
request.setCharacterEncoding("UTF-8");//post请求编码处理
}
response.setContentType("text/html;charset=utf-8");
//所有的静态和非静态资源都会被拦截执行这一行code
chain.doFilter(req,resp);
}
destory(){
}
}
使用注解改变过滤器执行顺序?;
使用过滤器实现编码处理优化
create EncodingFilter.java in com.huse.filter
全局编码处理器 拦截/*
WebFilter(filterName = "EncodingFilter",value="/*)
public class EncodingFilter implements Filter {
init(){
}
doFilter(){
HttpServeltRequest request = (HttpServeltRequest)req;
HttpServeltResponse response = (HttpServeltResponse)resp;
if(request.getMethod().equals("POST")){
request.setCharacterEncoding("UTF-8");//post请求编码处理
}
response.setContentType("text/html;charset=utf-8");
chain.doFilter(req,resp);
}
destory(){
}
}
WebFilter(filterName = "EncodingFilter",value="/*)
public class EncodingFilter implements Filter {
init(){
}
doFilter(){
HttpServeltRequest request = (HttpServeltRequest)req;
HttpServeltResponse response = (HttpServeltResponse)resp;
if(request.getMethod().equals("POST")){
request.setCharacterEncoding("UTF-8");//post请求编码处理
}
//图压,css.js 不应该设置text/html;charset=utf-8,动态资源text/html ; charset=utf-8 只针对Servlet设置
response.setContentType("text/html;charset=utf-8");
chain.doFilter(req,resp);
}
destory(){
}
}
//图片,css.js 不应该设置text/html;charset=utf-8,动态资源text/html ; charset=utf-8 只针对Servlet设置
//根据后缀名经行静态资源与servlet的区分
WebFilter(filterName = "EncodingFilter",value="/*)
public class EncodingFilter implements Filter {
init(){
}
doFilter(){
HttpServeltRequest request = (HttpServeltRequest)req;
HttpServeltResponse response = (HttpServeltResponse)resp;
String requestURI = request.getRequestURI();
if(!requestURI.contains(".")){
response.setContentType("text/html;charset=utf-8");
}
chain.doFilter(req,resp);
}
destory(){
}
}
请你把所有的servlet当中编码处理可以删除了
之前的下边的这段code也可以删除了
还有过滤器:重新重定向登录 放到过滤器当中
if(request.getSession().getAttribute("login") == null){
response.sendRedirect("/login.jsp");
return;
}
新建一个LoginFilter过滤器 拦截所有
静态资源不拦截只拦截过滤器 需要进行判断处理
写法一
doFilter(){
HttpServeltRequest request = (HttpServeltRequest)req;
HttpServeltResponse response = (HttpServeltResponse)resp;
String uri = request.getRequestURI();
if(uri.equals("login.jsp")){
chain.doFilter(req,resp);
return;
}
if(request.getSession().getAttribute("login") == null){
response.sendRedirect("/login.jsp");
return;
}
chain.doFilter(req,resp);
}
新建一个拦截页面 pages目录 里面是需要拦截 list.jsp update.jsp放到这个目录里面
doFilter(){
HttpServeltRequest request = (HttpServeltRequest)req;
HttpServeltResponse response = (HttpServeltResponse)resp;
String uri = request.getRequestURI();
if(uri.contains("pages") || uri.equals("/LoginServlet")){
chain.doFilter(req,resp);
return;
}
if(request.getSession().getAttribute("login") == null){
response.sendRedirect("/login.jsp");
return;
}
chain.doFilter(req,resp);
}
现在访问localhost:8080/login.jsp就可以访问了 目录外的表示可以放行