05-servlet-filter
使用流程:
1. 配置相关web.xml配置
2. 写一个servlet,在web.xml注册。
3. 创一个filter包,在里面写相关的filter,并且在web.xml注册。
//初始化:web服务器启动,就已经初始化了,随时等待过滤对象出现。
public class CharacterEncodingFilter implements Filter {
//初始化:web服务器启动,就已经初始化了,随时等待过滤对象出现。
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
/*
1、过滤中的所有代码,在过滤特定请求的时候都会执行
2、必须要让过滤器继续同行
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("CharacterEncodingFilter执行前...");
chain.doFilter(request, response);//让我们的请求继续走,如果不写,就不走,程序到这里就被拦截停止!
System.out.println("CharacterEncodingFilter执行后...");
}
public void destroy() {
System.gc();
System.out.println("CharacterEncodingFilter销毁");
}
}
注册:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.hjh.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
常用配置项:urlPatterns
配置要拦截的资源
- 以指定资源匹配。例如"/index.jsp"
- 以目录匹配。例如"/servlet/*"
- 以后缀名匹配,例如"*.jsp"
- 通配符,拦截所有web资源。"/*"
多个Filter的执行顺序
在我们的请求到达Servle之间是可以经过多个Filter的,一般来说,建议Filter之间不要有关联,各自处理各自的逻辑即可。这样,我们也无需关心执行顺序问题。
如果一定要确保执行顺序,就要对配置进行修改了,执行顺序如下:
在web.xml中,filter执行顺序跟<filter-mapping>的顺序有关,先声明的先执行
使用注解配置的话,filter的执行顺序跟名称的字母顺序有关,例如AFilter会比BFilter先执行
如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter
应用场景:
登录注销
实现流程:
- 登录页面,走一个登录请求和post方法。
- 登录请求:/servlet/login (请求路径对应web.xml所注册servlet的url-pattern)
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/servlet/login" method="post">
<input type="text" name="username">
<input type="submit">
</form>
</body>
</html>
- LoginServlet,通过servlet判断用户是否登录成功。
//获取前端请求的参数
String username = req.getParameter("username");
if (username.equals("admin")) {
req.getSession().setAttribute(Constant.USER_SESSION, req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");
} else {
resp.sendRedirect("/error.jsp");
}
在web.xml中注册
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.hjh.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
- 以上操作只是通过是否登录成功来决定是否跳转,并没有真正过滤此时用户是否仍然登录。所以需要有过滤器去做用户session判断。
过滤器如下:
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if (request.getSession().getAttribute(Constant.USER_SESSION) == null) {
response.sendRedirect("/error.jsp");
}
chain.doFilter(request, response);
}
- 然后在web\WEB-INF\web.xml中注册该filter,过滤的路径为 /sys/*
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.hjh.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
- 至此,就实现了登录过滤。