Servlet-学习笔记-下

9. 请求转发和响应重定向

9.1 概述

什么是请求转发和响应重定向

  • 请求转发和响应重定向是web应用中间接访问项目资源的两种手段,也是Servlet控制页面跳转的两种手段

  • 请求转发通过HttpServletRequest 实现,响应重定向通过HttpServletResponse 实现

  • 请求转发生活举例:张三找李四借钱,李四没有,李四找王五,让王五借给张三

  • 响应重定向生活举例:张三找李四借钱,李四没有,李四让张三找王五,张三自己再去找王五借钱

9.2 请求转发

请求转发运行逻辑图

  1. 请求转发时,请求和响应对象会继续传递给下一个资源

  2. 请求中的参数可以继续向下传递

  3. 请求转发时服务器内部的行为,客户端是不知道的

  4. 客户端只产生了一次请求

请求转发的特点

  • 1 请求转发是通过HttpServletRequest 对象实现的

  • 2 请求转发是服务器内部行为,对客户端是屏蔽的

  • 3 客户端只产生了一次请求 服务端只产生了一对 request 和 response 对象

  • 4 客户端的地址栏是不变的

  • 5 请求的参数是可以继续传递的

  • 6 目标资源可以是servlet动态资源 也可以是html静态资源

  • 7 目标资源可以是WEB-INF 下的受保护资源 该方式也是WEB-INF 下的资源的唯一访问方式

  • 8 目标资源不可以是项目外部的资源

代码实现

package com.mdklea.servlet;
​
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
​
import java.io.IOException;
​
/**
 * 1 请求转发是通过HttpServletRequest 对象实现的
 * 2 请求转发是服务器内部行为,对客户端是屏蔽的
 * 3 客户端只产生了一次请求 服务端只产生了一对 request 和 response 对象
 * 4 客户端的地址栏是不变的
 * 5 请求的参数是可以继续传递的
 * 6 目标资源可以是servlet动态资源 也可以是html静态资源
 * 7 目标资源可以是WEB-INF 下的受保护资源 该方式也是WEB-INF 下的资源的唯一访问方式
 * 8 目标资源不可以是项目外部的资源
 */
@WebServlet("/servletA")
public class ServletA extends HttpServlet{
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ServletA启动了");
        // 获取请求转发器
        //RequestDispatcher requestDispatcher = req.getRequestDispatcher("servletB");
        // 让请求转发器做出转发动作
        //requestDispatcher.forward(req,resp);
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("a.html");
        requestDispatcher.forward(req,resp);
    }
}

9.3 响应重定向

相应重定向逻辑图

相应重定向的特点

  • 1 相应重定向通过HttpServletResponse 对象的sendRedirect 方法实现

  • 2 相应重定向是服务端通过302响应码和路径,告诉客户端自己去找其他资源,实在服务端提示下的,客户端的行为

  • 3 客户端至少发送了两次请求,客户端地址栏是要变化的

  • 4 服务端产生了多对请求和响应对象,且请求和响应对象不会传递给下一个资源

  • 5 因为全程产生了多个HttpServletRequest对象,所以请求参数不可以传递,请求域中的数据也不可以传递

  • 6 重定向可以是其他Servlet动态资源,也可以是一些静态资源以实现页面跳转

  • 7 重定向不可以给到WEB-INF 下受保护的资源

  • 8 重定向可以到本项目以外的外部资源

9.4 重点

同样能够实现跳转,优先使用响应重定向

10 web乱码问题和路径问题总结

10.1 乱码问题

乱码问题产生的根本原因是什么

  1. 数据的编码和解码使用的不是同一个字符集

  2. 使用了不支持某个语言文字的字符集

各个字符集的兼容性

  • 由上图得知,上浮字符集都兼容了ASCII

  • ASCII中有什么?英文字母和一些通常使用的符号,所以这些东西无论使用什么字符集都不会乱码

10.1.1 HTML乱码问题

查看当前文件的字符集

查看项目字符集,配置,将Global Encoding 全局字符集,Project Encoding 项目字符集,Properties Files 属性配置文件字符集设置为UTF-8

TomCat控制台乱码

在tomcat中,修改tomcat/conf/logging.properties中,所有的UTF-8更改为GBK即可

