Day03 Response
一、response-概述
1、什么是response?
代表服务器的响应。
HTTP响应消息分为状态行、响应消息头、消息体三部分。
例:用火狐浏览器打开www.baidu.com,右击空白处–>点击审查元素–>选择网络–>双击域名为www.baidu.com的那一行。
2、response对象
HttpServletResponse对象,通过它的方法可以设置HTTP响应消息的内容。
在Servlet API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。由于,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。
二、response-设置响应行
1、常见状态码的含义
- 200 正常
- 302 重定向
- 304 访问缓存
- 404 表示服务器资源不存在
- 500 服务器程序错误,异常(如1/0)
2、设置状态码
setStatus(int status)方法 //200 302 304
sendError(int sc)方法 //404 500
三、response-设置响应头
1、响应头是什么?
响应头是一组键值对
2、设置响应头有什么用?
(1)设置自己的键值对
(2)修改系统已经存在的键值对
(3)设置方法
void setHeader(String name, String value)
//1.在响应头里面添加自己定义的key-value
response.setHeader("name","jack");
response.setHeader("age","22");
//2.修改key-value的值
response.setHeader("Content-Type","text/html;charset=utf-8");
//此处同上,直接根据键给值
response.setContentType("text/html;charset=utf-8");
//在此行代码之前不设置Content-Type的值,会乱码
response.getWriter().println("中国");
//设置响应头,5秒钟之后,页面自动跳转到/day14login/index.html
response.setHeader("Refresh", "5;url=/day14login/index.html");
setHeader("Content-Disposition", String value)
四、response-重定向
1、什么叫重定向?
两次请求,两次响应。
即,浏览器向servlet1发出请求,servlet1没有所需资源,servlet1响应给浏览器,让浏览器向servlet2发出请求,servlet2有所需资源,并响应给浏览器。
2、重定向的核心
(1)响应码:302
(2)响应头:Location
//servlet1没有所需资源,让浏览器访问servlet2
//设置重定向的参数
//1.设置状态码302
response.setStatus(302);
//2.设置Location,指向servlet2
response.setHeader("Location","/web01_response/demo02");
上述两行也可以用一行解决
response.sendRedirect("/web01_response/demo02");
五、response-设置响应体
1、设置响应体的方法
(1)getWriter()方法:字符流
只能向浏览器响应文本内容:字符串,标签
response.getWriter().write("<font color='red'>中国</font>");
产生中文乱码的原因:Tomcat默认编码格式为IOS 8859-1
解决方式:在此输出代码前,加入下行代码
response.setHeader("Content-Type","text/html;charset=utf-8");
(2)getOutputStream()方法:字节流
可以向浏览器响应任何类型的数据: 图片,视频,音频。
向页面输出字符串(需要转成字节类型输出),使用write,不需要解决乱码。
//获取字节输出流
OutputStream outputStream =response.getOutputStream();
//写数据到浏览器
byte [] bytes = "中国".getBytes();
outputStream.write(bytes);
2、图片的复制
(1)将图片响应给浏览器
- 获取a.jpg文件的输入流
- 将文件中的数据读取到字节数组
- 将字节数组中的数据写入:response的输出流
- 关流
文件业务类
public class FileService {
//复制文件
public void copy(InputStream inputStream, OutputStream outputStream) throws IOException {
//边读边写
//1.字节数组 缓冲区
byte[] buffer = new byte[1024];
int len = 0;
//2.边读边写
while ((len=inputStream.read(buffer))!=-1){
outputStream.write(buffer,0,len);
}
}
}
将src目录下的a.jpg文件复制到整个项目下
//文件复制
@Test
public void test01() throws IOException {
//读取该文件
String file1 = "a.jpg";
//复制上个文件到该文件
String file2 = "b.jpg";
//加载src目录下的文件
InputStream inputStream = TestFileService.class.getClassLoader().getResourceAsStream(file1);
//创建一个新的空文件,防止没有file2文件
File file = new File(file2);
file.createNewFile();
OutputStream outputStream = new FileOutputStream("b.jpg");
//1.创建文件业务类
FileService fileService = new FileService();
//2.调用业务方法copy
fileService.copy(inputStream,outputStream);
//3.关闭流
inputStream.close();
outputStream.close();
}
3、浏览器访问Servlet显示图片
在web目录下添加以下文件
//1.加载web目录下的a.jpg文件成为一个输入流
InputStream inputStream = getServletContext().getResourceAsStream("download/a.jpg");
//2.再使用字节流 将数据写到浏览器
OutputStream outputStream = response.getOutputStream();
//3.浏览器自动将数据显示成图片
FileService fileService = new FileService();
fileService.copy(inputStream,outputStream);
//4.关闭流
outputStream.close();
inputStream.close();
4、超链接访问文件
点击链接可以直接读取文件。
浏览器本身支持,本质也是先读文件,再将文件写到浏览器。
<a href="/web01_response/download/a.jpg">点一点看图片</a><br/>
<a href="/web01_response/download/a.mp3">点一点看mp3</a><br/>
<a href="/web01_response/download/a.mp4">点一点看mp4</a><br/>
<a href="/web01_response/download/a.zip">点一点看zip</a><br/>
5、文件的下载
- 文件的复制
本质就是将一个文件的所有字节 读出来,再复制到另一个文件中。 - 打开网络文件
浏览器读服务器的文件,本质也是复制。 - 下载网络文件
本质文件复制,不过通过设置响应头,控制浏览器以附件的形式下载。
弹出保存框
如果需要浏览器弹出保存框,则需要通过设置响应头的两个指令 :
Content-Type 设置MIME-Type,也就是根据文件的后缀名有对应的type值设置。
Content-Disposition 设置附件名称,也就是文件名。
//指令,调用浏览器弹出下载框,由用户自己保存
response.setHeader("Content-Type", image/jpg);
response.setHeader("Content-Disposition", "attachment;filename=a.jpg");
getMimeType方法
当下载的文件不知道是什么后缀名,可以使用**getMimeType()**方法
//获取请求参数中的文件名
String filename = request.getParameter("filename");
//根据文件的后缀名得到mime-type类型,如:.jpg image/jpeg
String mimeType = getServletContext().getMimeType(filename);
//指令,调用浏览器弹出下载框,由用户自己保存
response.setHeader("Content-Type", mimeType);
response.setHeader("Content-Disposition", "attachment;filename="+filename );
文件名为中文
1、如果是非中文的保存名称,浏览器可以正常保存,但如果是中文的话,需要进行先进行URL编码
美女 -----> %ED%AD%AC
2、不同的浏览器转码方式不一样: IE浏览器 火狐浏览器 其他浏览器
下面是一个转码的方法
public String getFileName(HttpServletRequest request,String filename) throws UnsupportedEncodingException {
String agent = request.getHeader("User-Agent");
if (agent.contains("MSIE")) {
// IE浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}
然后对传入的文件名进行处理
//获取请求参数中的文件名
String filename = request.getParameter("filename");
//将传入的文件名进行处理
String saveName = getFileName(request,filename);
//自动根据文件的后缀名得到mime-type类型 .jpg image/jpeg
String mimeType = getServletContext().getMimeType(filename);
//指令,调用浏览器弹出下载框,由用户自己保存
response.setHeader("Content-Type", mimeType);
response.setHeader("Content-Disposition", "attachment;filename="+saveName);