Java研学-Web 组件交互与作用域

一 跳转与数据共享

   Jsp 和 Servlet 责任分离,可实现数据获取,查询等重复功能的复用
  ① Servlet 去数据库中查找
  ② Servlet 把数据给 jsp
  ③ jsp 把数据响应给浏览器
数据流转

二 转发重定向概述

1 作用

  利用 JSP, Servlet 完成 web 组件的跳转,从一个组件跳到另一个组件

2 转发

① 跳转位置
  服务器端进行的组件(资源)的跳转
② 转发原理
  转发是指由服务器端进行页面跳转
转发原理
③ 转发方法

// request 对象与转发相关方法
request.getRequestDispatcher("/要跳转到的地址").forward(request, response);

3 重定向

① 跳转位置
 &emsp浏览器端进行的页面(组件/资源)跳转
② 重定向原理
  重定向是指由客户端进行页面跳转
重定向原理
③ 重定向方法

// response对象与重定向相关方法
response.sendRedirect("要跳转的地址")

4 转发重定向的区别

区别转发 forward重定向 redirect
目录服务端的根目录:http://localhost:8080/项目地址/
跳转的 path 不用写项目路径(虚拟目录)
浏览器的根目录(端口之后):http://localhost:8080
跳转 path 需加上项目路径(虚拟目录)
地址栏地址栏不会发生变化,还是上一个地址会变化,显示新的地址
跳转位置服务端 进行跳转浏览器端 跳转
请求对象(域)请求域数据不会丢失,因为是同一个请求请求域数据会丢失,因为不是同一个请求
WEB-INF下资源请求转发可以跳转到WEB-INF 下的资源重定向不可以跳转到 WEB-INF 下的资源
跨域访问请求转发不可以跳转到其他域名或项目下的资源
(例:http://www.baidu.com)
重定向可以跳转到其他域名或项目下的资源
(例:http://www.baidu.com)

5 转发重定向演示

  创建两个Servlet通过转发重定向实现页面间的跳转
① 一号Servlet

package com.tj;

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(urlPatterns = "/that")
public class ThatServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println(username);
        // 转发到 twoServlet
        req.getRequestDispatcher("/this").forward(req,resp);
        // 可以跳转到 WEB-INF 中
        // req.getRequestDispatcher("/WEB-INF/index.jsp").forward(req,resp);
        // 不能访问到别人的项目(外域)
        //req.getRequestDispatcher("https://www.bilibili.com/").forward(req,resp);
        // 重定向到 ThisServlet
        //resp.sendRedirect("/untitled6/com/tj/ThisServlet");
        // 不可以访问 WEB-INF 下的资源
        // resp.sendRedirect("/WEB-INF/index.jsp");
        // 可以访问其他项目(外域)
        // resp.sendRedirect("https://www.bilibili.com/");
        System.out.println("后面代码可以执行,但是无意义");
    }
}

② 二号Servlet

package com.tj;

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(urlPatterns = "/this")
public class ThisServlet extends HttpServlet{
    protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
        // 设置内容类型和编码
        resp.setContentType("text/html;charset=utf-8");
        // 获得字符打印流
        PrintWriter out = resp.getWriter();
        out.print("ThisServlet");
    }
}

6 一些细节

① 使用转发可保留请求域中的数据,还可以跳转到 WEB-INF 目录中的页面(资源)
② 使用重定向可访问其他项目(跨域),但不能跳转到 WEB-INF 目录中的页面(资源)
③ 重定向与转发的后续代码都会执行,但没有执行的意义,因为不管是转发还是重定向浏览器最终显示的都是跳转后页面的数据

三 三大作用域

1 作用

  用于 Servlet 之间数据共享的服务器内存区域,作用域结构是一个Map<String, Object>
  作用域范围:请求域–>会话域–>上下文域(由小到大)
作用域

2 类型

作用域类型作用范围
请求域HttpServletRequest只在同一次请求中起作用
会话域HttpSession同一个会话中起作用浏览器第1次访问服务器直到浏览器关闭的整个过程称为1次会话
上下文域ServletContext同一个应用中起作用服务器启动直到服务器关闭的整个过程都起作用

3 方法

作用域有关的方法作用
Object getAttribute(“键”)从中得到一个值
void setAttribute(“键”,Object数据)向作用域中存储键值对数据
void removeAttribute(“键”)删除作用域中的键值对数据

不同的作用域对象调用方法会对应操作不同的作用域数据

4 操作

  于 ThisServlet 存储键值到作用域中,转发至另一个 ThatServlet,从 ThatServlet中取出键值并且输出

ThisServlet
package com.tj;

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(urlPatterns = "/this")
public class ThisServlet extends HttpServlet{
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 存储键值对到请求域
        req.setAttribute("name", "request");
        // 存储键值对到会话域
        req.getSession().setAttribute("name", "session");
        // 存储键值对到上下文域
        req.getServletContext().setAttribute("name", "servletContext");
        // 转发到second
        req.getRequestDispatcher("/that").forward(req, resp);
    }
}
ThatServlet
package com.tj;

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(urlPatterns = "/that")
public class ThatServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 设置内容类型和编码
        resp.setContentType("text/html;charset=utf-8");
        // 获得字符打印流
        PrintWriter out = resp.getWriter();
        // 从请求域中获取数据
        Object reqName = req.getAttribute("name");
        // 从会话域中获取数据
        Object sessionName = req.getSession().getAttribute("name");
        // 从上下文域中获取数据
        Object appName = req.getServletContext().getAttribute("name");
        out.print("请求域数据:" + reqName + "<br>");
        out.print("会话域数据:" + sessionName + "<br>");
        out.print("上下文域数据:" + appName + "<br>");
    }
}