HttpServletResponse对象
- 一、HttpServletResponse对象介绍
- 1.1、负责向客户端(浏览器)发送数据的相关方法
- 1.2、负责向客户端(浏览器)发送响应头的相关方法
- 1.3、负责向客户端(浏览器)发送响应状态码的相关方法
- 1.4、响应状态码的常量
- 二、HttpServletResponse对象常见应用
- 2.1、Response输出方法
- 2.2、Response乱码问题
- 2.3、中文文件下载
- 三、HttpServletResponse常见应用——设置响应头控制浏览器的行为
- 3.1、设置http响应头控制浏览器禁止缓存当前文档内容
- 3.2、设置http响应头控制浏览器定时刷新网页(refresh)
- 3.3、通过response实现请求重定向
- 3.4、重定向与转发的区别
- 四、web工程中URL地址的推荐写法
- 4.1、"/"代表当前web工程的常见应用场景
- 4.2、"/"代表webapps目录的常见应用场景
HttpServletResponse对象
一、HttpServletResponse对象介绍
![9fc837a10ccefdc845c180c074f475cf.png](https://img-blog.csdnimg.cn/img_convert/9fc837a10ccefdc845c180c074f475cf.png)
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。查看HttpServletResponse的API,可以看到这些相关的方法。
1.1、负责向客户端(浏览器)发送数据的相关方法
![ac62f1e76fb75b2c6db424f29d898ab1.png](https://img-blog.csdnimg.cn/img_convert/ac62f1e76fb75b2c6db424f29d898ab1.png)
1.2、负责向客户端(浏览器)发送响应头的相关方法
![b562e7705e1063f4b40e8fc13b0020e6.png](https://img-blog.csdnimg.cn/img_convert/b562e7705e1063f4b40e8fc13b0020e6.png)
![19080a9e99d0977127fe5248ebd21de2.png](https://img-blog.csdnimg.cn/img_convert/19080a9e99d0977127fe5248ebd21de2.png)
1.3、负责向客户端(浏览器)发送响应状态码的相关方法
![fc4c14eb503c775589fa9b5b6cc09355.png](https://img-blog.csdnimg.cn/img_convert/fc4c14eb503c775589fa9b5b6cc09355.png)
1.4、响应状态码的常量
HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:状态码404对应的常量
![5d354b4245a797f97bdfe14d7ed9305b.png](https://img-blog.csdnimg.cn/img_convert/5d354b4245a797f97bdfe14d7ed9305b.png)
状态码200对应的常量
![6f356c85faead72fd38c9b410627b786.png](https://img-blog.csdnimg.cn/img_convert/6f356c85faead72fd38c9b410627b786.png)
状态码500对应的常量
![cf3cc8bf036385e9fff76db05ac72d6d.png](https://img-blog.csdnimg.cn/img_convert/cf3cc8bf036385e9fff76db05ac72d6d.png)
二、HttpServletResponse对象常见应用
2.1、Response输出方法
- PrintWriter getWriter()
- 获得字符流,通过字符流的write(String s)方法可以将字符串设置到response缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
- ServletOutputStream getOutputStream()
- 获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。
注意:虽然response对象的getOutSream()和getWriter()方法都可以发送响应消息体,但是他们之间相互排斥,不可以同时使用,否则会发生异常。
2.2、Response乱码问题
乱码发生的原因:
计算机中的数据都是以二进制进行存储的,因此传输文本时,就会发生字节和字符之间的转换。字符与字节之间的转换需要查码表完成,将字符转换为字节的过程叫做编码,将字节转换为字符的过程叫做解码。如果编码和解码使用的码表不一致,就会发生乱码。这就是乱码发生的根本原因
①、response缓冲区的默认编码是iso8859-1,此码表中没有中文。所以需要更改response的编码方式:
![7bb3cd8276573a4605f0cfdb62740580.png](https://img-blog.csdnimg.cn/img_convert/7bb3cd8276573a4605f0cfdb62740580.png)
②、通过更改response的编码方式为UTF-8,任然无法解决乱码问题,因为发送端服务端虽然改变了编码方式为UTF-8,但是接收端浏览器端仍然使用GB2312编码方式解码,还是无法还原正常的中文,因此还需要告知浏览器端使用UTF-8编码去解码。
![eceb0099dab2da2e643458440f471761.png](https://img-blog.csdnimg.cn/img_convert/eceb0099dab2da2e643458440f471761.png)
上面通过调用两个方式分别改变服务端对于Response的编码方式以及浏览器的解码方式为同样的UTF-8编码来解决编码方式不一样发生乱码的问题。response.setContentType("text/html;charset=UTF-8")
这个方法包含了上面的两个方法的调用,因此在实际的开发中,只需要调用一个response.setContentType("text/html;charset=UTF-8")
方法即可。
![9ba0597efca658df5612877020fbaed2.png](https://img-blog.csdnimg.cn/img_convert/9ba0597efca658df5612877020fbaed2.png)
2.3、中文文件下载
示例:文件下载 注意:下载中文文件时,需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码:URLEncoder.encode(fileName, "字符编码"),否则会出现文件名乱码。ResponseDemo02.java
- package com.lovo.study;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.URLEncoder;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class ResponseDemo02 extends HttpServlet {
- private static final long serialVersionUID = 1L;
- public ResponseDemo02() {
- super();
- }
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- //获取要下载文件的绝对路劲
- String realPath = this.getServletContext().getRealPath("/downloads/美女.jpg");
- //获取要下载的文件名
- String fileName = realPath.substring(realPath.lastIndexOf("") + 1);
- //设置content-disposition响应头控制浏览器以下载的形式打开文件,
- //中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
- response.setHeader("Content-disposition",
- "attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
- InputStream in = new FileInputStream(realPath);
- int len = 0;
- byte [] buffer = new byte[1024];
- OutputStream out = response.getOutputStream();
- while((len = in.read(buffer)) > 0){
- out.write(buffer,0,len);
- }
- in.close();
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- doGet(request, response);
- }
- }
三、HttpServletResponse常见应用——设置响应头控制浏览器的行为
3.1、设置http响应头控制浏览器禁止缓存当前文档内容
- response.setDateHeader("expries", -1);
- response.setHeader("Cache-Control", "no-cache");
- response.setHeader("Pragma", "no-cache");
3.2、设置http响应头控制浏览器定时刷新网页(refresh)
- response.setHeader("refresh", "5");//设置refresh响应头控制浏览器每隔5秒钟刷新一次
3.3、通过response实现请求重定向
请求重定向:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。实现方式:response.sendRedirect(String location),即调用response对象的sendRedirect方法实现请求重定向sendRedirect内部的实现原理:使用response设置302状态码和设置location响应头实现重定向
- package com.lovo.study;
- 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 ResponseDemo03 extends HttpServlet {
- private static final long serialVersionUID = 1L;
- public ResponseDemo03() {
- super();
- }
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- /**
- * 1.调用sendRedirect方法实现请求重定向,
- * sendRedirect方法内部调用了
- * response.setHeader("Location", "/request_form.jsp");
- * response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
- */
- response.sendRedirect("/request_form.jsp");
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- doGet(request, response);
- }
- }
3.4、重定向与转发的区别
1)转发是服务器行为,重定向是客户端行为。 为什么这样说呢,这就要看两个动作的工作流程:转发过程:客户浏览器发送http请求——web服务器接受此请求——调用内部的一个方法在容器内部完成请求处理和转发动作——将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。重定向过程:客户浏览器发送http请求——web服务器接受后发送302状态码响应及对应新的location给客户浏览器——客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址——服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。2).对信息的传输不一样重定向,其实是两次request第一次,客户端request A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候IE可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。请求转发是服务器内部把对一个request/response的处理权,移交给另外一个对于客户端而言,它只知道自己最早请求的那个A,而不知道中间的B,甚至C、D。传输的信息不会丢失。3).对于路径的认知不一样请求转发是服务器端的动作,所以当转发路径如:
- request.getRequestDispatcher("/RequestDemo07").forward(request, response);
路径前的绝对路径"/",会被认为是当前工程的根目录,也就是说,如果当前路径是:http://localhost:8080/ServletDemo/RequestDemo06那么根据上面的跳转就会跳转到http://localhost:8080/ServletDemo/RequestDemo07而重定向,如下面的路径: response.sendRedirect("/RequestDemo07");如果当前路径是: http://localhost:8080/ServletDemo/RequestDemo06就会跳转到: http://localhost:8080/RequestDemo07
四、web工程中URL地址的推荐写法
在JavaWeb开发中,只要是写URL地址,那么建议最好以"/"开头,也就是使用绝对路径的方式,那么这个"/"到底代表什么呢?可以用如下的方式来记忆"/":如果"/"是给服务器用的,则代表当前的web工程,如果"/"是给浏览器用的,则代表webapps目录。
4.1、"/"代表当前web工程的常见应用场景
①.ServletContext.getRealPath(String path)获取资源的绝对路径
- /**
- * 1.ServletContext.getRealPath("/download/1.JPG")是用来获取服务器上的某个资源,
- * 那么这个"/"就是给服务器用的,"/"此时代表的就是web工程
- * ServletContext.getRealPath("/download/1.JPG")表示的就是读取web工程下的download文件夹中的1.JPG这个资源
- * 只要明白了"/"代表的具体含义,就可以很快写出要访问的web资源的绝对路径
- */
- this.getServletContext().getRealPath("/download/1.JPG");
②.在服务器端forward到其他页面
- /**
- * 2.forward
- * 客户端请求某个web资源,服务器跳转到另外一个web资源,这个forward也是给服务器用的,
- * 那么这个"/"就是给服务器用的,所以此时"/"代表的就是web工程
- */
- this.getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);
③.使用include指令或者<jsp:include>
标签引入页面
- <%@include file="/jspfragments/head.jspf" %>
- <jsp:include page="/jspfragments/demo.jsp" />
此时"/"代表的都是web工程。
4.2、"/"代表webapps目录的常见应用场景
①.使用sendRedirect实现请求重定向
- response.sendRedirect("/index.jsp");
服务器发送一个URL地址给浏览器,浏览器拿到URL地址之后,再去请求服务器,所以这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录,也就是上面的路径实际是:
- http://localhost:8080/index.jsp
这样的路径肯定不不正确的,所以要正常访问需要改为:
- response.sendRedirect("/SerlvetDemo(工程名)/index.jsp");
这种写法是将项目名称写死在程序中的做法,不灵活,万一哪天项目名称变了,此时就得改程序,所以推荐使用下面的灵活写法:
- response.sendRedirect(request.getContextPath()+"/index.jsp");
request.getContextPath()获取到的内容就是"/ServletDemo",这样就比较灵活了,使用request.getContextPath()代替"/项目名称",推荐使用这种方式,灵活方便!②.使用超链接跳转
- <a href="/ServletDemo/index.jsp">跳转到首页</a>
这是客户端浏览器使用的超链接跳转,这个"/"是给浏览器使用的,此时"/"代表的就是webapps目录。使用超链接访问web资源,绝对路径的写法推荐使用下面的写法改进:
- <a href="${pageContext.request.contextPath}/index.jsp">跳转到首页</a>
③.Form表单提交④.js脚本和css样式文件的引用 处理方案等同于超链接案例:生成随机图片
- package com.lovo.study;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics2D;
- import java.awt.image.BufferedImage;
- import java.io.IOException;
- import javax.imageio.ImageIO;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class ResponseDemo04 extends HttpServlet {
- private static final long serialVersionUID = 1L;
- public ResponseDemo04() {
- super();
- }
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- response.setHeader("refresh", "5");
- BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
- Graphics2D g = (Graphics2D)image.getGraphics();
- //先设置画笔颜色然后画背景颜色
- g.setColor(Color.WHITE);
- g.fillRect(0, 0, 80, 20);
- //设置画笔颜色画数字
- g.setColor(Color.BLUE);
- //设置字体
- g.setFont(new Font(null, Font.BOLD, 20));
- //生产随机数
- int [] nums = {0,1,2,3,4,5,6,7,8,9};
- String str = "";
- for(int i=0; i<6; i++){
- int n = (int)Math.floor(Math.random() * 10);
- str += n;
- }
- //画字符串
- g.drawString(str, 0, 20);
- //设置响应头以图片方式打开
- response.setContentType("image/jpeg");
- //设置响应头清除缓存
- response.setDateHeader("expries", -1);
- response.setHeader("Cache-Control", "no-cache");
- response.setHeader("Pragma", "no-cache");
- //6.将图片写给浏览器
- ImageIO.write(image, "jpg", response.getOutputStream());
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- doGet(request, response);
- }
- }