一.介绍
1:HttpServletResponse接口来自于Servlet规范中,在Tomcat中存在servlet-api.jar
可以看到HttpServletResponse接口继承于ServleResponse接口
2:HttpServletResponse接口实现类由Http服务器负责提供
3:HttpServletResponse接口负责将doGet/doPost方法执行结果以二进制的形式写入到【响应体】交给浏览器,即我们常说的服务器找到资源后放入http响应协议包中发给请求方
4: 开发人员习惯于将HttpServletResponse接口修饰的对象称为【响应对象】,例如HttpServletResponse response,response为一个响应对象。
二.主要功能
1) 将执行结果以二进制形式写入到【响应体】
2) 设置响应头中[content-type]属性值,从而控制浏览器使用对应编译器将响应体二进制数据编译为【文字,图片,视频,命令】
3) 设置响应头中【location】属性,将一个请求地址赋值给location.放入响应协议包,当http响应协议包返回给浏览器后,从而控制浏览器向指定服务器发送请求,
resp.sendRedirect方法内部的原理便是location 属性
三.编程实战
下面我们对HttpServletResponse接口进行编程实战:
第一种情况:我们此时浏览器的请求发送到了后台,后台接收到了请求,想要返回给浏览器一个字符串,那么此时怎么将这个字符串写入到我们的响应体中呢?
答:分为两步:
第一步:首先通过我们的响应对象resp调用getWriter方法来向我们的Tomcat索要我们的输出流,代码如下所示:
PrintWriter printwriter=resp.getWriter();
第二步:通过输出流来将我们的数据以二进制的形式放入到我们的响应体中,注意此处我们所用的方法为print方法,括号中放入我们想要传给浏览器的字符串参数名即可,假定为name:
printwriter.print("name");
第二种情况:write方法与print方法的区别在哪里?
下面先来看一段代码:思考最后代码的输出结果:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int money = 97; PrintWriter out = resp.getWriter(); out.write(money); }
最终我们会看到程序返回给前台的结果为a,这是为什么呢?原因是假如此时我们使用write方法的话,在它将数字写入响应体的时候会先将数字转变为ASCII码,然后再写入响应体中。
而当我们使用print方法的时候,我们会看到程序返回给前台的结果为97了。
总结:write方法一般会将【字符】,【字符串】,【ASCII码】写入到响应体,而在我们的实际开发中,用的最多的还是我们的print方法,它会将真实数据写入到响应体。
第三种情况:既然聊到了我们的print方法,那么再来看下关于print方法的最常见的一个情况,下面先来看代码:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = "宋彪<br/>喜欢喝水<br/>"; PrintWriter printWriter = resp.getWriter(); printWriter.print(name); }
前面我们说过,在开发的过程中我们最常见的是我们的print方法,那么思考上面的字符串最终返回给浏览器的时候会不会出现乱码的情况呢?
答:答案当然是会了,前面我们提到过HttpServlet接口会为我们的响应头中的[content-type]属性值设置值,在我们没有使用任何设置手段的时候,默认的[content-type]属性的值为“text” ,即content-type="text",意为指定我们的浏览器使用文本编译器来解析我们http响应协议包中的响应体的二进制数据。但是此时解析的时候发现我们的二进制数据中不但有文本,还有html标签,文字,这些此时是不能够被浏览器解析的,浏览器会默认将<br/>和中文作为文本在浏览器窗口展示出来,并没有把<br/>和中文字符当做html标签命令和中文文字,那么此时便必须由我们的后台去指定新的[content-type]属性值,此时代码如下所示:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = "宋彪<br/>喜欢喝水<br/>"; //定义新的content-type属性值 resp.setContentType("text/html;charset=utf-8"); //向Tomcat索要输出流 PrintWriter printWriter = resp.getWriter(); //通过输出流将结果写入响应体 printWriter.print(name); }
此时需要由我们的响应体对象resp去调用setContentType方法来定义新的[content-type]属性值。
text意为文本编译器,html意为标签编译器,charset=utf-8意为文字编译器。
注意:设置我们content-type属性值的位置必须在我们向tomcat索要输出流之前。
第四种情况:这块我们来介绍下我们的location属性吧
假如此时我们的服务器端想让我们的浏览器端去访问一个新的地址的话,便会用到location属性。
举个例子,这里先提到一个重定向的概念,即我们的resp.sendRedirect方法,此时先来看一段代码:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name="http://www.baidu.com?userName=mike"; resp.sendRedirect(name); }
此时我们当浏览器发送请求到后台服务器后,服务器此时执行了重定向方法,将我们想要浏览器待会访问的地址放入到我们的http响应协议包的响应头中的【location】属性中,然后当我们的http响应协议包返回给浏览器后,从而控制浏览器向指定服务器发送请求,这里我们指定向百度发送一个请求。
为了方便大家的观看location的效果,此处我们使用Fiddler这个抓包工具来看下:
可以看到当我们使用重定向方法后,这个地址就被放到了location属性值里。