Filter 过滤器
用来干嘛?
1.处理中文乱码
2.登陆验证
注意:导包别导错了
关于处理中文乱码
我们如果直接在Servlet里面在网页上打印数据
毫无疑问会乱码
我们之前是用
resp.setContentType("text/html;charset=utf-8");来设置发送到客户端的响应的内容类型和响应的字符编码 解决这个问题
但是如果我们要写1000个Servlet,就要写1000个这个语句,这肯定是每个人都不想看到的。
所以,当当当!filter出场了!
我们写个过滤器
import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
//初始化 在tomcat启动时就开始初始化,为了去随时监听请求
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器初始化");
}
//过滤器中的代码,会在执行所有规定的请求前执行
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
System.out.println("过滤器执行前");
//filterChain起到执行者的功能,只有写了这个语句过滤器才会执行功能
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("过滤器执行成功");
}
@Override
public void destroy() {
System.out.println("过滤器销毁了");
}
}
过滤器也要在web.xml里配置映射
<filter>
<filter-name>filter1</filter-name>
<filter-class>com.wjc.filter.CharacterEncodingFilter</filter-class>
</filter>
<!-- 该过滤器会过滤该url下的所有请求-->
<filter-mapping>
<filter-name>filter1</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
执行
如果不是规定的url范围下的不会过滤
我们来看一下控制台,理解一下它的生命周期
断开tomcat连接时,过滤器才销毁
其实过滤器是不是有点像面向切面编程aop那感觉了。。嘿嘿(个人想法
参考了一下Chain of Responsibility(职责链模式)
总结一下吧,就是原本Servlet可以自身要处理很多问题,但是耦合性非常强,而Filter就是它的一个帮手,所以Filter里面有个Chain,它是必要存在的。Filter专门处理某些问题,来分担职责了,降低了代码的耦合度,还能提高效率。
登陆验证
做了个小案例 先来看一下项目结构
定义一个常量
public class Constant {
public static final String USER_SESSION="USER_SESSION";
}
Login.jsp 登录主界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--form action="传递你表单的数值到指定页面。不写的话就相当于刷新网页。--%>
<form action="/servlet/login" method="post">
用户名:<input type="text" name="username"> <br>
<input type="submit">
</form>
</body>
</html>
web.xml
<filter>
<filter-name>logfile</filter-name>
<filter-class>com.wjc.filter.LoginFilter</filter-class>
</filter>
<!-- 该过滤器会过滤该url下的所有请求-->
<filter-mapping>
<filter-name>logfile</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.wjc.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LoginOutServlet</servlet-name>
<servlet-class>com.wjc.servlet.LoginOutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginOutServlet</servlet-name>
<url-pattern>/servlet/loginOut</url-pattern>
</servlet-mapping>
LoginServlet
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
if("admin".equals(username)){
//往session里面存入数据
req.getSession().setAttribute(Constant.USER_SESSION,req.getSession().getId());
//重定向,因为是session,别的页面也能拿到数据,转发不行
resp.sendRedirect("/sys/success.jsp");
}else{
resp.sendRedirect("/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
登陆成功
<p>
<a href="/servlet/loginOut">注销</a>
</p>
</body>
</html>
在登录成功页面有个注销功能
public class LoginOutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object user_session = req.getSession().getAttribute(Constant.USER_SESSION);
if(user_session!=null){
req.getSession().removeAttribute(Constant.USER_SESSION);
resp.sendRedirect("/Login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
出错了!
<a href="/Login.jsp">返回登录页面</a>
</body>
</html>
至此,会有个问题,就是你注销了删除了session里面username的值,如果直接访问success.jsp还是能访问。因此我们需要用过滤器来过滤访问success.jsp的请求
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
Object attribute = request.getSession().getAttribute(Constant.USER_SESSION);
if (attribute==null) {
response.sendRedirect("/error.jsp");
} else if ("admin".equals(attribute)) {
response.sendRedirect("/sys/success.jsp");
}
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
里面强转类型是因为我们Servlet里用的是HttpServletRequest 和HttpServletResponse,在web.xml配置相应的filter即可成功。