HttpServletResponse
在创建Servlet时会重写service()方法,或doGet()/doPost(),这些方法都需要传入两个参数,一个是代表请求的request,一个是代表响应的response。
service方法中的response的类型是ServletResponse,而doGet/doPost方法中的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大。
response的运行流程
首先,客户端网页输入链接地址,发送请求,并被封装为Http请求。这个请求会被tomcat服务器接收传送到tomcat引擎,即tomcat内核。tomcat内核首先解析请求的资源,然后将请求的信息封装成request对象,与此同时创建一个response对象,然后创建servlet对象,最后调用service方法。服务器在web应用中去运行service方法。write()方法是将响应的内容写到response缓冲区中。服务器会自动监测到service方法中的内容是否写完,当service方法结束后,方法返回到tomcat内核去该response缓冲区去获取设置的内容。tomcat从response中获取设置的内容组装成一个Http响应,这里面包括响应行、响应头、响应体。最后将该Http响应返回到客户端解析Http响应显示页面。
通过response设置响应行
设置响应行的状态码
setStatus(int sc)
例如:response.setStatus(404); 设置状态码
通过response设置响应头
addHead(String name,String value)
addIntHead(String name,int value)
addDateHead(String name,long date)
setHead(String name,String value)
setDateHead(String name,long date)
setIntHead(String name,int value)
package com.oracle.demo01; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.addHeader("name", "张三"); response.addIntHeader("age", 18); response.addDateHeader("birthday", 2000000000L); response.setIntHeader("age", 30); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
重定向需要:
1、状态码:302
2、响应头:Location 代表重定向地址
package com.oracle.demo02; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class servlet01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 原生代码 // 没有响应,告知客户端去重定向到servlet02 // 1、设置状态码302 // response.setStatus(302); // 2、设置响应头Location // response.setHeader("Location", "servlet02"); // 开发中常用的重定向方法 response.sendRedirect("servlet02"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
通过response设置响应体
(1)响应体设置文本
PrintWriter 的getWriter()获得字符流,通过字符流的write(String s)方法可以将字符串设置到response缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回到浏览器端。
中文乱码的问题
response缓冲区的默认编码时ISO8859-1,此码表中没有中文,可以通过response的setCharacterEncoding(String charset)设置response的编码格式,如UTF-8
response.setCharacterEncoding("UTF-8");
在将response缓冲区的编码设置为UTF-8,但是浏览器的默认编码是本地系统的编码,由于我们都是中文系统,所以客户端浏览器的默认编码是GBK,我们可以手动修改浏览器的编码为UTF-8.
在开发中,通常在代码中指定浏览器解析页面的编码方式,通过response的setContentType(String type)方法指定页面解析的编码为UTF-8
response.setContentType("text/html;charset=UTF-8");
这条代码中隐含有设置response缓冲区的编码为UTF-8的功能。
package com.oracle.demo01; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置response缓冲区中的编码方式 // response.setCharacterEncoding("UTF-8"); //response.setHeader("Content-type", "text/html;charset=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); } }
(2)响应头设置字节
ServletOutputStream getOutputStream()获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由tomcat服务器将字节内容组成Http响应返回给浏览器。
package com.oracle.demo01; import java.io.FileInputStream; import java.io.IOException; 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 Servlet02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 使用response获得字节输出流 ServletOutputStream out = response.getOutputStream(); // 获得服务器上的图片 String path = this.getServletContext().getRealPath("aaa.jpg"); FileInputStream in = new FileInputStream(path); int len = 0; byte[] bytes = new byte[1024]; while ((len = in.read()) != -1) { out.write(bytes, 0, len); } in.close(); out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
文件的下载
文件的下载就是将文件从服务器拷贝到浏览器端。运用IO技术将服务器端的文件通过InputStream读取到,然后通过ServletOutputStream写入到response缓冲区中。
上述代码可以将图片从服务器端传输到浏览器,但浏览器直接解析图片显示在页面上, 而不是提供下载,我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方 式。
1)告知浏览器文件的类型:response.setContentType(文件的MIME类型);
2)告示浏览器文件的打开方式是下载:response.setHeader("Content-Disposition","attachment;filename=文件名称");
package com.oracle.demo01; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import sun.misc.BASE64Encoder; 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 filenameEncoding=""; if (agent.contains("MSIE")) { // IE浏览器 filenameEncoding = URLEncoder.encode(filename, "utf-8"); filenameEncoding = filename.replace("+", " "); } else if (agent.contains("Firefox")) { // 火狐浏览器 BASE64Encoder base64Encoder = new BASE64Encoder(); filenameEncoding = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else { // 其它浏览器 filenameEncoding = URLEncoder.encode(filename, "utf-8"); } // 要下载的这个文件类型--客户端通过文件的MIME类型去区分类型 response.setContentType(this.getServletContext().getMimeType(filename)); // 告诉客户端该文件不是直接解析,而是以附件的形式打开(下载) response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoding); // 获取下载的文件在服务器上的绝对路径 String path = this.getServletContext().getRealPath("download/" + filename); // 获取输出流,通过response获得输出流,用于向客户端写内容 ServletOutputStream out = response.getOutputStream(); // 获取该文件的输入流 FileInputStream in = new FileInputStream(path); // 文件拷贝的模板 int len = 0; byte[] bytes = new byte[1024]; while ((len = in.read()) != -1) { out.write(bytes, 0, len); } in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }