04 转发与重定向、cookie、Session、监听器、过滤器

本文详细介绍了HTTP的转发与重定向的区别与实现方式,探讨了Cookie的工作原理与操作,深入讲解了Session的创建、作用及操作,并详细阐述了监听器在ServletContext、HttpSession和ServletRequest中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、转发与重定向

1、简介

  • 什么是转发

    • 同一个请求作用域里面,从一个目标组件(jsp/Servlet)跳转到另一个目标组件(jsp/Servlet),url地址是不会发生改变的
  • 什么是重定向

    • 它其实也是从一个目标组件跳转到另一个目标组件,但不是在同一个请求作用域里面,并且url地址是发生改变的

2、原理问题

  • 如图以下描述
    在这里插入图片描述
    结论

  • 转发是属于同一个请求对象

  • 重定向是属于不同的请求对象,并且url地址会发生改变

3、如何实现转发

  • 实现转发有两种方式
写法一:
getServletContext().getRequestDispatcher("/BServlet").forward(request,response);
写法二:
request.getRequestDispatcher("/BServlet").forward(request,response);

举例

  • AServlet
package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = "/AServlet")
public class AServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("当前是A servlet");

        //将数据存储到request对象
        request.setAttribute("username","tom");

        //转发到B Servlet组件
        //request.getRequestDispatcher("/BServlet").forward(request,response);

        getServletContext().getRequestDispatcher("/BServlet").forward(request,response);

    }
}

  • BServlet
package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(value = "/BServlet")
public class BServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {

        String username= (String) request.getAttribute("username");
        resp.setCharacterEncoding("UTF-8");

        //设置响应文档类型
        resp.setContentType("text/html");
        PrintWriter pw=resp.getWriter();
        pw.println("<html>");
        pw.println("<body>");
        pw.println("<h1>");
        pw.println("当前是B Servlet  username="+username);
        pw.println("</h1>");
        pw.println("</body>");
        pw.println("</html>");
    }
}

4、如何实现重定向

  • 如何实现重定向
response.sendRedirect("/DServlet");

举例

  • CServlet类
package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = "/CServlet")
public class CServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("当前是C servlet");

        request.setAttribute("username","tom");

        //重定向到D Servlet
        response.sendRedirect("/DServlet");

    }
}

package com.gec.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(value = "/DServlet")
public class DServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {

        String result="";

        Object usernameObj=request.getAttribute("username");
        if(usernameObj==null)
        {
        //前端将会输出不能从request获取数据,因为不同请求对象
            result="不能从request获取数据";
        }else {
            result= (String) usernameObj;
        }

        resp.setCharacterEncoding("UTF-8");

        //设置响应文档类型
        resp.setContentType("text/html");
        PrintWriter pw=resp.getWriter();
        pw.println("<html>");
        pw.println("<body>");
        pw.println("<h1>");
        pw.println("当前是D Servlet  result="+result);
        pw.println("</h1>");
        pw.println("</body>");
        pw.println("</html>");

    }
}

二# 、Cookie用法

1、Cookie简介

  • 服务端将数据存储到客户端的磁盘,就是通过cookie机制实现。它是在客户端访问Web服务器时,服务器在客户端硬盘上存放的信息,服务器可以根据Cookie来跟踪客户状态。

2、作用

  • 服务器跟踪客户端的状态

3、原理

在这里插入图片描述
上述如图以下:

  • 客户端发送请求(还没有产生cookie数据)
  • 服务端生成cookie数据,将此cookie数据封装到响应头部信息内容
  • 客户端接受到响应头信息,解释cookie数据,将cookie数据保存到本地文cookie件
  • 下一次客户端再发请求给服务器,则从cookie文件取数据,将此数据封装到请求头,发送给服务器解释
  • 服务器解释cooke的请求头部数据,获取数据

4、如何实现cookie操作

  • 如何将数据存储到cookie
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

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


        //将数据存储到cookie
        //新建一个cookie对象,是以键值对保存的
        Cookie cookie=new Cookie("user","tom");
		//设置cookie的存活时间
        cookie.setMaxAge(7*24*60*60); //单位是“秒“,所以一星期内有效

        //将cookie数据写到http协议响应部分的头部信息
        response.addCookie(cookie);
  }

如何从cookie读取数据

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //读取cookie数据
        Cookie cookies[]=request.getCookies();

        for (Cookie cookie : cookies) {

            System.out.println("name="+cookie.getName()+"  value="+cookie.getValue());

        }
}

三、会话实现

1、简介

  • 当客户端发送请求给服务器,则已经建立一次会话(Session)关系

2、产生会话的条件

  • 当直接访问jsp页面

  • 在Servlet组件,request调用getSession()方法

//创建一次会话,也就是产生一个Session对象
HttpSession session=request.getSession();

或者
    
HttpSession session=request.getSession(true);

//若尚未存在HttpSession实例,则直接返回null,它不会创建新的Session对象
HttpSession session=request.getSession(false);

