我用代码教会你:Filter做登录拦截
1.前言
在大家刚开始学习Java Web时,相信最先接触到的一定是JSP + Servlet来开发web应用。这里我们来唠一唠Servlet中的过滤器Filter的使用,以及相应的实际开发场景。
2.Filter是什么?
2.1官方这么定义Filter
过滤器(Filter)是一个对象,它对资源(servlet或静态内容)的请求或资源的响应执行过滤任务,或对两者执行过滤任务。——摘自JavaEE6文档
2.2查看Filter文档
Java EE6文档:https://tool.oschina.net/apidocs/apidoc?api=javaEE6
3.Filter执行流程图解
4.实际开发场景中的Filter
4.1统一编码处理
4.1.1业务场景
在我们开发Java Web中,form表单经常需要填写中文并且传递到服务器中进行存储。因此,我们进行需要处理乱码问题。
若注册表单有中文参数,则处理注册的Servlet就需要处理中文乱码问题;若登录表单有中文参数,则处理登录的Servlet就需要处理中文乱码问题;2个表单有中文就要处理2次,那10个form表单,100个form表单呢???
因此,通过Filter来统一处理所有请求的中文乱码问题,非常的酸爽。下面我们用代码演示下:
4.1.2项目结构
PS:此时我们实现一个这样的效果:写2个表单分别是login.jsp与register.jsp,填写中文进行提交表单。通过filter进行统一处理多个表单的中文乱码问题。
4.1.3 处理表单的Servlet
RegisterServlet:
@WebServlet(name = "RegisterServlet",urlPatterns = "/register.do")
public class RegisterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收参数
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
System.out.println("username:"+username+",pwd:"+pwd);
request.getRequestDispatcher("login.jsp").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
LoginServlet:
@WebServlet(name = "LoginServlet",urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
System.out.println("username:"+username+",pwd:"+pwd);
request.getRequestDispatcher("index.jsp").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
4.1.4 注册与登录的JSP页面
登录表单:
注册表单:
4.1.5 使用Filter处理所有请求的中文乱码
@WebFilter(filterName = "CommonFilter",urlPatterns = "*.do")
public class CommonFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("--------公共拦截器--start----------");
//当每个表单中都有中文提交时,此时Servlet都需要进行乱码处理
req.setCharacterEncoding("UTF-8");
chain.doFilter(req, resp);//放行
System.out.println("--------公共拦截器--end----------");
}
public void init(FilterConfig config) throws ServletException {
}
}
4.1.6 演示效果
在登录页面,或者注册页面填入中文后,Servlet即使不做中文乱码处理也能接收中文了。因为Filter帮我们做了中文乱码处理
如下图:
4.2用户登录拦截器
4.2.1业务场景
在实际开发中,有很多请求是需要用户登录后才能进行访问的。例如:我们登录到淘宝,你查看购物车,或者查看订单列表就会提示登陆。下面我用代码告诉你,怎么实现???
4.2.2 项目结构
PS:此时我们实现一个效果,当用户在index.jsp中跳转到"订单列表"时,通过filter进行拦截,判断用户是否登录,如果未登录则跳转到登陆页面让用户进行登录。
4.2.2 在上个例子的基础上,做如下准备:
订单列表:Order.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>订单列表</title>
</head>
<body>
<h1>订单列表</h1>
</body>
</html>
主页:index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页</title>
</head>
<body>
<h1>welcome to index.jsp!</h1>
<a href="login.jsp">登录</a>
<a href="register.jsp">注册</a>
<a href="${pageContext.request.contextPath}/order/showOrder.do">查看订单列表</a>
</body>
</html>
OrderServlet:
@WebServlet(name = "OrderServlet",urlPatterns = "/order/showOrder.do")
public class OrderServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("------------展示订单列表-------------");
request.getRequestDispatcher("index.jsp").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
4.2.3 编写登录拦截器
@WebFilter(filterName = "LoginFilter",urlPatterns = "/order/*")
public class LoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("--------登录拦截器--start----------");
//涉及到4个作用域
HttpServletRequest request = (HttpServletRequest)req;
HttpSession session = request.getSession();
String userName = (String) session.getAttribute("session_user");
if(userName!=null&!"".equals(userName)){
//说明用户登录了
chain.doFilter(req, resp);//放行
}else{
//说明用户未登录
//跳转到登陆页面
request.setAttribute("tip","请先登录!");
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}
System.out.println("--------登录拦截器--end----------");
}
public void init(FilterConfig config) throws ServletException {
}
}
4.2.4 演示效果
1)在index.jsp页面直接访问"查看订单列表"
2)由于用户未登录而跳转到登陆页面并提示
3)通过查看控制台打印数据,观察并思考多个拦截器之间执行返回流程。
4.3其他场景应用
1)身份验证过滤器
2)日志和审核过滤器
3)图像转换过滤器
4)数据压缩过滤器
5)加密的过滤器
该篇博文通过2个实例来熟悉Filter在实际开发场景中的作用,当熟悉了这2个实例后,其他业务场景的应用,以后用到了再去实现。