过滤器的简介跟简单应用(禁止缓存,设置中文乱码等)
1.介绍
* servlet技术:Servlet、Filter(过滤器)、Listener(监听器)
* servlet:能做什么
* filter: 是否能做
* listener:在做什么
* 过滤器Filter
* sun提供对,静态web资源(html/image/avi等)或动态web资源(servlet,jsp),进行拦截(过滤)的技术
* 实现接口:javax.servlet.Filter
2.过滤器编写流程
* 编写实现类
* 配置web.xml
3.过滤器的生命周期
* 初始化方法:init(FilterConfig) ,
* 初始化时间:服务器启动时
* FilterConfig对象,当前过滤器的配置描述对象
* java.lang.String getFilterName() ,获得过滤器的名称,web.xml<filter><filter-name>
* java.lang.String getInitParameter(java.lang.String name) ,获得当前web.xml文件中配置的初始化参数
* java.util.Enumeration getInitParameterNames() ,获得所有的名称
* ServletContext getServletContext() ,获得当前web项目的上下文对象的引用。
* 拦截方法:doFitter(ServletRequest,ServletResponse,FilterChain)
* 每一次请求时,进行拦截。
* 注意:请求路径必须与拦截的配置路基吻合
* 销毁方法:destroy()
* 销毁时间:服务器正常关闭时
4、doFilter详解
* request和response与servlet相同
* javax.servlet.ServletRequest接口,子接口 javax.servlet.http.HttpServletRequest
* javax.servlet.ServletResponse接口,子接口 javax.servlet.http.HttpServletResponse
* 强制转换:
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
* FilterChain,过滤器链
* 将与请求资源吻合的所有过滤器组成一个过滤器链,如果所有的过滤器都放行,请求资源才可以被访问
* 放行:chain.doFilter(request,response );
* 切忌:编写过滤器时,必须先写“放行”语句
5.web.xml配置
* 注册过滤器
* <filter-name>,给已经注册的过滤器,名一个当前web.xml文件的中的唯一名称
* <filter-class>,需要注册的过滤器类的完整路径名
* 配置初始化参数
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
* 映射过滤器
* <filter-name> 在当前映射之前已经注册的过滤器的名称
* <url-pattern> 过滤器也是通过请求路径进行拦截
* 完整路径名匹配,/demo/testServlet
* 不完整路径名匹配:/demo/*
* 扩展名匹配:*.jsp | *.action
* 多个过滤器的过滤顺序:<filter-mapping>在web.xml文档中的顺序就是拦截顺序
* 注册一个filter,可以存在多个映射
<filter>
<filter-name>demo1</filter-name>
<filter-class>xxx</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<url-pattern>/demo1</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>demo1</filter-name>
<url-pattern>/demo2</url-pattern>
</filter-mapping>
* 注册多个filter,使用一个映射
<filter>
<filter-name>demo2</filter-name>
<filter-class>yyy</filter-class>
</filter>
<filter>
<filter-name>demo3</filter-name>
<filter-class>zzz</filter-class>
</filter>
<filter-mapping>
<filter-name>demo2</filter-name>
<url-pattern>/demo2</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>demo3</filter-name>
<url-pattern>/demo2</url-pattern>
</filter-mapping>
* dispatcher标签
* 位置:<filter-mapping><dispatcher>
* 取值
* REQUEST,request,确定当前过滤器拦截请求的资源,默认值(浏览器-->服务器)
* FORWARD,forward,确定当前过滤器拦截转发的资源,(服务器 --> 服务器)
* INCLUDE,include,确定当前过滤器拦截包含的资源,(服务器 --> 服务器)
* ERROR,error,确定当前过滤器拦截错误的资源,在web.xml文件中配置有好页面
* ASYNC,async,确定当前过滤器拦截异步的资源 (java ee 6.0 /servlet 3.0)
* 现在web项目 java ee 5.0 /servlet2.5 ,不支持异步和注解
Java代码解析
1、配置整站编码
java代码:
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class Demo1EncodingFilter implements Filter { private String encoding ; private String contentType ; @Override public void init(FilterConfig config) throws ServletException { encoding = config.getInitParameter("encoding"); contentType = config.getInitParameter("contentType"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //设置中文编码 request.setCharacterEncoding(this.encoding); response.setContentType(this.contentType); //放行 chain.doFilter(request, response); } @Override public void destroy() { } }
web.xml配置:
<!-- 中文过滤器 start --> <filter> <filter-name>Demo1EncodingFilter</filter-name> <filter-class>cn.itcast.filter.demo1.Demo1EncodingFilter</filter-class> <!-- 给当前过滤器配置初始化参数 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>contentType</param-name> <param-value>text/html;charset=UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>Demo1EncodingFilter</filter-name> <url-pattern>/demo1/*</url-pattern> </filter-mapping>
2、.配置所有的图片不进行缓存
java代码:
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DispatcherImageNoCacher implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; /* * <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> */ response.setDateHeader("expires", -1); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); chain.doFilter(request, response); } @Override public void destroy() { } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <%=request.getContextPath() %> <form action="${pageContext.request.contextPath}/login/loginServlet" method="post"> <table border="1"> <tr> <td>用户名</td> <td><input type="text" name="username" /></td> </tr> <tr> <td>密码</td> <td><input type="password" name="password" /></td> </tr> <tr> <td></td> <td><input type="checkbox" name="remeberme" />自动登录</td> </tr> <tr> <td></td> <td><input type="submit" value="登录"/></td> </tr> </table> </form> </body> </html>
web.xml配置
<!-- 图片不缓存 --> <filter> <filter-name>DispatcherImageNoCacher</filter-name> <filter-class>cn.itcast.filter.dispatcher.demo2.DispatcherImageNoCacher</filter-class> </filter> <filter-mapping> <filter-name>DispatcherImageNoCacher</filter-name> <url-pattern>*.jpg</url-pattern> <url-pattern>*.gif</url-pattern> </filter-mapping>
jsp页面:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <img src="1.jpg"/> <img src="2.jpg"/> <img src="3.jpg"/> </body> </html>
3、设置图片的有效时间
java代码
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ExpiresImageDemo3 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) resp; HttpServletRequest request = (HttpServletRequest) req; response.setDateHeader("expires", System.currentTimeMillis() + 1000l * 60 * 60 * 24 * 30); chain.doFilter(request, response); } @Override public void destroy() { } }
web.xml配置
<!-- 图片有效时间 --> <filter> <filter-name>ExpiresImageDemo3</filter-name> <filter-class>cn.itcast.filter.expires.demo3.ExpiresImageDemo3</filter-class> </filter> <filter-mapping> <filter-name>ExpiresImageDemo3</filter-name> <url-pattern>*.jpg</url-pattern> <url-pattern>*.gif</url-pattern> </filter-mapping>
4、 自动登录(session,cookie)
* 如果用户已经登录,并且需要自动登录,将用户的信息保存到cookie
* 如果用户访问其他页面,通过cookie信息判断进行自动登录,将登录的用户写的session
Filter代码:
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.itcast.login.domain.User; public class LoginFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //1判读用户是否登录 session User user = (User) request.getSession().getAttribute("loginUser"); if(user != null){ chain.doFilter(request, response); } else { //2获得cookie Cookie[] allCookie = request.getCookies(); if(allCookie != null){ //3自动登录user session String loginUserCookieValue = null; for(Cookie cookie : allCookie){ if("loginCookie".equals(cookie.getName())){ loginUserCookieValue = cookie.getValue(); break; } } //勾选了自动登录 if(loginUserCookieValue != null){ //查询数据库 User loginUser = new User(); loginUser.setUsername(loginUserCookieValue.split("@")[0]); loginUser.setPassword(loginUserCookieValue.split("@")[1]); //将用户信息放置session request.getSession().setAttribute("loginUser", loginUser); } } chain.doFilter(request, response); } //chain.doFilter(request, response); }
servlet代码:
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.itcast.login.domain.User; public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); //1获得数据--并封装 String username = request.getParameter("username"); String password = request.getParameter("password"); String remeberme = request.getParameter("remeberme"); //没有选为null ,选中默认为on User user = new User(username, password); //2在数据库中查询账号与密码是否匹配,如果匹配,将用户信息放置到session, // * 假设 jack 1234 if("jack".equals(user.getUsername()) && "1234".equals(user.getPassword())){ //登录成功 // * 是否选中自动登录 if(remeberme != null){ // ## 自动登录 --将用户的信息放置到cookie,下一次浏览器将携带 Cookie loginCookie = new Cookie("loginCookie",user.getUsername() + "@" + user.getPassword()); loginCookie.setMaxAge(60 * 60 * 24); loginCookie.setPath("/"); //所有人可以访问 //将cookie通知浏览器 response.addCookie(loginCookie); } //用户信息session request.getSession().setAttribute("loginUser", user); //转发 //request.getRequestDispatcher("/login/show.jsp").forward(request, response); response.sendRedirect(request.getContextPath() + "/login/show.jsp"); } else { //不成功 response.getWriter().print("您没有登录"); } //3选择视图--展示登录之后的页面 } }
Jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <%=request.getContextPath() %> <form action="${pageContext.request.contextPath}/login/loginServlet" method="post"> <table border="1"> <tr> <td>用户名</td> <td><input type="text" name="username" /></td> </tr> <tr> <td>密码</td> <td><input type="password" name="password" /></td> </tr> <tr> <td></td> <td><input type="checkbox" name="remeberme" />自动登录</td> </tr> <tr> <td></td> <td><input type="submit" value="登录"/></td> </tr> </table> </form> </body> </html>
实体类:
public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [username=" + username + ", password=" + password + "]"; } public User() { super(); } public User(String username, String password) { super(); this.username = username; this.password = password; } }
web.xml配置文件
<!-- login start --> <filter> <filter-name>LoginFilter</filter-name> <filter-class>cn.itcast.login.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>LoginFilter</filter-name> <url-pattern>/login/*</url-pattern> </filter-mapping> <!-- login end -->