黑马就业班(02.JavaWeb+项目实战\07.Request和Response)——HTTP协议(响应消息)、Response对象、ServletContext对象

  • 2个重要概念:虚拟目录(项目的访问路径)与资源路径(Servlet类的访问路径)。
  • URL中各种符号的作用:添加链接描述
  • URL中问号的作用:添加链接描述

今日内容

1. HTTP协议:响应消息
2. Response对象
3. ServletContext对象

1、HTTP协议
  HTTP协议可以分为2部分描述:请求消息与响应消息。
   请求消息:客户端发送给服务器端的数据

* 数据格式:
	1. 请求行
	2. 请求头
	3. 请求空行
	4. 请求体

   响应消息:服务器端发送给客户端的数据

* 数据格式:
	1. 响应行
		1) 组成:协议/版本 响应状态码 状态码描述
		eg:200 ok:告诉客户端响应状态码200代表OK,响应成功
		
		2) 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。
			1. 状态码都是3位数字 
			2. 分类:
				1. 1xx:服务器接收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
				2. 2xx:成功。代表:200
				3. 3xx:重定向(视频5.15解析),重定向也是资源跳转的一种方式,与Request的请求转发很类似。注意区分请求转发与重定向。
				代表:302(重定向)304(访问缓存):访问缓存就是提示客户端浏览器,它访问的信息之前访问过,缓存在客户端本地,且服务器没有更改资源,可以去客户端本地找。
				
				4. 4xx:客户端错误。
					* 代表:
						* 404(请求路径没有对应的资源) 
						* 405:请求方式没有对应的doXxx方法。比如我们使用XXX方法向某一个Servlet类请求资源,但是这个类没有处理XXX请求的方法doXXX,就会出现405(演示405错误:视频3-12.00解析)
				5. 5xx:服务器端错误。代表:500(服务器内部出现异常),出现这种情况一般是我们服务器的代码写错。
						
	2. 响应头:
		1. 格式:头名称: 值
		2. 常见的响应头:
			1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式。(以后遇到浏览器显示中文乱码,需要在服务器端代码中的Response响应设置Content-Type(或者使用setContentType()方法)解决;而服务器读取浏览器的请求信息出现中文乱码,也需要在浏览器端使用 setCharacterEncoding(编码方式) 来设置。)
			浏览器会根据服务器告知的编码方式去解析响应消息。
			
			2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
				* 值:
					* in-line:默认值,在当前页面内打开
					* attachment:以附件形式打开响应体。 比如我们点击一个超链接,它不会在浏览器里面打开这个超链接,而是弹出一个框框,让你去下载。
					*格式是:attachment;filename=xxx:以附件形式打开响应体。文件下载。
						
	3. 响应空行
	4. 响应体:传输的数据

   响应消息举例:我们在火狐浏览器打开一个百度界面-F12-网络-刷新,找到“https://www.baidu.com”资源,打开,找到消息头原始头,这些就是响应消息。响应体可以在响应处找到。

HTTP/1.1 200 OK		(响应行)
Bdpagetype: 1			(响应头)
Bdqid: 0xd5f9a0b9000c99ac
Cache-Control: private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html
Cxy_all: monline_3_dg+9f09c7fb838c1316f0a42904cbaa1e40
Date: Fri, 07 Feb 2020 13:12:43 GMT
Expires: Fri, 07 Feb 2020 13:12:43 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Server: BWS/1.1
Set-Cookie: BDRCVFR[Fc9oatPmwxn]=aeXf-1x8UdYcs; path=/; domain=.baidu.com
Set-Cookie: delPer=0; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=10; path=/
Set-Cookie: BD_HOME=0; path=/
Set-Cookie: H_PS_PSSID=1465_21108; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Traceid: 1581081163028858420215418531515709823404
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked
(响应空行)
百度响应回去的就是我们百度的界面内容。(响应体)

   当然,我们也可以启动自己的服务器,在默认访问界面index.jsp的body下加一句

<body>
    hello response
  </body>

   然后将当前项目的虚拟目录改为:/ResponsePro ,启动当前服务器,访问index.jsp,同样使用火狐浏览器,就可以看到响应的消息:

HTTP/1.1 200 		(响应行)
Set-Cookie: JSESSIONID=3E2AA6B18DE8FD18B05C0BE5C9F3EE67; Path=/ResponsePro; HttpOnly		(响应头:用来设置响应消息的展示)
Content-Type: text/html;charset=UTF-8
Content-Length: 100
Date: Fri, 07 Feb 2020 13:30:02 GMT
(响应空行)
<html>		(响应体)
  <head>
    <title>$Title$</title>
  </head>
  <body>
    hello response
  </body>
</html>

重定向

  405响应状态码演示:先创建ServletTest类(删除doGet方法),访问:http://localhost:8080/ResponsePro/servletTest,出现405错误。因为我们使用GET方式提交请求,但是ServletTest类没有这种请求的处理doGet方法,所以出现405错误。

package lkjtest.web.servlet;
@WebServlet("/servletTest")
public class ServletTest extends HttpServlet
{
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
       }
}

2、Response对象
  功能:设置响应消息。

1. 设置响应行
	1) 格式:HTTP/1.1 200 ok
	2) 设置状态码:setStatus(int sc) 
2. 设置响应头:setHeader(String name, String value) 
	
3. 设置响应体:设置响应体,应该使用输出流Writer或者OutputStream,将我们想设置的内容写出到响应消息中。
	* 使用步骤:
		1) 获取输出流
			* 字符输出流:PrintWriter getWriter()

			* 字节输出流:ServletOutputStream getOutputStream()	(同样将ServletOutputStream当中OutputStream使用就可以)

		2) 使用输出流,将数据输出到客户端浏览器

Response对象使用案例

