Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,把这个java类称为过滤器Filter.
开发人员可以实现用户在访问某个资源前后进行拦截处理。访问web容器前和响应前进行处理
常用的Filter
验证过滤器
日志过滤器
图像转换过滤器
数据压缩过滤器
加密过滤器
标记过滤器
触发资源访问事件
Mime类型链
XSL/T过滤器
常用方法
void init(FilterConfig fig)Filter被初始化
void destroy()此方法仅在过滤器所在线程都退出之后调用,或在过了超时期之后调用
doFilter(ServletRequest req,ServletResponse resp,FilterChain chain)
FilterChain是servlet容器为开发人员提供的对象。过滤器使用FilterChain调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器,则调用链末尾的资源。
方法doFilter(ServletRequest req,ServletResponse resp)
传递给下一个Filter,或是资源。
首页代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="login.html">用户登录</a><br/><br/>
<a href="control/test?test=你好">访问TestServlet(需要登录后才能访问)</a>
</body>
</html>
登录页面代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<fieldset>
<legend>登录</legend>
<form action="login" method="post">
<p>
用户名:<input name="name">
密码:<input type="password" name="password">
<input type="reset" name="reset" value="取消">取消
<input type="submit" name="submit" value="确定">确定
</p>
</form>
</fieldset>
</body>
</html>
验证登录的Servlet
package com.iotek.jee.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String password = req.getParameter("password");
System.out.println("user name:"+name);
if("admin".equals(name)&&"12345".equals(password)){
HttpSession session = req.getSession();
session.setAttribute("user_name",name);
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("<h3>欢迎"+name+"访问LoginServlet</h3><a href='index.html'>返回首页</a>");
}else{
resp.sendRedirect("login.html");
}
}
}
登录成功后才可以访问的Servlet
package com.iotek.jee.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession(false);
String name = (String) session.getAttribute("user_name");
String test = req.getParameter("test");
resp.getWriter().write("<h3>欢迎"+name+" "+test+"访问TestServlet</h3><a href='../index.html'>返回首页</a>");
}
}
验证Filter生命周期
package com.iotek.jee.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;
public class LifeCycleFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
print("init");
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
print("doFilter");
chain.doFilter(req, resp);
print("chain doFilter end");
}
@Override
public void destroy() {
print("destroy");
}
void print(String info){
System.out.println(info+" thread name: "+Thread.currentThread().getName());
}
}
验证字符编码的Filter
package com.iotek.jee.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;
public class EncodingFilter implements Filter {
private String encoding="GBK";
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
req.setCharacterEncoding(encoding);
chain.doFilter(req, resp);
}
@Override
public void init(FilterConfig config) throws ServletException {
encoding = config.getInitParameter("encoding");
}
}
登录成功后要想访问TestServlet需要经过验证的Filter
package com.iotek.jee.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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginValidationFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
HttpSession session = request.getSession(false);
if(session==null || session.getAttribute("user_name")==null){
response.sendRedirect("../login.html");
}else{
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<filter>
<filter-name>LifeCycleFilter</filter-name>
<filter-class>com.iotek.jee.filter.LifeCycleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LifeCycleFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.iotek.jee.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.iotek.jee.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/control/test</url-pattern>
</servlet-mapping>
<filter>
<filter-name>LoginValidationFilter</filter-name>
<filter-class>com.iotek.jee.filter.LoginValidationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginValidationFilter</filter-name>
<url-pattern>/control/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.iotek.jee.filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Filter的配置问题:
当URL-pattern属性相同时按先后顺序验证
属性不相同时按越小范围越后验证的方式。
还有字符编码问题,可以在server.xml文件中配置
<Connector connectionTimeout="20000" port="8088" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>
省的以后还要在定义字符编码的Filter,避免将html,css等等都要过滤一遍。
可以将某一类需要验证的Servlet放在同一个虚拟文件夹下面