HTTP响应消息&response对象&ServletContext对象
HTTP响应消息
概念
-
响应消息:服务器端发送给客户端的数据
-
数据格式:
- 响应行:
- 组成:协议/版本 响应状态码 状态码的描述
- 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
- 状态码都是3位数字
- 分类:
- 1xx:服务器接收客户端消息,但是没有接收完成,等待一段时间后,发送1xx多状态码
- 2xx:成功。代表200
- 3xx:重定向。代表:302(重定向),304访问缓存
- 4xx:客户端错误。
- 代表:
- 404(请求路径没有对应的资源)
- 405:请求方式没有对应的doGet方法
- 代表:
- 5xx:服务器端错误
- 代表:500(服务器内部出现异常)
- 响应头:
- 格式:头名称:值
- 常见的响应头:
- Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
- Content-disposition:服务器告诉客户端以什么格式打开相应体数据
- 值:
- in-line:默认值,在当前页面内打开
- attachment;filename=xxx:以附件形式打开响应体。文件下载
- 值:
- 响应空行
- 响应体:传输的数据
- 响应行:
-
响应字符串格式:
HTTP/1.1 200 OK Content-Type: text/html;charset=UTF-8 Content-Length: 90 Date: Thu, 23 Dec 2021 06:31:23 GMT Keep-Alive: timeout=20 Connection: keep-alive <html> <head> <title>$Title$</title> </head> <body> $END$ </body> </html>
-
Response对象
-
功能:设置相应消息
- 设置响应行
- 格式:HTTP/1.1 200 OK
- 设置状态吗:setStatus(int sc)
- 设置相应头:setHeader(String name,String value)
- 设置响应体:
- 使用步骤:
- 获取输出流
- 字符输出流:只能输出字符数据 PrintWriter getWriter()
- 字节输出流:可输出任意数据 ServletOutputStream getOutputStream()
- 使用输出流,将数据输出到客户端浏览器
- 获取输出流
- 使用步骤:
- 设置响应行
-
案例:
-
完成重定向
-
重定向:资源跳转方式
-
代码实现
//1. 设置状态吗为302 // resp.setStatus(302); // //2.设置响应头location // resp.setHeader("location","/day15/rd2"); //简单的重定向方法 resp.sendRedirect("/day15/rd2");
-
重定向的特点:redirect
- 地址栏发生变化
- 重定向可以访问其它站点(服务器)的资源
- 重定向是两次请求,不能使用request对象来共享数据
-
转发的特点
- 转发地址栏路径不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求
-
路径写法:
- 路径分类
- 相对路径:通过相对路径不可以确定唯一资源
- 如:。/index.html
- 不以/开头,以“.”开头路径
- 规则:确定访问的当前资源和目标资源直径的相对位置关系
- 绝对路径:通过绝对路径可以确定唯一资源
- 如:http://localhost/day15/rd2 /day15/rd2
- 以/开头的路径
- 规则:判断定义的路径是给谁用的
- 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
- 建议虚拟目录动态获取:request.getContextPath();
- <a>,<from>重定向。。。
- 给服务器使用:不需要加虚拟目录
- 转发路径
- 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
- 相对路径:通过相对路径不可以确定唯一资源
- 路径分类
-
-
服务器输出字符数据到浏览器
-
步骤:
- 获取字符输出流
- 输出数据
-
注意:
-
乱码问题:
-
告诉浏览器响应体使用的编码
-
在获取流之前设置!!!
-
//简单的形式,设置编码,获取流的默认编码是ISO-8859-1,是在获取流之前设置!!! resp.setContentType("text/html;charset=utf-8");
-
-
-
-
服务器输出字节数据到浏览器
- 步骤:
- 获取字节输出流
- 输出数据
- 步骤:
-
验证码(案例):
-
本质:图片
-
目的:防止恶意
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> /** * 点击超链接或者图片,需要换一张 * 1. 给超链接和图片绑定单击事件 * 2.重新设置图片的src属性值 */ window.onload=function (){ //1.获取图片对象 var img = document.getElementById("checkCode"); img.onclick=changeccs var btn = document.getElementById("change"); btn.onclick=changeccs function changeccs (){ //加时间戳 alert("改"); var data = new Date().getTime(); img.src="ccs?"+data; } } </script> </head> <body> <img id="checkCode" src="ccs"/> <a id="change" href="#">看不清换一张</a> </body> </html>
-
-
ServletContext对象
概念:
- 代表整个web应用,可以和程序的容器(服务器)来通信
- 获取:
- 通过request对象获取
- request。getServletContext();
- 通过HTTPServlet获取
- this.getDervletContext();
- 通过request对象获取
- 功能:
- 获取MIME类型:
- MIME类型:在互联网通信过程中定义的一种文件数据类型
- 格式:大类型/小类型 text/html imge/jpeg
- 获取:String getMimeType(String file);
- MIME类型:在互联网通信过程中定义的一种文件数据类型
- 域对象:共享数据
- setAttribute(String name,Object value);
- getAttribute(String name);
- removeAttribute(String name);
- ServletContext对象范围:所有用户所有请求的数据
- 获取文件的真实路径(服务器路径)
- 方法:String getRealPath(String path);
- 获取MIME类型:
案例:
-
文件下载需求:
- 页面显示超链接
- 点击超链接后弹出下载提示框
- 完成图片文件下载
-
分析:
- 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
- 任何资源都必须弹出下载提示框
- content-disposition:attachment;filename=xxx
-
步骤:
-
定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
-
定义Servlet
- 获取文件名称
- 使用字节输入流加载文件进内存
- 指定response的响应头:content-disposition:attachment;filename=xxx
- 将数据写出到response输出流
-
java部分code,DownloadServletDemo1.java
package cn.web.download; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.FileInputStream; import java.io.IOException; @WebServlet("/dld1") public class DownloadServletDemo1 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取请求参数,文件名称 String filename = request.getParameter("filename"); //2.使用字节输入流加载文件进内存 //2.1找打文件服务器路径 ServletContext servletContext = this.getServletContext();//获取对象 String realPath = servletContext.getRealPath("/img/" + filename); //2.2用字节流关联、 FileInputStream fileInputStream = new FileInputStream(realPath); //3.设置response的响应头 //3.1设置响应头类型:content-type String mimeType = servletContext.getMimeType(filename);//获取文件mime类型 response.setHeader("content-type",mimeType); //3.2设置相应头打开方式:content response.setHeader("content-disposition","attachment;filename="+filename); //4.将输入流数据写出到输出流中 ServletOutputStream outputStream = response.getOutputStream(); byte[] buff = new byte[1024*8]; int len = 0; while ((fileInputStream.read(buff)!= -1)){ outputStream.write(buff,0,len); } fileInputStream.close(); } }
-
html部分code,download.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="/day15/img/goodgkl.jpg">下载</a> <!--<img src="img/goodgkl.jpg" width="580" alt="wu">--> <hr> <!--<img src="img/goodgkl.jpg">--> <a href="/day15/dld1?filename=goodgkl.jpg">下载</a> </body> </html>
-
-
问题:
- 中文文件名问题
- 解决思路:
- 获取客户daunt使用的浏览器版本信息
- 根据不同版本信息,设置filename的编码方式不同
- 解决思路:
- 中文文件名问题
––>
下载
</body>
</html>
```
-
问题:
- 中文文件名问题
- 解决思路:
- 获取客户daunt使用的浏览器版本信息
- 根据不同版本信息,设置filename的编码方式不同
- 解决思路:
- 中文文件名问题