3、会话作用

  • http协议它是一种无状态的协议

    • http协议具有健忘症
      • 前一次请求的数据,会全部丢失
  • 如何将数据保存,使得每次请求都获取,这就依赖于session机制。

4、如何操作会话

  • 创建会话
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session=request.getSession();
        //将数据保存到会话对象session里面,我们就可以在其他servlet里面访问到数据了
        session.setAttribute("username",username);
        session.setAttribute("password",password);
	}
	//我们就可以在其他servlet里面访问到数据了,代码如下

获取会话信息

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session=request.getSession();

        //获取session数据
        String username= (String) session.getAttribute("username");
        String password= (String) session.getAttribute("password");
        //这里就获取到了username值和password值
    }

注销会话

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session对象
        HttpSession session=request.getSession();
        //注销会话
        session.invalidate();
    }

配置session有效期

  • 在web.xml文件配置
    <session-config>
        <!--默认分钟为单位-->
        <session-timeout>15</session-timeout>
    </session-config>

5、会话原理

  • 每次会话,都会独立产生一个session对象

  • 不同的主机,或者同一台主机(但不同的浏览器),产生会话对象是不同的
    在这里插入图片描述

  • 上述描述:

    • ServletContext它是Web应用的共享对象,也就是全局对象
    • 一般不用ServletContext对象保存数据,因为一个Web应用就对应一个ServletContext对象,当不同客户端同时访问这个Web应用时,对于ServletContext对象,后面的客户端的数据会覆盖前面客户端提交的数据。
    • Session是会话里面的共享对象
  • Session工作机制
    ····客户端发送请求到服务端,当直接访问jsp页面或者request调用getSession()方法时,产生会话,同时生成SessionId。
    ····服务端容器产生SessionId之后,被封装到响应的头部信息,记住传的是id,而不是username值和password的值
    ····接下来的步骤和cookie差不多
    ····最后web容器拿到sessionid再解析之后,就可以找到对应这个sessionid的数据,比如图中username=tom,password=1111,
    ····因此可以看出,username=tom,password=1111是
    在这里插入图片描述

四、监听器

1、简介

  • 针对HttpServletRequest、HttpSession、ServletContext对象的创建及销毁,实现事件监听

2、监听器类别

  • ServletContextListener
  • ServletContextAttributeListener
  • HttpSessionListener
  • HttpSessionAttributeListener
  • HttpSessionBindingListener
  • ServletRequestListener
  • ServletRequestAttributeListener

3、ServletContextListener用法

  • 简介

    • 监听ServletContext对象的创建及销毁
  • 什么时候创建ServletContext对象

    • 当启动Web应用
  • 什么时候销毁ServletContext对象

    • 当停止Web应用
  • 如何实现监听器

  • 加注解,实现接口,重写对应接口的两方法

    • 方式一:使用注解
@WebListener
public class MyServletContextListener implements ServletContextListener
{
    /*
    * 当Web应用启动,会触发此方法
    * */
    @Override
    public void contextInitialized(ServletContextEvent sce) {

        System.out.println("servletContext对象创建");
    }

    /*
    * 当Web应用停止,会触发此方法
    * */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {

        System.out.println("servletContext对象销毁");

    }
}

方式二:并在web.xml文件注册

public class MyServletContextListener implements ServletContextListener
{
    /*
    * 当Web应用启动,会触发此方法
    * */
    @Override
    public void contextInitialized(ServletContextEvent sce) {

        System.out.println("servletContext对象创建");
    }

    /*
    * 当Web应用停止,会触发此方法
    * */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {

        System.out.println("servletContext对象销毁");

    }
}

在web.xml文件注册

    <listener>
        <listener-class>com.gec.listener.MyServletContextListener</listener-class>
    </listener>

4、HttpSessionListener

  • 简介

    • 主要针对HttpSession对象的创建及销毁的监听
  • 举例

    • 通过注解创建监听器
package com.gec.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class MyHttpSessionListener implements HttpSessionListener {

    /*
    * 当会话创建,触发此方法
    * */
    @Override
    public void sessionCreated(HttpSessionEvent se) {


        System.out.println("会话创建  会话id="+se.getSession().getId());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {

        System.out.println("会话销毁  会话id="+se.getSession().getId());


    }
}

5、ServletRequestListener用法

  • 简介

    • 针对每次请求的创建及销毁的监听
  • 用法

    • 监听器
package listener;

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyServletRequestListener implements ServletRequestListener {


    @Override
    public void requestDestroyed(ServletRequestEvent sre) {

        System.out.println("请求对象销毁");

    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {

        System.out.println("请求对象创建");

    }
}

6、HttpSessionAttributeListener用法

  • 简介

    • 针对session对象的数据进行操作(添加、删除、替换)
  • 用法实现


@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {

    /*
    * 当数据添加到session,触发此方法
    * */
    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {

        System.out.println("当数据添加到session");
    }

    /*
    * 当数据从session移除,触发此方法
    * */
    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {

        System.out.println("当数据从session移除");
    }

    /*
    * 当数据从session替换,触发此方法
    * */
    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {

        System.out.println("当数据从session替换");


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值