Cookie Session和过滤器Filter

发布时间:2024年01月09日

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。

会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自同一浏览器,以便在同一次会话的多次请求间实现资源共享。

因为http协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内资源共享。

实现方式:1、客户端会话跟踪技术:Cookie,把数据存放到客户度浏览器中。2、服务端会话跟踪技术:Session,把数据存放到服务端servlet中。

Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。

发送Cookie:

@WebServlet("/aServlet")
public class aServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //发送Cookie

        String value="张三";
        String encode = URLEncoder.encode(value,"UTF-8");

        //1.创建Cookie对象
        Cookie cookie=new Cookie("username",encode);

        cookie.setMaxAge(60*60*24*7);

        //2.发送Cookie
        response.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

接收Cookie:

@WebServlet("/bServlet")
public class bServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Cookie

        //1.获取Cookie数组
        Cookie[] cookies = request.getCookies();

        //2.遍历数组
        for (Cookie cookie : cookies) {
            //3.获取数据
            String name = cookie.getName();
            if ("username".equals(name)) {
                String value = cookie.getValue();
                String decode = URLDecoder.decode(value);
                System.out.println(name+":"+decode);
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

默认情况下Cookie存放在浏览器内存中,当浏览器关闭,内存释放,则Cookie释放。但我们可以设置Cookie存活时间,运用cookie.setMaxAge()方法,参数单位为秒。当传入参数为正数时,即为存入浏览器内存的时间,秒数。为负数时,默认值,Cookie在浏览器内存中,浏览器关闭时,则Cookie被销毁。为零时:删除对应的Cookie。

Session:服务端会话跟踪技术,将数据存放到服务端:

发送Session

@WebServlet("/Session1")
public class Session1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Session
        //1.创建Session
        HttpSession session = request.getSession();
        //2.存储数据
        session.setAttribute("username","zs");


    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

接收Session:

@WebServlet("/Session2")
public class Session2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Session数据
        //1.获取Session对象
        HttpSession session = request.getSession();

        //销毁
        //session.invalidate();//此时访问该网页,会报错

        //2.获取数据
        Object username = session.getAttribute("username");
        System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

Session是基于Cookie实现的,来保证同一个浏览器获取的Session是同一个Session。获取的Session有一个id属性,tomcat在浏览器做出响应的时候会自动把这个id属性当作一个Cookie发送给浏览器键值对为set-cookie:JSESSIONID=...,然后客户端就把这个浏览器在带着cookie头访问服务端来获取Session对象。

Session使用细节:

? Session钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘文件中。

? Session活化:再次启动浏览器后,会从文件中加载数据到Session中。这时硬盘中的文件已经消失了。

浏览器重启后,虽然数据未丢失,但因为浏览器被关闭了,所以重启浏览器获取的Session也不是原来那个了。

默认情况下,Session会30分钟后自动销毁。

Cookie和Session区别:

? 存储位置:Cookie是将数据存储在客户端,Session是将数据存储在服务端。

? 安全性:Cookie不安全,Session安全

? 数据大小:Cookie最大3KB,Session无大小限制。

? 存储时间:Cookie可以长期存储,Session默认30分钟。

? 服务器性能:Cookie不占服务器资源,Session占用服务器资源。

Filter,过滤器:是Javaweb三大组件(Servlet,Filter,Listener)之一。过滤器可以把对资源的请求拦截下来,从而实现一些特殊功能。过滤器一般实现比较通用的操作,比如:权限控制,统一编码处理,敏感字符处理等等。

Filter的定义:

?1、定义类,实现filter接口,并重写所有方法。

?2、配置Filter拦截资源路径,需要在类上定义注解@WebFilter()

?3、在doFiler方法中输出一句话,并放行,只有执行了chain.doFilter方法才会 被放行。

写在放行代码前的代码为放行前代码,后面的为放行后代码。

注意:

?1、放行后访问对应资源,资源访问完后还会回到Filter中。就是浏览器发送请求的时候会经过Filter,服务端做出响应的时候也会经过Filter。

?2、浏览器发送请求经过Filter时,只执行放行前代码。响应时返回Filter中,Filter中的代码,会从放行代码开始只执行放行后代码,不会从头开始执行。

Filter拦截路径设置

?1、拦截具体路径:具体资源路径

?2、目录拦截:/目录/*? ? 访问该目录下的所有资源都会被拦截

?3、后缀名拦截:*.jsp? ? 访问后缀名为jsp的资源都会被拦截

?4、拦截所有: /*? 所有资源都会被拦截。

@WebFilter("/*")
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 req = (HttpServletRequest) servletRequest;

        //0.判断访问是否是跟登陆有关的资源
         //是的话放行,不是就拦截
        String []urls={"/login.jsp","register.jsp","/loginServlet","/register.jsp","/register.html","/SelectUserServlet"};
        //获取资源访问路径
        String url = req.getRequestURI();
        //循环判断
        for (String u : urls) {
            if (url.contains(u)){
                filterChain.doFilter(servletRequest,servletResponse);

                return;
            }
        }
    }
 

    @Override
    public void destroy() {

    }
}

其中一些网站不需要被拦截,我们需要把不需要被拦截的网站写入一个数组。然后获取请求的网址,若请求的网址存在于数组中就会被放行,放行后直接return,这样后面的代码哪怕是响应时跳回Filter中都不会在被执行。

过滤器链:一个web应用,可以配置多个过滤器,这个过滤器称为过滤器链

?注解配置的多个Filter,优先级按照过滤器类名(字符串)的自然排序,就是从a到z,从0到9。依次访问拦截。

文章来源:https://blog.csdn.net/hguhbh/article/details/135483710
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。