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 -->