sout 乱码问题,设置JVM加载.class文件时使用UTF-8字符集

  • 设置虚拟机加载.class文件的字符集和编译时使用的字符集一致

10.1.2 请求乱码问题
10.1.2.1GET请求乱码

GET请求方式乱码分析

  • GET方式提交参数的方式是将参数放到URL后面,如果使用的不是UTF-8,那么会对参数进行URL编码处理

  • HTML中的<meta charset='字符集/'> 影响了GET方式提交参数的URL编码

  • tomcat10.1.7 的URL编码默认为 UTF-8

  • 当GET方式提交的参数URL编码和tomcat10.1.7默认的URL编码不一致时就会出现乱码

10.1.2.2 POST方式请求乱码

POST请求方式乱码分析

  • POST请求将参数放在请求体中进行发送

  • 请求体使用的字符集受到了<meta charset="字符集"/>的影响

  • Tomcat10.1.7默认使用UTF-8字符集对请求体进行解析

  • 如果请求体的URL转码和Tomcat的请求体解析编码不一致,就容易出现乱码

package com.mdklea.servlet;
​
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
​
import java.io.IOException;
import java.io.PrintWriter;
​
@WebServlet("/servletC")
public class ServletC extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应体使用UTF-8编码
        resp.setCharacterEncoding("GBK");
        // 设置Context-Type 响应头,告诉客户端用UTF-8编码
        resp.setContentType("text/html;charset=UTF-8");
​
        PrintWriter writer = resp.getWriter();
        writer.write("<h1>你好,你好,你好,你好,你好,我的头发,是真发!</h1>");
        /**
         * Tomcat10中,响应体默认的编码字符集使用的是UTF-8
         * 响应头
         * 相应行
         * 响应体  你好 Hello (UTF-8)
         *
         * 解决思路
         * 1 可以设置响应体的编码字符集和客户端的保持一致 不推荐 客户端解析的字符集是无法预测的
         * 2 可以告诉客户端使用指定的字符集进行解码 通过设置Content-Type 响应头
         */
    }
}

10.2 路径问题

10.2.1相对路径和绝对路径

相对路径

  • 相对路径的规则是:以当前资源所在的路径为出发点去寻找目标资源

  • 相对路径不以/开头

  • 在file协议下,使用的是磁盘路径

  • 在http协议下,使用的是url路径

  • 相对路径中可以使用./表示当前资源所在路径,可以省略不写

  • 相对路径中可以使用../表示当前资源所在路径的上一层路径,需要时手动添加

绝对路径

  • 绝对路径的规则是:使用一个固定的路径做出出发点去寻找目标资源,和当前资源所在的路径没有关系

  • 绝对路径要以/开头

  • 绝对路径的写法中,不以当前资源的所在路径为出发点,所以不会出现./和../

  • 不同项目和不同的写一下,绝对路径的基础位置可能不同,寻找目标资源路径的写法都一致

应用场景

  1. 前端代码中,href src action 等属性

  2. 请求转发和重定向中的路径

10.2.1.1 前端路径问题

相对路径

以当前资源的所在路径为出发点去找目标资源

语法:不以/为开头

./表示当前资源的上一层路径

缺点:目标资源路径受到当前资源路径的影响 不同的位置,相对路径写法不同

绝对路径

始终以固定的路径作为出发点去找目标资源 和当前资源所在路径没有关系

语法:以/开头

不同的项目中,固定的路径出发点可能不一致,可以测试一下

优点:目标资源路径的写法不会受到当前资源路径的影响,不同的位置,绝对路径写法一致

缺点:绝对路径要补充项目的上下文,项目上下文是可以改变的

通过head>base>herf 属性,定义相对路径公共前缀,通过公共前缀把一个相对路径转换为绝对路径(不完美)

10.2.1.2 重定向路径问题

重定向到ServletB

  1. 相对路径写法

    和前端的相对路径规则一致

    resp.sendRedirect("servletB")

  2. 绝对路径写法

    http://localhost:8080/开头

    resp.sendRedirect("/d05/servletB")

10,2,1,3 请求转发到ServletB
  1. 相对路径写法 一致

    http://localhost:8080/d05/servletA

  2. 绝对路径

    请求转发的绝对路径是不需要添加项目上下文的

    请求转发的/ 代表的路径是 http://localhost:8080/d05/

最终解决方式:设置项目路径为/

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值