欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Session和过滤器

程序员文章站 2022-05-23 08:44:30
...
1. Session技术
1.1.1 Session介绍

Session是服务器技术,数据是保存在服务器端。
可以解决浏览器保存Cookie遇到的问题,例如: 中文支持,数据量大小,数据个数…

【注意】
Session是依赖于Cookie来完成的!!!
如果浏览器关闭了Cookie功能,会导致Session功能无法使用【非绝对】
可以利用URL参数来解决Session信息验证问题,但是非常麻烦!

Session可以保留浏览器和服务器直接的交互数据,同时Session也是一个域对象!!
1. 一个Session对象可以存储多个键值对信息,并且支持任意类型,包括中文字符串
2. Session没有严格的大小限制
3. Session是保留在服务器端,从理论角度分析,只要硬盘足够大,存什么都行,数量不限制
4. 每一个浏览器请求会对应一个Session对象,如果需要在之后的请求中想要继续获取Session,需要保存一个核心的Cookie信息 JSESSIONID UUID

1.3.2 Session方法总结

通过HttpServletRequest对象获取Session对象
HttpSession session = getSession(boolean create);
如果传入false,要求必须验证Cookie名字为JSESSIONID 的cookie,如果没有Cookie或者Cookie存储的JSESSIONID 服务器端不存在,返回值为null,无对应Session,反之返回对应Session对象
如果传入是true,首先通过Cookie获取对应验证Session,如果没有获取到对应Session,创建新Session,并且生成一个新的SessionID

String getId();
获取Session对象的ID号,在当前服务器中具有唯一性

setInactiveInterval(int sec);
设置Session对象的有效时间,所谓有效时间,是从用户请求时间开始计算,如果在有效时间内用户重新发送了带有对应SessionID Cookie的请求,有效时间从新计算,如果设置0或者负数,有效时间为永久

invalidate();
在服务器端销毁Session对象

Session也是一个域对象
存在setAttribute,getAttribute,removeAttribute方法
1.1.3 使用Session和Cookie完成自动登录Session和过滤器

代码实现:
主页面:

@WebServlet("/index.do")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 获取Session 非创建模式
    HttpSession session = req.getSession(false);

    if (null == session) {
        resp.sendRedirect("login.html");
    } else {
        resp.setContentType("text/html;charset=utf-8");

        resp.getWriter().append("<h1>欢迎光临" + session.getAttribute("userName") + "</h1>");
        resp.getWriter().append("<h3><a href='logout.do'>退出</a></h3>");
    }
}

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws 	ServletException, IOException {
    	doGet(req, resp);
	}
}

登录页面:

@WebServlet("/login.do")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    User user = new User();
    req.setCharacterEncoding("utf-8");

    Map<String, String[]> parameterMap = req.getParameterMap();

    try {
        BeanUtils.populate(user, parameterMap);
    } catch (IllegalAccessException | InvocationTargetException e) {
        e.printStackTrace();
    }

    String sql = "select * from user where name = ? and password = ?";
    Object[] params = {user.getName(), user.getPassword()};
    List<User> query = new BaseDao().query(sql, params, User.class);

    if (query != null) {
        /*
         登陆成功
         创建Seesion
        */
        HttpSession session = req.getSession(true);
        session.setAttribute("userName", user.getName());

        Cookie jsessionid = new Cookie("JSESSIONID", session.getId());
        jsessionid.setMaxAge(60 * 60);
        resp.addCookie(jsessionid);

        resp.sendRedirect("index.do");
    } else {
        // 登陆失败,回到登陆页面
        resp.sendRedirect("login.html");
    }
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   	 doGet(req, resp);
	}
}

退出页面:

@WebServlet("/logout.do")
public class LogouServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    HttpSession session = req.getSession(false);

    session.invalidate();

    Cookie jsessionid = new Cookie("JSESSIONID", "");
    jsessionid.setMaxAge(0);
    resp.addCookie(jsessionid);

    resp.sendRedirect("index.do");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req, resp);
  }
}
2.过滤器
2.1 什么是过滤器

interface FilenameFilter 文件名过滤器

public boolean accept(File dir, String name);

Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。

JavaWEB开发中,过滤器作用,限制用户的一些操作。
JavaWEB三大组件 Servlet Filter Listener

2.2 第一个过滤器
2.2.1 web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <filter>
        <filter-name>AFilter</filter-name>
        <filter-class>com.qfedu.a_filter.AFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AFilter</filter-name>
        <!-- 需要限制哪些路径对应的资源 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
2.2.2 @WebFilter注解配置
package com.qfedu.a_filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class AFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("AFilter Working...");
        chain.doFilter(request, response);
        System.out.println("AFilter Ending...");
    }

    @Override
    public void destroy() {

    }
}
1.2.3 过滤器链

在资源放行前,过滤请求,在资源放行后,过滤响应,多个过滤器之间过滤成链)

通常客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。
每个过滤器实现某个特定的功能,一个过滤器检测多个Servlet。(匹配几个,检测几个)。
一组过滤器中的执行顺序与<filter-mapping>的配置顺序呢有关。
当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源
2.5 过滤器的优先级
在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter。当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源

如果为注解的话,是按照类名的字符串顺序进行起作用的
如果web.xml,按照 filter-mapping注册顺序,从上往下
web.xml配置高于注解方式
推荐使用xml方式进行配置
2.7 过滤器的优点

可以实现 Web 应用程序中的预处理和后期处理逻辑

 chain.doFilter(req, resp);//资源放行
如果不去执行这一句话,那么请求就会被拦截,不再继续往下走
在资源放行的前后,我们可以对请求进行处理和对响应进行处理
2.8 过滤器的典型应用

过滤器的作用来看

1.过滤所有的请求,因为他是在servlet.jsp.html等资源执行之前执行,可以类似封装的作用,比如处理乱码
2.可以在资源放行之前,对request进行处理,过滤敏感词
3.我们可以在资源放行之后,对资源响应给浏览器的response进行相关处理:压缩响应内容