我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。
service方法中的response的类型是ServletResponse,而doGet/doPost方法的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大。
1.response的运行流程
因为response代表响应,所以我们可以通过该对象分别设置Http响应的响应行,响 应头和响应体
1.通过response设置响应行
设置响应行的状态码
setStatus(int sc)
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //相应行 response.setStatus(404); }
2.通过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表示设置
重定向需要:1.状态码:302
2.响应头:location 代表重定向地址
MyServlet01直接跳转到MyServlet02
public class MyServlet01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //response.setStatus(302);//设置状态码302 //设置Location头 //response.setHeader("Location","/Web03/MyServlet02" ); //重定向 response.sendRedirect("/Web03/MyServlet02"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
public class MyServlet02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().write("hello dandan..."); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
3.通过response设置响应体
设置定时刷新
public class RefreshServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //定时shuaxin response.setHeader("Refresh","5;url=http://www.baidu.com"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
(1)响应体设置文本
获得字符流,通过字符流的write(
String s)
方法可以将字符串设置到response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览 器端。
关于设置中文的乱码问题
原因: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");
public class BodyServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置缓冲区的码表 //response.setCharacterEncoding("utf-8"); //设置浏览器解析码表 response.setContentType("text/html;charset=utf-8"); response.getWriter().write("你好"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
上面的代码不仅可以指定浏览器解析页面时的编码,同时也内含 setCharacterEncoding的功能,所以在实际开发中只要编写 response.setContentType("text/html;charset=UTF-8");就可以解决页面输出中文乱码问题。
(2)响应头设置字节
ServletOutputStream
getOutputStream()
获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字 节,在由Tomcat服务器将字节内容组成Http响应返回给浏览器。
1.案例-完成文件下载
文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。所以文件下载需 要IO技术将服务器端的文件使用InputStream读取到,在使用 ServletOutputStream写到response缓冲区中
上述代码可以将图片从服务器端传输到浏览器,但浏览器直接解析图片显示在页面上, 而不是提供下载,我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方 式。
1)告知浏览器文件的类型:response.setContentType(文件的MIME类型);
2)告示浏览器文件的打开方式是下载:
response.setHeader("Content-Disposition","attachment;filename=文件名称");
但是,如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况, 原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐 浏览器是Base64编码方式。所里这里需要解决浏览器兼容性问题,解决浏览器兼容 性问题的首要任务是要辨别访问者是ie还是火狐(其他),通过Http请求体中的一 个属性可以辨别
解决乱码方法如下(不要记忆--了解):
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");
}
其中agent就是请求头User-Agent的值
public class DownloadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取文件名 String filename=request.getParameter("filename"); //解决中文乱码 filename=new String(filename.getBytes("ISO-8859-1"),"UTF-8"); //获取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"); } //图片,txt下载 //1.告知浏览器文件MIME类型 response.setContentType(getServletContext().getMimeType(filename)); //2.告知浏览器改文件的打开方式是以附件方式打开 response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder); //获取文件绝对 String path=getServletContext().getRealPath("download/"+filename); //明确数据源 FileInputStream fis=new FileInputStream(path); //目的地 ServletOutputStream out=response.getOutputStream(); int len=0; byte[] bytes=new byte[1024]; while((len=fis.read(bytes))!=-1){ out.write(bytes,0,len); } fis.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
<body> <a href="/Web03/DownloadServlet?filename=小薯条.jpg">小薯条.jpg</a> <a href="/Web03/DownloadServlet?filename=a.wmv">a.wmv</a> <a href="/Web03/DownloadServlet?filename=a.zip">a.zip</a> <a href="/Web03/DownloadServlet?filename=a.txt">a.txt</a> </body>
response细节点:
- response获得的流不需要手动关闭,web容器(tomcat容器)会帮助我们关闭,
- getWriter和getOutputStream不能同时调用
- 重定向语句一般作为终结代码