Phase4 JavaEE Day3 Request&Response

本文深入探讨Web开发中的转发与包含技术,解析其工作原理、路径写法及应用场景,对比转发、定时刷新与重定向的区别,助力开发者掌握高效页面跳转技巧。

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

request

1.post和get乱码问题

POST:
为什么服务端设置utf-8呢?因为页面的meta标签有一个charset=utf-8,前后端保持一致。
在这里插入图片描述
设置第一行代码就ok了,但是这行代码必须要写在获取请求参数之前。

get:
前提:使用的是tomcat8版本,然后页面使用的编码格式是utf-8,这个时候是不存在乱码问题的

2. 表单路径的写法

从表单路径可以进一步推广到所有的路径,比如img的src,a标签的href等等
在这里插入图片描述

  • 全路径:http开头,域名端口号,应用名资源名。
  • 相对路径写法:需要提交的地址和你当前的地址他们之间的相对关系。
    需要提交的地址: http://localhost:8080/request/form
    当前的页面所在的地址:http://localhost:8080/request/page/form.html
    所以,相对路径应该怎么写呢?form。
  • /应用名/资源路径, /request/form.

3.转发包含

目前为止,我们所有的操作都在一个servlet中,但是如果有一个请求,我希望多个servlet同时参与进来,可以怎么做呢?

3.1 路径写法

  • 全路径 不可在这里插入图片描述
    这个时候即便你写的是全路径,那么此时仍然是在当前request应用内。全路径不可以写。在这里插入图片描述
  • 相对路径 OK
    在这里插入图片描述
  • 第三种
    如果是/应用名开头的写法呢?
    在这里插入图片描述
    在这里插入图片描述
    但是这种写法就不可以吗? 直接写/资源名即可
    之前的form表单写法是/应用名/资源路径,现在的转发路径/资源名,怎么记忆呢?
    之前的form表单地址写法,以及现在的转发路径如果用相对路径,都是一样的。区别在于使用/开头的路径写法时,路径的差异:
    前提,适用于/开头的路径(不适用于相对路径):
    /开头的路径要不要加/应用名,这个时候看执行主体(路径是给谁用的)是浏览器还是服务器,如果是浏览器,那么浏览器压根不可能知道你的应用名是啥,所以必须带;但是如果是服务器,那么服务器肯定可以知道你的应用名是什么,所以不需要去带

form表单的action。img的src、a标签的href,这些都是怎么显示处理的。都是浏览器

  • dispatcher.forward(request,response)的处理流程:
    1、清空用于存放响应正文数据的缓冲区
    2、如果目标组件为Servlet或JSP,tomcat就调用它们,把它们产生的响应结果发送到客户端;如果目标组件为文件系统中的静态HTML文档,tomcat就读取文档中的数据并把它发送给客户端。
    特点:1、由于forward()方法先清空用于存放响应正文数据的缓冲区,因此源组件生成的响应结果(无论转发前后)不会被发送到客户端,只有目标组件生成的响应结果才会被送到客户端。
    2、如果源组件在进行请求转发之前,已经提交了响应结果(如调用了response的flush或close方法),那么forward()方法会抛出IllegalStateException。为了避免该异常,不应该在源组件中提交响应结果

  • include()方法的处理流程
    如果目标组件为Servlet或JSP,就执行它们,并把它们产生的响应正文添加到源组件的响应结果中;如果目标组件为HTML文档,就直接把文档的内容添加到源组件的响应结果中
    特点:
    1、源组件与被包含的目标组件的输出数据都会被添加到响应结果中。
    2、在目标组件中对响应状态代码或者响应头所做的修改都会被忽略。

几个比较新的关于路径的API
在这里插入图片描述

3.2转发包含之间的区别

拿到了RequestDispatcher对象之后,调用forward方法执行的是转发;调用include方法执行的是包含

区别

  • 转发:我源组件执行了部分代码,之后将请求全权交个目标组件来处理,源组件不再过问。一般用在servlet处理完结果,根据结果跳转至一个页面。
  • 包含:我源组件需要一些额外的功能,这个时候,可以把目标组件的功能包含到我自身中来,我再一并响应。一个很大的页面,需要有很多块小组件,可以把这个小组件包含进来,然后这个页面一起响应。

功能上的不同,在代码上面是怎么体现出来的呢?全部都是针对源组件来说的

  • 转发:留头不留体(在最终的响应报文中,转发的源组件可以留下响应头,但是无法留下响应体数据)
  • 包含:留头也留体(在最终的响应报文中,包含的源组件不仅可以留下响应头,也可以留下响应体)

在这里插入图片描述

request域

域:一块空间。可以在这个空间里面进行数据共享

  • context域。context对象中有一个map,任何能够拿到context对象都可以进行数据共享
  • request域。request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。request对象中也有一个map,任何能够拿到同一个request对象,也可数据共享,但是哪些可以拿到同一个request对象?
    1.反复刷新一个页面,多次请求,是同一个request对象吗?不是
    2.怎么才能拿到同一个request对象呢?转发包含的源组件和目标组件之间。比如servlet进行逻辑处理,拿到了list,接下来将其放入request域中,然后在jsp页面中取出来(本质也是servlet)

源组件设置request域
在这里插入图片描述
在这里插入图片描述
为什么有context域还要有request域呢?

有些数据仅仅需要短暂保存一下,这个时候就可以使用request域,没必要使用context域。

response

就是代表了将来的响应报文。子接口HttpServletResponse。
响应报文:
响应行:版本、状态码、原因
响应头:

响应体:
在这里插入图片描述

1.响应字符数据–中文乱码

  • 方案一
    在这里插入图片描述

  • 方案二
    在这里插入图片描述
    本质上setHeader和setContentType都是设置响应头,只不过前者可以设置更多东西,后者只能设置ContentType

前两种方案,告知客户端编码格式是使用的响应头,能不能通过响应体告知呢?

  • 方案三
    在这里插入图片描述

2.响应二进制数据

比如传输一个图片到浏览器:Response.getOutputStream()在这里插入图片描述
问题: 比如在web目录下有一个1.jpg,直接通过浏览器输入地址
http://localhost:8080/response/1.jpg

此时请求到达response应用,response应用内并没有设置任何能够处理该请求的servlet的url-pattern,那么这个时候,会调用tomcat提供的缺省servlet来处理该请求,处理逻辑就是找到当前应用下的资源,然后以流的形式写入到response中。(访问静态资源也有作业参与)

而通过访问一个servlet,servlet直接将1.jpg的内容呈现出来,

3.页面定时刷新

在这里插入图片描述
跳转到应用外
在这里插入图片描述

4.重定向

在这里插入图片描述
此时页面中并不会显示redirect的内容
在这里插入图片描述
在这里插入图片描述
同样,也可以在应用内跳转。不受应用限制。
重定向还可以另外一种实现方式:
在这里插入图片描述
两种方式完全等价。

5.转发、定时刷新、重定向区别和联系

  • 联系:都可以用来进行页面跳转。
  • 区别:转发只能在应用内;刷新和重定向没有限制
       转发是服务器介导的;刷新和重定向是浏览器介导的
       转发是request对象介导的;刷新和重定向是response
       转发两个组件之间可以共享request域;刷新和重定向是两次不同的请求
       转发是发送一次请求;刷新和重定向是发起两次请求

6.下载

首先对于浏览器来说,可以打开的文件会执行打开操作,对于无法打开的文件会执行下载操作。但是如果对于一个可以打开的文件,比如图片,这个时候我想直接下载,而不是打开,就可以使用接下来说的设置一个响应头
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值