目录
1.HttpServletResponse对象
我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。
service方法中的response的类型是ServletResponse,而doGet/doPost方法的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口。专门用来封装http响应消息。
2.response的运行流程
3. 通过response设置响应行
设置响应行的状态码
setStatus(int sc)
4.通过response设置响应头
addHeader(String name, String value)
addIntHeader(String name, int value)
addDateHeader(String name, long date)
setHeader(String name, String value)
setDateHeader(String name, long date)
setIntHeader(String name, int value)
add表示添加,set表示设置
重定向:状态码:302;响应头:location 代表重定向的位置
//没有响应资源,告知客户端重定向到servlet2
//1.设置状态码302
response.setStatus(302);
//2.设置响应头Location
response.setHeader("Location", "/WEB14/servlet2");
//封装成一个重定向的方法sendRedirect(url)
response.sendRedirect("/WEB14/servlet2");
设置定时刷新的响应头
//设置定时刷新的头
response.setHeader("refresh","5;url=http://www.baidu.com");
使用JS完成页面定时跳转
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
window.onload = function(){
var time = 5;
var secondEle = document.getElementById("second");
var timer = setInterval(function(){
secondEle.innerHTML = time;
time--;
if(time==0){
clearInterval(timer);
location.href="http://www.baidu.com";
}
},1000);
}
</script>
</head>
<body>
恭喜你,注册成功,<span style="color:red" id="second">5</span>秒钟后跳转,如不跳转点击<a href="http://www.baidu.com">这里</a>!
</body>
</html>
5.通过response设置响应体
1)响应体设置文本
获得字符流,通过字符流的write(String s)方法可以将字符串设置到response缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
PrintWriter writer = response.getWriter();
response对象通过getWriter()拿到PrintWriter类型的字符流,然后对流进行操作。
关于设置中文的乱码问题
//设置response查询的码表
//response.setCharacterEncoding("UTF-8");
//通过一个头Content-Type告知客户端使用何种码表
//response.setHeader("Content-Type", "text/html;charset=UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
//writer.write("hello response!!!");
writer.write("中国");//??
原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文,可以通过response的setCharacterEncoding(String charset) 设置response的编码
但我们发现客户端还是不能正常显示文字
原因:我们将response缓冲区的编码设置成UTF-8,但浏览器的默认编码是本地系统的编码,因为我们都是中文系统,所以客户端浏览器的默认编码是GBK,我们可以 手动修改浏览器的编码是UTF-8。
我们还可以在代码中指定浏览器解析页面的编码方式,
通过response的setContentType(String type)方法指定页面解析时的编码是UTF-8
response.setContentType("text/html;charset=UTF-8");
上面的代码不仅可以指定浏览器解析页面时的编码,同时也内含 setCharacterEncoding(设置response编码)的功能,所以在实际开发中只要编写
response.setContentType("text/html;charset=UTF-8");就可以解决页面输出中文乱码问题。
2)响应头设置字节
ServletOutputStream getOutputStream()
获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,在由Tomcat服务器将字节内容组成Http响应返回给浏览器。
//使用response获得字节输出
ServletOutputStream out = response.getOutputStream();
//获得服务器上的图片
String realPath = this.getServletContext().getRealPath("a.jpg");
InputStream in = new FileInputStream(realPath);
int len = 0;
byte[] buffer = new byte[1024];
while((len=in.read(buffer))>0){
out.write(buffer, 0, len);
}
in.close();
out.close();
6.文件下载案例
问题
1)什么情况会文件下载?
浏览器不能解析的文件就会下载。
2)什么情况需要在服务器编写文件下载代码?
理论上,浏览器可以解析的代码需要编写文件下载代码。
实际开发中,只要是下载的文件都编写文件下载代码
<h1>使用服务器端编码的方式实现文件下载</h1>
<a href="/WEB14/downloadServlet?filename=a.flv">a.flv</a><br>
<a href="/WEB14/downloadServlet?filename=a.jpg">a.jpg</a><br>
<a href="/WEB14/downloadServlet?filename=a.mp3">a.mp3</a><br>
<a href="/WEB14/downloadServlet?filename=a.mp4">a.mp4</a><br>
<a href="/WEB14/downloadServlet?filename=a.txt">a.txt</a><br>
<a href="/WEB14/downloadServlet?filename=a.zip">a.zip</a><br>
<a href="/WEB14/downloadServlet2?filename=美女.jpg">美女.jpg</a><br>
文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。所以文件下载需要IO技术将服务器端的文件使用InputStream读取到,在使用ServletOutputStream写到response缓冲区中。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得要下载文件的名称
String filename = request.getParameter("filename");
//要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
response.setContentType(this.getServletContext().getMimeType(filename));
//告诉客户端该文件不是直接解析 而是以附件形式打开(下载)
response.setHeader("Content-Disposition", "attachment;filename="+filename);
//获得文件的绝对路径
String path = this.getServletContext().getRealPath("download/"+filename);
//获得文件的输入流
InputStream in = new FileInputStream(path);
//获得输出流--通过response获得输出流,用于向客户端写内容
ServletOutputStream out = response.getOutputStream();
//文件拷贝的模板代码
int len = 0;
byte[] buffer = new byte[1024];
while((len=in.read(buffer))>0){
out.write(buffer, 0, len);
}
in.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方式。
- 告知浏览器文件的类型:response.setContentType(文件的MIME类型);
- 告示浏览器文件的打开方式是下载:response.setHeader("Content-Disposition","attachment;filename=文件名称");
文件下载中文乱码
下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况,原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐浏览器是Base64编码方式。所里这里需要解决浏览器兼容性问题。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//***文件名称是中文的下载***
//获得要下载文件的名称
String filename = request.getParameter("filename");//???.jpg
//解决获得中文参数的乱码
filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg
//要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型
response.setContentType(this.getServletContext().getMimeType(filename));
//获得请求头中的User-Agent
String agent = request.getHeader("User-Agent");
//根据不同浏览器进行不同的编码
String filenameEncoder = "";
if (agent.contains("MSIE")) {
// IE浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
filenameEncoder = filenameEncoder.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncoder = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else {
// 其它浏览器
filenameEncoder = URLEncoder.encode(filename, "utf-8");
}
//告诉客户端该文件不是直接解析 而是以附件形式打开(下载)----filename="+filename 客户端默认对名字进行解码
response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);
//获得文件的绝对路径
String path = this.getServletContext().getRealPath("download/"+filename);
//获得文件的输入流
InputStream in = new FileInputStream(path);
//获得输出流--通过response获得输出流,用于向客户端写内容
ServletOutputStream out = response.getOutputStream();
//文件拷贝的模板代码
int len = 0;
byte[] buffer = new byte[1024];
while((len=in.read(buffer))>0){
out.write(buffer, 0, len);
}
in.close();
}
response细节点
1)response获得的流不需要手动关闭,Tomcat容器会帮助我们关闭
2)getWriter和getOutputStream不能同时调用