blog
原创

HTTP——响应消息、Response、ServletContext

响应消息数据格式

响应行

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

响应状态码

服务器告知客户端浏览器本次请求和响应的状态

状态码都为三位数字

状态码分类

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

2xx:请求响应成功,如200

3xx:重定向,如302(重定向),304(访问缓存)

4xx:客户端错误,如404(请求路径没有对应资源),405(请求方式没有对应方法)

5xx:服务器端错误,如500(服务器内部异常)

响应头

响应头名称:响应头值

○ 常见的响应头
  1. Content-Type:服务器告知客户端本次响应体的数据格式以及编码格式
  2. Content-disposition:服务器告知客户端以什么格式打开响应体数据,默认值为in-line(在当前页面打开),可选值attachment(以附件形式打开响应体)

响应空行

空行,分隔响应头和响应体

响应体

服务器端给客户端传递的数据

Response

设置响应行

○ void setStatus(int sc) :设置状态码

设置响应头

○ void setHeader(String name, String value) :设置响应头,参数为响应头名称,响应头值

设置响应体

获取输出流
方法 描述
ServletOutputStream getOutputStream() 获取字节输出流
PrintWriter getWriter() 获取字符输出流
使用输出流
// 获取字符输出流
PrintWriter writer = response.getWriter();
// 输出数据
writer.write("<p>Response</p>");

// 获取字节输出流
ServletOutputStream outputStream = response.getOutputStream();
// 输出数据
outputStream.write("Response".getBytes());
输出中文乱码问题

浏览器的默认字符集以当前操作系统语言为准,若操作系统为中文,则浏览器默认为GBK(GB2312)

而Tomcat的默认编码格式ISO-8859-1,编码解码使用的字符集不一致,则会出现中文乱码问题

在获取输出流之前,要设置流的默认编码

response.setCharacterEncoding();

response.setCharacterEncoding("GBK");

但是若浏览器解码为utf-8,也会出现乱码问题,所以服务器需要告知浏览器服务器发送消息数据的编码格式,设置响应头的Content-type响应头值为对应字符集

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

也可以通过提供好的 setContentType() 方法来设置

response.setContentType("text/html;charset=GBK");

通过该方法可以不设置流编码,该方法可以同时设置流编码并告知客户端响应消息使用的流编码

==该方法同样也要在获取输出流之前调用==

重定向

将各种网络请求重新定个方向转到其它位置

方法1
  1. 设置状态码为 302
response.setStatus(302);
  1. 设置location响应头,响应头值为路径
response.setHeader("location","/Response/responseDemo1");
示例

responseDemo

@WebServlet("/responseDemo")
public class ResponseDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 若访问 /responseDemo,将自动跳转到 /responseDemo1
        System.out.println("this is demo");
        // 设置状态码
        response.setStatus(302);
        // 设置响应头
        response.setHeader("location","/Response/responseDemo1");
    }

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

responseDemo1

@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("this is demo1");
    }

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

控制台输出

this is demo
this is demo1
方法2

使用 void sendRedirect(String location) 方法进行重定向

示例

将方法1中的responseDemo代码更改为

@WebServlet("/responseDemo")
public class ResponseDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 若访问 /responseDemo,将自动跳转到 /responseDemo1
        System.out.println("this is demo");
        // 重定向
        response.sendRedirect("/Response/responseDemo1");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
重定向与转发的区别
转发 forward 重定向 redirect
地址栏路径 不变 改变
可访问资源 只能访问当前服务器下的资源 可访问其他服务器的资源
请求次数 一次 两次

由于重定向是两次请求,所以无法使用Request对象共享数据

重定向路径写法
路径分类

(1). 相对路径:通过相对路径不可以确定唯一资源

./login.html

以 . 开头的路径

要确定当前资源与目标资源之间的相对位置关系

./:代表当前目录

../:代表上一级目录

(2). 绝对路径:通过绝对路径可以确定唯一资源

http : //localhost:8080/Response/responseDemo1

以 / 开头的路径

要判断定义的路径的使用对象/判断请求从哪里发出

  • 若使用对象为客户端(如重定向,请求由浏览器发出),则需要添加虚拟目录
  • 若使用对象为服务器(如转发,为服务器内部资源跳转),则不需要添加虚拟目录
动态获取虚拟目录

若重定向路径定义为绝对路径的情况下,项目虚拟目录发生变化,则需要更改大量的路径,可以使用Request对象的getContextPath()方法获取虚拟目录,并将其拼接到重定向的路径中

response.sendRedirect(contextPath + "/responseDemo1");

ServletContext

代表整个Web应用,可以和程序容器(服务器)进行通信

获取ServletContext对象

通过Request对象来获取

request.getServletContext();

通过HttpServlet获取

this.getServletContext();

通过两种方法获取到的ServletContext对象为同一个对象

javax.servlet.ServletContext servletContext1 = request.getServletContext();
javax.servlet.ServletContext servletContext2 = this.getServletContext();
System.out.println(servletContext1 == servletContext2); // 输出 true

功能

获取MIME类型

MIME类型:MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,是在互联网通信过程中定义的一种文件数据类型,是一种标准,用来表示文档、文件或字节流的性质和格式

大类型/小类型 如:text/html

方法 描述 参数
String getMimeType(String s) 获取MIME类型 String 文件名
ServletContext servletContext = this.getServletContext(); // 获取ServletContext对象
String filename = "file.txt"; // 定义文件名称
String mimeType = servletContext.getMimeType(filename); // 获取文件的MIME类型
System.out.println(mimeType); // 输出结果为 text/plain
共享数据
方法 描述
void setAttribute(String name, Object o) 存储数据
Object getAttribute(String name) 通过键来获取值
void removeAttribute(String name) 通过键移除键值对

ServletContext对象范围:所有用户所有请求的数据

若当用户1使用浏览器1访问Servlet1时调用了setAttribute()方法存储了数据,用户2通过浏览器2访问Servlet2是调用 getAttribute()方法依然可以获取到用户1存储的数据

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

○ String getRealPath(String Path)

ServletContext servletContext = this.getServletContext();
String path = servletContext.getRealPath("/"); // 访问web目录下资源
path = servletContext.getRealPath("/WEB-INF"); // 访问WEB-INF目录下资源
path = servletContext.getRealPath("/WEB-INF/classes"); // 访问src目录下资源
HTTP
  • 作者:Melonico
  • 发表时间:2021-03-15 17:52
  • 更新时间:2021-03-15 17:52

评论

暂无评论,快来发表第一个评论吧!
留言
TOP