一、HttpServletResponse概叙
我们在创建servlet时会覆盖service()方法,或doGet()/doPost()方法,这些方法都有两个参数,一个代表请求的request和代表响应的response。service方法中的response是ServletResponse,而doGet和doPost方法中的response是HttpServletResponse是ServletResponse的子接口,功能更强大。
二、Htttp响应分为响应行、响应头和响应体,所以可以通过response设置响应头和响应体
1、response设置响应行 --- 设置相应行的状态码 response.setStatus(int sc);
2、response设置相应头
response.addHeader(String name, String value);
response.addIntHeader(String name, int value);
response.addDateHeader(String name, Date data);
response.setHeader(String name, String value);
response.setDateHeader(String name, long date);
reposne.setIntHeader(String name, int value);
其中add表示添加,set表示设置
3、通过response设置相应体
1)设置响应体文本
PrintWriter.getWriter() --- 获得字符流,通过字符流的writer()方法将字符串设置到response的缓冲区中,随后Tomcat会将缓冲区的内容组装成Http发送给客户端。
关于设置中文乱码的问题:因为response缓冲区默认的编码是ISO8859-1,此码中没有中文,可以通过response.setCharacterEncoding(String charset)设置response编码。虽然如此设置了,但是浏览器还是不能正确显示中文,原因是我们只设置了缓冲区中的编码,而没有设置浏览器的编码,所以需要我们手动修改浏览器的编码,也可以在代码中设置,指定浏览器的编码方式。response.setContentType("text/html;charset=UTF-8"); 这句代码包含了设置缓冲区编码为utf-8的功能,所以在实际开发中只需要写这一句代码就OK了。
通过ServletOutputStream getOutputStram()获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节。最后由Tomcat发给客户端。
三、案例 --- 完成文件下载
文件下载的实质就是文件拷贝,将文件从服务器拷贝到客户端。所以文件下载需要IO技术将服务器的文件使用InputStream读取到,再使用ServletOutputStream写到response缓冲区中。代码如下:
String filePath = getServletContext().getRealPath("文件路径/文件名称"); //获得文件的绝对路径
InputStream in = new FileInputStream(filepath); //使用io读到该文件
OutputStream out = response.getOutputStream();//将文件写到response缓冲区中
int len = 0;
byte[] buffer = new byte[1024];
while((len = in.read(buffer)) > 0){
out.write(buffer, 0, len);
}
in.close();关闭资源 //out.close();response获得流不需要手动关闭 Tomcat会自动关闭
比如上述文件的的地址写的是一张图片的地址,那么代码完成了将服务器上的图片传给浏览器,但是浏览器并没有下载而是自动解析,将图片显示在页面上。因此,如果需要浏览器下载该文件,需要告诉浏览器文件的类型和文件的打开方式。正确的文件下载的代码,只要在上述代码前加上下面两句:
response.setContentType(getServletContext().getMimeType("a.jpg"));//设置文件的Mime类型
response.setHeader("Content-Disposition", "attachment;filename=a.jpg");//告知浏览器打开文件的方式是下载
如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况, 原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐 浏览器是Base64编码方式。所里这里需要解决浏览器兼容性问题,解决浏览器兼容 性问题的首要任务是要辨别访问者是ie还是火狐(其他),通过Http请求体中的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");
}