HTTP:http响应报文分析
响应行
响应行格式: 协议/版本 状态码
常见状态码:
状态码 | 状态码描述 | 说明 |
---|
200 | OK | 请求已成功,请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。 | 302 | Move temporarily | 重定向,请求的资源临时从不同的地址响应请求。 | 304 | Not Modified | 从浏览器缓存中读取数据,不从服务器重新获取数据。例如,用户第一次从浏览器访问服务器端图片资源,以后在访问该图片资源的时候就不会再从服务器上加载而直接到浏览器缓存中加载,这样效率更高。 | 404 | Not Found | 请求资源不存在。通常是用户路径编写错误,也可能是服务器资源已删除。 | 403 | Forbidden | 服务器已经理解请求,但是拒绝执行它 | 405 | Method Not Allowed | 请求行中指定的请求方法不能被用于请求相应的资源 | 500 | Internal Server Error | 服务器内部错误。通常程序抛异常 |
响应头
服务器基于响应头通知浏览器,响应头也是用键值对key:value 形式
常见的响应头 :
响应头Key | 响应头value |
---|
location | 指定响应的路径,需要与状态码302配合使用,完成重定向 | content-Type | 响应正文的类型(MIME类型,属于服务器里面的一种类型,例如文件在window系统有自己的类型,.txt .doc .jpg。文件在服务器中也有自己的类型),同时还可以解决乱码问题。例如:text/html;charset=UTF-8 | content-disposition | 通过浏览器以附件形式解析正文,例如:attachment;filename=xx.zip | refresh | 页面刷新,例如:3;url=www.itcast.cn //三秒刷新页面到www.itcast.cn |
说明:
MimeType:标识数据类型
最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML 文档,而为了支持多媒体数据类型,HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。
MIME意为多功能Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。
每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
常见的MIME类型(通用型):
windows tomcat
超文本标记语言文本 .html text/html ***
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain ***
PDF文档 .pdf application/pdf
Microsoft Word文件 .word application/msword
PNG图像 .png image/png ***
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
......
Response:HttpServletResponse
HttpServletResponse介绍
问题 : tomcat服务器接受客户端的请求之后,处理请求之后,服务器如何将对应的数据响应给客户端呢?
解决方案 : Servlet程序接受客户端请求之后,通过HttpServletResponse对象来完成向客户端的响应。
结论:通过HttpServletResponse对象,可以将数据返回给客户端。
HttpServletResponse对象代表服务器响应,tomcat创建HttpServletResponse对象,并将该对象作为参数传递给Servlet的service方法
HttpServletResponse对象的作用:设置响应行、响应头、响应体 (把响应信息返回给浏览器)
响应行相关API
响应行包含:协议/版本 、状态码。 如:HTTP/1.1 200
响应行中的信息,通常只会用到状态码,操作状态码的方法:
方法 | 说明 |
---|
setStatus(int code) | 向浏览器发送状态码 |
常用状态码:
对应的状态码响应状态码常量 | 说明 |
---|
200 | 响应成功 | 404 | 资源路径错误或资源被删除 | 500 | 服务器内部错误 | 302 | 重定向 |
响应头相关API
响应头中的信息是以key:value 形式存在的
设置响应头的方法:
方法 | 说明 |
---|
setHeader(String name , String value) | 设置响应头信息 |
常见响应头:
响应头Key | 响应头value |
---|
refresh | 页面刷新。 例如:3;url=http://www.itcast.cn //三秒刷新页面到http://www.itcast.cn | content-type | 设置响应数据的类型(MIME类型)和编码格式。 例如:text/html;charset=UTF-8 | location | 指定响应的路径,需要与状态码302配合使用,完成重定向 | content-disposition | 通知浏览器以附件形式解析正文。 例如:attachment;filename=xx.zip |
响应体相关API
响应体:存放服务器要返回给浏览器的数据
响应体相关方法:
方法 | 说明 |
---|
ServletOutputStream getOutputStream() | 用于向浏览器输出二进制数据。【字节流–文件下载】 | java.io.PrintWriter getWriter() | 用于向浏览器输出字符数据。【字符流–给浏览器响应数据】 |
Response:定时刷新
实现Servlet控制浏览器跳转页面
Response:浏览器显示原数据
案例:实现浏览器不解析返回的html格式数据
代码:使用content-type设置响应数据的类型,告诉浏览器不要解析html格式数据
@WebServlet("/contentServlet")
public class ContentServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("content-type","text/plain");
response.getWriter().print("<html><body><h1>itcast</h1></body></html>");
}
}
说明:text/plain的意思是将文件设置为纯文本的形式,浏览器在获取到这种文件时并不会对其进行处理。
Response:处理响应乱码
乱码产生的原因
tomcat服务器如果需要响应给浏览器中文数据,tomcat使用getWriter() 输出字符时,对于中文需要进行编码处理,而tomcat8 默认编码是ISO-8859-1 ,该码表是不支持中文编码的。所以响应给浏览器,出现乱码。
响应乱码解决方案
因为HttpServletResponse 实现类是由tomcat服务器提供的,所以服务器在向浏览器输出数据之前,对于中文要采用支持中文的编码进行编码,通过response.setContentType("text/html;charset=utf-8"); :
-
设置响应的数据类型(text/html); -
设置响应的数据编码(utf-8);
处理响应乱码的API方法:
方法 | 说明 |
---|
response.setHeader("content-type","text/html;charset=utf-8"); | 设置响应头 | response.setContentType("text/html;charset=utf-8"); | 简写方式 |
注意事项:
- 开发中通常使用
response.setContentType("text/html;charset=utf-8"); 来处理响应乱码; - 处理响应乱码必须书写在响应数据之前才起作用;
代码:content-type 设置响应数据的类型和编码
@WebServlet("/encodeServlet")
public class EncodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
response.getWriter().print("传智播客黑马程序员");
}
}
Response:重定向
重定向原理分析
重定向API
重定向可以去一个servlet,也可以去一个html静态资源
方法 | 说明 |
---|
response.setStatus(302); response.setHeader(“location”, “/otherServlet”); | 通过设置响应状态码和响应头实现重定向 | response.sendRedirect(“/otherServlet”); | 重定向的简写方式 |
注意: 开发中通常使用response.sendRedirect("/otherServlet"); 来实现重定向
- 当服务器需要浏览器重新定向(重新请求)时,需要告知浏览器状态码为:302
- 在开发中,通常使用:response.sendRedirect(“/请求路径”) 来实现请求重定向
- 重定义的特点:一次请求、响应 变为 两次请求、响应
Response:转发和重定向的区别
完成重定向操作之后,大家心里有一个疑问:之前学习的转发和现在的重定向都可以完成跳转,都可以跳转到一个servlet,也可以跳转到一个html静态资源,功能相同。那么他们之间有什么区别呢?
转发和重定向的区别
区别点 | 转发 | 重定向 |
---|
实现原理 | 服务器内部 | 浏览器执行 | 请求次数 | 一次 | 两次 | 浏览器地址栏地址 | 不变化 | 变为第二次请求的地址 | 能否共享request域 | 能够共享 | 不能共享 | 作用 | 共享request域对象 | 完成跳转 |
说明:
Response:向浏览器返回数据
案例:向浏览器输出数据
响应体方法:
方法 | 说明 |
---|
ServletOutputStream getOutputStream() | 用于向浏览器输出二进制数据。【字节流–文件下载】 | java.io.PrintWriter getWriter() | 用于向浏览器输出字符数据。【字符流–给浏览器响应数据】 |
案例:使用getWriter()方法向浏览器返回数据
@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
char[] arr = {'a','b'};
List<String> list = new ArrayList<>();
list.add("liuyan");
list.add("zhuyin");
list.add("guanxiaotong");
response.getWriter().println("hello");
response.getWriter().println('a');
response.getWriter().println(65);
response.getWriter().println(true);
response.getWriter().println(arr);
response.getWriter().println(list);
}
}
ServletContext对象应用
当希望通过浏览器下载服务器上的某个文件时,Servlet是需要找到这个文件在服务器上的位置,获取文件类型(告知浏览器是什么文件类型)
简而言之:要想实现文件的下载,要先学习ServletContext对象
ServletContext对象介绍
ServletContext对象
- 当tomcat服务器启动的时候,会为每个web项目创建一个唯一的ServletContext对象,该对象代表当前整个Web应用项目
- ServletContext对象不仅封装了当前web应用的所有信息,而且实现了多个servlet的数据共享,在ServletContext中可以存放共享数据,ServletContext对象是真正的一个全局对象,凡是web容器中的Servlet都可以访问
在每个项目中可以有多个Servlet程序,每个Servlet程序都是独立的。当前这个项目的配置信息,就必须使用描述这个项目的ServletContext对象获取。
结论:ServletContext对象代表的就是整个web项目
- web项目下的资源文件,ServletContext都可以拿到
- 下载文件时,需要借用ServletContext对象获取文件、获取文件类型
ServletContext对象API方法
方法名 | 描述 |
---|
setAttribute(String name,Object object) | 向ServletContext中存数据 | getAttribute(String name) | 从ServletContext中取数据 | removeAttribute(name) | 从ServletContext中移除数据 | String getRealPath(String path) | 返回资源文件在服务器文件系统上的真实路径(文件的绝对路径) | getMimeType(fileName) | 获取服务器中文件类型 |
ServletContext对象,tomcat为每一个web项目单独创建的一个上下文(知上知下贯穿全文)对象。有如下功能:
1.可以在多个servlet之间共享数据
? 存放:setAttribute()
? 获得:getAttribute()
? 删除:removeAttribute()
2.可以获得当前WEB项目中的指定资源(文件)
? String path = getRealPath( String fileName); //获取指定文件在web项目下的绝对路径
ServletContext对象的应用
需求1:如何获取上下文servletContext对象
使用HttpServlet类的父类 GenericServlet中的方法 : getServletContext()
代码如下:
@WebServlet("/servletContextDemoServlet")
public class ServletContextDemoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
}
}
需求2:如何获取服务器中文件的路径
- 例如:在当前项目下的web文件夹下放一个1.jpg的图片,获取其真实路径(绝对路径)
@WebServlet("/servletContextDemoServlet")
public class ServletContextDemoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
String realPath = servletContext.getRealPath("/1.jpg");
System.out.println("realPath = " + realPath);
}
}
说明:
获取结果:
realPath = F:\ideawork\jiuyeban2\heima60\heima03\out\artifacts\web_war_exploded\1.jpg
说明:我们的项目在发布的时候会被打成一个war包,这个war包下的class文件会被放在tomcat下被运行。
所以这里获取的真实路径是这个war包下的1.jpg所在的路径。
如图:
需求3:获取当前项目下的1.jpg在服务器中的文件类型
String mimeType = servletContext.getMimeType("1.jpg");
System.out.println("mimeType = " + mimeType);
注意:对于方法 getMimeType(“1.jpg”); 这里书写获取文件类型的文件名和后缀名即可
|