1. 完成重定向
  重定向:资源跳转的方式。请求转发也是资源跳转的一种方式。(重定向详解:视频6-1.25)
  如下图,重定向过程中,A资源告诉浏览器的2件事

1.告诉浏览器重定向:状态码302
2.告诉浏览器资源的路径:响应头location:B资源的路径
一般我们使用sendRedirect()方法来实现重定向

  下面对请求转发与重定向进行区分(重要):一般会问:forward 和 redirect 区别

* 重定向的特点:redirect
		1.浏览器地址栏路径发生变化
		2. 重定向可以访问其他站点(服务器)的资源
		3. 重定向是两次请求。不能使用request对象来共享数据,因为此时有多次请求,就有多个Request对象。

* 请求转发的特点:forward
		1. 浏览器地址栏路径不发生变化
		2. 只能转发到当前服务器内部资源中。
		3. 转发是一次请求,既多个被访问的Servlet资源之间只有一次请求。可以使用request对象在request域内进行资源的共享。

  重定向相关代码

//ResponseTest1类
package lkjtest.web.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("/responseTest1")
public class ResponseTest1 extends HttpServlet
{
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
   
        System.out.println("responseTest1 run....111111");
        //这里注意对比与Request对象请求转发的区别

        /*
        //访问/responseTest1,会自动跳转到/responseTest2资源
        response.setStatus(302);//1、设置响应状态码为302:重定向
        //这里注意设置重定向的路径时加上虚拟目录,包含虚拟目录和类的资源路径。我们设置Deployment的时候将虚拟目录设置为“/ResponsePro”
        //如果虚拟目录设置为“/”,那么这里location的地址就设置为资源路径就可以“/responseTest2”
        response.setHeader("location" , "/ResponsePro/responseTest2");//2、设置location响应头信息。告诉浏览器重定向的资源的地址
        */


        //我们发现重定向其实只需要设置重定向下一个资源的路径即可,可以使用sendRedirect这个方法来实现重定向,比较方便
        //sendRedirect(要转发的路径,既虚拟目录 + 跳转的资源路径)
         //动态获取虚拟目录(虚拟目录写死不好,一当我们将虚拟目录修改,就需要修改全部使用到虚拟目录的地方,十分麻烦。我们一般都会动态获取虚拟目录)
//        String contextPath = request.getContextPath();//通过Request对象来获取(当前项目)虚拟目录,因为重定向也是在同一个项目下,当前类与要转发到类的虚拟目录相同
//        response.sendRedirect(contextPath + "/responseTest2");//以后重定向使用sendRedirect


        //重定向可以访问其他站点的资源
//       response.sendRedirect("http://www.itcast.cn");//会跳转到其他站点的资源下。

        //重定向不能使用Request共享数据
        request.setAttribute("msg" , "redirect");
        response.sendRedirect("/ResponsePro/responseTest2");//通过redirect共享数据失败
    }

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

//-------------------------------------------------------
//ResponseTest2 
package lkjtest.web.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("/responseTest2")
public class ResponseTest2 extends HttpServlet
{
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
   
        System.out.println("responseTest2 run...22222222");//访问/responseTest1,如果重定向成功,会打印这一句

        //演示重定向不能使用Request共享数据
        Object msg = request.getAttribute("msg");
        System.out.println(msg);//不能打印出msg,打印null
    }

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

在这里插入图片描述

  • 补充:Response之相对路径和绝对路径(重要)
      我们在重定向或者请求转发的时候需要填写路径,相应的写法如下:(这部分见视频8、9的解析)
路径分类如下:
1. 相对路径:通过相对路径不可以确定唯一资源
	* 如:./index.html	(代表当前目录下的index.html资源,这样我们就必须找到当前路径)
	* 不以/开头,以.开头路径

	* 规则:找到当前资源和目标资源之间的相对位置关系(见视频7-4.15,这部分直接看视频即可,太繁琐不再记录)
		* ./:当前目录
		* ../:后退一级目录

2. 绝对路径:通过绝对路径可以确定唯一资源
	* 如:http://localhost/day15/responseDemo2(完整的绝对路径)		
	/day15/responseDemo2(省略了协议、服务器的IP或域名、端口号)
	
	* 以/开头的路径

	* 规则:判断定义的路径是给谁用的?
		    * 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
			* 建议虚拟目录动态获取:request.getContextPath()
			* <a> , <form> 重定向...都是给客户端使用的
		* 给服务器使用:不需要加虚拟目录
			* 请求转发路径(目前只有这一个是给服务器端使用的)

1、如何判断路径是给客户端用的还是给服务器用的?
判断请求将来从哪儿发出(视频9-1.25)
请求从浏览器发出,比如在浏览器点击超链接访问服务器,在浏览器通过地址栏输入路径直接访问服务器,都必须加虚拟路径。我们的重定向的2次请求都是从浏览器发出的。
请求从服务端发出,比如前面说的请求转发,请求是从服务器内的一个Servlet类转发到另一个Servlet类,这就是在服务器内使用,不加虚拟目录。

2、为什么给客户端使用要加虚拟目录,而给服务器端使用不需要加虚拟目录(视频9-5.45)

  相对路径解析的相关代码(结合视频)
  我们在web目录下放location.html,通过location.html访问当前项目下的ResponseTest2类

<!--location.html-->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>

        <h1>找到当前资源和目标资源之间的相对位置关系</h1>
        <!--下面讨论的是相对路径
        需要注意,只有项目的名称(虚拟目录)才算一级资源目录,而像src、web这种文件夹是不算一级资源目录的(重要,需要格外注意)
        比如我们在访问location.html的时候,路径是http://localhost:8080/ResponsePro/location.html,只有虚拟目录ResponsePro算一级目录
        -->
        <P>
            当前资源:location.html
          
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值