目录

HTTP协议

 Response响应消息

响应行

 响应头

 响应体

 Response对象

案例练习

实现重定向

 获取字符流

乱码问题

 ServletContext对象


HTTP协议

请求消息:客户端发送给服务器端的数据

数据格式:

1.请求行

2.请求头

3.请求空行

4.请求体

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

数据格式:
1.响应行

2.响应头

3.响应空行

4.响应体

 Response响应消息

响应行

组成:协议/版本 响应状态码 状态码描述

响应状态码:服务器告诉客户端浏览器请求和响应的一个状态

状态码:

特点:状态码都是三位数字组成

分类:

1xx  :服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx状态码

2xx  :成功。代表性状态码:200

3xx  :重定向。

代表:302(重定向),资源跳转的一种方式

axios的response格式 response内容_axios的response格式


代表:304  访问缓存

axios的response格式 response内容_重定向_02

4xx  :客户端错误

代表1: 404(请求路径没有对应的资源)

代表2:405(请求方式没有对应doXxx方法)

5xx  :服务器端错误

代表1: 500(服务器内部出现异常)

 响应头

格式:头名称:值

常见的响应头

1.Content-Type  :服务器告诉客户端本次响应体数据格式以及编码格式

例如,Content-Type:  text/html;charset=UTF-8,作用:告诉浏览器当前页面是html格式的,以及当前页面的编码格式,这会改变浏览器解码格式

2.Content-dispostion :服务器告诉客户端以什么格式打开响应体数据

值:

1.in - line :默认值,在当前页面内打开

2.attachment:filename = xxx  : 以附件形式打开响应体。例如文件下载

 响应体

真实的传输的数据

 Response对象

功能:设置响应消息

设置响应行:

HTTP/1.1 200 OK

1.设置状态码:setStatus(int sc)

设置响应头:

setHeader(String name,String value)

设置响应体:

使用步骤:

获取输出流

字符输出流:PrintWriter getWriter()

字节输出流:ServletOutputStream getOutputStream()

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

案例练习

实现重定向

步骤:

1.浏览器访问A资源时,告诉浏览器重定向:状态码302

2.告诉浏览器B资源的路径:响应头location:B资源的路径

转发的特点:

1.转发地址栏路径不变

2.转发只能访问当前服务器下的资源

3.转发是一次请求,可以使用request对象来共享数据

重定向的特点:

1.地址栏发生变化

2.重定向可以访问其他站点(服务器)的资源

3.重定向是两次请求,不能用request对象来共享数据

路径

路径分类:

1.绝对路径:通过绝对路径可以确定唯一的资源,例如http://localhost:8080/project01/demo01  通常写为/project01/demo01,以/开头

规则:判断定义的路径是给谁用的(判断请求从哪里发出·)

1.给客户端浏览器用的(重定向),需要加虚拟目录(项目的访问路径)

2.给服务器使用(服务器内部资源跳转,不需要客户点击链接),不需要加虚拟目录

注意:为了让以后写的代码具有通用性,防止未来改虚拟目录,跳转的路径将无法访问,我们使用request.getContextPath()来动态获取目录

2.相对路径:通过相对路径不可以确定唯一的资源,例如,  ./index.html ,以 . 开头,可以省略./

./ :标识当前目录

../:标识后退一级目录

规则:找到访问当前资源和目标资源之间的相对位置关系

/*
重定向
访问demo01资源,会自动跳转到demo02资源
 */
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("/demo01")
public class ServletResponse01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo01被访问啦");
        //1.设置状态码为302
        response.setStatus(302);
        //2.设置响应头location
//        response.setHeader("location","/demo02");
        //或者使用简单的重定向方法
        response.sendRedirect("/demo02");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    this.doPost(request,response);
    }
}
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("/demo02")
public class ServletResponse02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo2被访问了....");
    }

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

 获取字符流

乱码问题

原因:编码解码不一样

解决方案:写在最前面设置响应头

response.setHeader("content-type","text/html;charset=utf-8");

更简单的形式

response.setContentType("text/html;charset=utf-8");

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取流对象之前设置编码
        //response.setCharacterEncoding("GBK");
        //因为我们事先可能不知道浏览器的编码
        //我们需要告诉浏览器,服务器发送的消息体数据的编码,建议浏览器使用该编码解码,用下面这句替代设置编码代码
       // response.setHeader("content-type","text/html;charset=utf-8");
        //response提供了一个简单的形式设置编码
        response.setContentType("text/html;charset=utf-8");
        //获取字符输出流
        PrintWriter pw = response.getWriter();
        //输出数据
        pw.write("hello,response");
        //获取字节输出流
        ServletOutputStream sos = response.getOutputStream();
        //输出数据
        sos.write("hello".getBytes("utf-8"));
    }

 ServletContext对象

