一、Filter:
该接口在HTTP服务器调用资源文件之前,对HTTP服务器进行拦截。
二、作用:
- 拦截HTTP服务器,帮助HTTP服务器检测当前请求合法性。
- 拦截HTTP服务器,对当前请求进行增强操作。
三、Filter接口实现类开发步骤
- 创建一个java类实现Filter接口
- 重写Filter接口中的doFilter方法
- 在web.xml文件中将过滤器接口注册到HTTP服务器
首先是过滤器第一个作用实例,帮助http服务器检测请求合法性。举个例子,用户携带参数访问http服务器上的某个资源文件,对当前参数进行判断,只有当用户参数合法时才允许其访问该文件。直白点说,某个网站资源只有当用户年龄大于18时才允许访问,否则将不允许访问。Filter接口就可以实现这个。
来看下代码,首先我在web包下放了一张x.png的图片。
接下来将通过get方式对这张图片进行访问,在浏览器地址栏输入localhost:8080/myweb/x.png?age=20
(参数直接打在url后面了,当然也可以通过表单等方式获取用户参数)。
过滤器接口通过请求对象拿到用户给的参数值,判断参数的合法性。如果合法,将把拦截的请求对象和响应对象还给http服务器。如果不合法,拒绝本次请求并在浏览器上展示给用户。
public class OneFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//1、通过拦截请求对象得到请求包参数信息,从而得到来访用户的真实年龄
String age=servletRequest.getParameter("age");
//2、根据年龄,帮助HTTP服务器判断本次请求合法性
if(Integer.valueOf(age)<18){//合法请求
//将拦截请求对象和响应对象交还给tomcat,由tomcat继续调用资源文件
filterChain.doFilter(servletRequest,servletResponse);//放行
}else{
//过滤器代替HTTP服务器拒绝本次请求
servletResponse.setContentType("text/html;charset=UTF-8");
PrintWriter out=servletResponse.getWriter();
out.print("<center><font style='color:red;font-size:40px'>不合法的请求</font></center>");
}
}
}
别忘了web.xml中注册filter
<!-- 将过滤器类文件路径交给tomcat -->
<filter>
<filter-name>OneFilter</filter-name>
<filter-class>com.luna.filter.OneFilter</filter-class>
</filter>
<!-- 通知tomcat在调用何种资源文件时使用过滤器 -->
<filter-mapping>
<filter-name>OneFilter</filter-name>
<url-pattern>/x.png</url-pattern>
</filter-mapping>
接下来是过滤器第二个作用实例,对当前请求进行增强操作。我们都知道,当浏览器以post方式发送请求给http服务器,那么http服务器收到请求协议包时会由当前请求对象request负责解码,而request默认使用ISO-8859-1字符集(一个东欧语系字符集)。如果拿到的参数是中文,控制台只能是乱码。这时我们的解决办法是:在读取请求体内容之前,应该通知请求对象使用utf-8解析。即读取参数之前应该有这样一行代码:request.setCharacterEncoding(“UTF-8”);
那么问题来了,如果你有100个servelt都需要接收浏览器以post方式发送的请求,那么这行代码要写100遍吗??
当然不用,Filter就是来解决这个问题的。
首先给一个html,里面有两个表单都是以post方式提交…
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<form action="/myweb/one" method="post">
参数:<input type="text" name="para"><br>
<input type="submit" value="以post方式获得OneServlet的参数">
</form>
<form action="/myweb/two" method="post">
参数:<input type="text" name="para"><br>
<input type="submit" value="以post方式获得TwoServlet的参数">
</form>
</center>
</body>
</html>
两个servlet,获取用户提交的参数
public class OneServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String para=request.getParameter("para");
System.out.println("OneServlet:"+para);
}
}
public class TwoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String para=request.getParameter("para");
System.out.println("TwoServlet:"+para);
}
}
然后就是Filter。只要在过滤器里将你想要过滤的操作写入,再将请求对象和响应对象还给http服务器。
public class OneFileter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");//设置过滤内容
filterChain.doFilter(servletRequest,servletResponse);//放行
}
}
web.xml注册不能忘,不然就没效果了。这个 标签中的/*表示过滤所有的资源文件。
<servlet>
<servlet-name>OneServlet</servlet-name>
<servlet-class>com.luna.controller.OneServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>TwoServlet</servlet-name>
<servlet-class>com.luna.controller.TwoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>OneServlet</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TwoServlet</servlet-name>
<url-pattern>/two</url-pattern>
</servlet-mapping>
<filter>
<filter-name>OneFilter</filter-name>
<filter-class>com.luna.filter.OneFileter</filter-class>
</filter>
<filter-mapping>
<filter-name>OneFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这样我们就会发现,两个servlet通过post提交的数据在控制台上都能够正常显示了。