概念:代表整个web应用,可以和程序的容器(服务器)来通信。

作用:

1.获取MIME类型

MIME类型:在互联网通信过程中定义的一种文件数据类型,http遵循了这种标准

MIME类型格式:大类型/小类型  例如text/html,image/jpeg

作用:用于Content-type响应头的设置,告诉浏览器发的数据是什么类型什么格式,浏览器就会以相应的方式解析。

获取方式:String getMimeType(String file)

原因:其实是通过文件后缀名获取的,因为所有文件对应的MiME类型都装在tomcat服务器中,而ServletContext又恰好可以与服务器通信。

axios的response格式 response内容_重定向_03

 

axios的response格式 response内容_java_04


2.域对象:共享数据

setAttribute(String name,Object value)

getAtrribute(String name)

removeAttribute(String name)

servletContext对象范围:所有用户所有请求的数据,普通对象范围只能在一次请求中共享数据。

servletContext生命周期:服务器启动,被创建,服务器停止,才被销毁。

缺点:不太安全,因为所有对象都可以使用

3.获取文件的真实路径(服务器路径)

axios的response格式 response内容_http_05

 方法: String getRealPath(String path)

 获取对象的两种方法:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //servletContext的获取
    ServletContext context1=  request.getServletContext();
    ServletContext context2 = this.getServletContext();
    System.out.println(context1 == context2);//true
        //无论用哪种方式获取,最终获取的都是同一个。
    }

获取MIME类型:

public class ServletContext1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //servletContext的获取
   // ServletContext context1=  request.getServletContext();
    ServletContext context2 = this.getServletContext();
    System.out.println(context2 == context2);//true
        //无论用哪种方式获取,最终获取的都是同一个。
        String filename = "a.jpg";
        String mimetype =context2.getMimeType(filename);
        System.out.println(mimetype);
    }

 获取文件的真实路径:

例如,我们用获取真实路径的方法获取配置文件。

我们知道,配置文件在idea中可以放在三处,分别是在src,web,web下新建的WEB-INF下。

举例说明,file.xml   file2.xml   file3.xml分别在src,web,WEB-INF中放置的。

axios的response格式 response内容_服务器_06

 如何获取这些文件的真实目录呢?

因为我们总是需要将配置文件加载进内存,例如在用druid连接池技术连接数据库时就会用class.getClassLoader()的方式将src下的文件加载进内存,但是这种方法非常局限,只限于src下的文件。

我们知道每一个项目都存在一个相应的配置文件:

axios的response格式 response内容_java_07

 在电脑中找到这个配置文件:

axios的response格式 response内容_重定向_08

 打开这个配置文件来看看:

axios的response格式 response内容_http_09

path是虚拟路径,真正对应的服务器路径是docBase里的路径。

 先来访问web目录下的file2的真实服务器路径:

public class ServletContext2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取ServletContext对象
        ServletContext context = this.getServletContext();
        //获取文件的服务器真实路径
        String realPath = context.getRealPath("/file2.xml");
        System.out.println(realPath);
    }

axios的response格式 response内容_重定向_10

/file2.xml 时访问的是web目录下的资源。

其中/代表的是上图中的D:\JAVA\JAVAhei\response\out\artifacts\response_war_exploded路径,那么web目录下的文件恰好就在该路径下,当我们要访问其他自己创建的文件夹下的文件时,那么就应该与file2.xml的位置相对比即可。

那么当我们访问WEB-INF的文件时又该如何呢?

先来看看对比file2.xml文件,WEB-INF下的文件在哪里

file2.xml文件所在处:

axios的response格式 response内容_服务器_11

 

 WEB-INF文件夹下的file3文件所在处:

axios的response格式 response内容_axios的response格式_12

 访问WEB-INF下的file3文件:

public class ServletContext3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context1 = this.getServletContext();
        String realpath = context1.getRealPath("/WEB-INF/file3.xml");
        System.out.println(realpath);
    }
如何访问src目录下的file文件呢?
src下的所有文件将会被放到WEB-INF目录下的classes目录下:

axios的response格式 response内容_http_13

 访问src目录下的file文件:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context1 = this.getServletContext();
        String realpath = context1.getRealPath("/WEB-INF/classes/file.xml");
        System.out.println(realpath);
    }