HttpServletResponse

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。(注意到request和response对象都是web服务器端创建的)

HttpServletResponse对象介绍

HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
HttpServletResponse对象的功能分为以下4种:

  • 设置响应头信息
  • 发送状态码
  • 设置响应正文
  • 重定向

查看HttpServletResponse的API,可以看到这些相关的方法。


HttpServletResponse
一些常见的状态码常量
404:SC_NOT_FOUND
500:SC_INTERNAL_SERVER_ERROR
200:SC_OK

设置状态码

response.setStatus(200)://设置状态码;
response.sendError(404, “您要查找的资源不存在”)
HttpServletResponse对象常用方法
负责向客户端(浏览器)发送数据的相关方法
  • ServletOutputStream getOutputStream() ;该方法用于返回Servlet引擎创建的""字节输出流""对象,Servlet程序可以按字节形式输出响应正文。
  • PrintWriter getWriter();该方法用于返回Servlet引擎创建的字符输出流对象,Servlet程序可以按字符形式输出响应正文。
PrintWriter out = response.getWriter():获取字符流;
ServletOutputStream out = response.getOutputStream():获取字节流;

注意:

  • 两个方法相互排斥,若同时使用,则会抛出IlegalStateException异常。
  • getOutputStream()返回的字节输出流对象,类型为:ServletOutputStream,直接输出字节数组中的二进制数据;getWriter()方法将Servlet引擎的数据缓冲区包装成PrintWriter类型的字符输出流对象后返回,PrintWriter对象只能输出字符文本内容
  • 在使用response.getWriter()时需要注意默认字符编码为ISO-8859-1,如果希望设置字符流的字符编码为utf-8,可以使用response.setCharaceterEncoding(“utf-8”)来设置。这样可以保证输出给客户端的字符都是使用UTF-8编码的! 但客户端浏览器并不知道响应数据是什么编码的!如果希望通知客户端使用UTF-8来解读响应数据,那么还是使response.setContentType(“text/html;charset=utf-8”)方法比较好,因为这个方法不只会调用response.setCharaceterEncoding(“utf-8”),还会设置content-type响应头,客户端浏览器会使用content-type头来解读响应数据。
  • response.getWriter()是PrintWriter类型,所以它有缓冲区,缓冲区的默认大小为8KB。也就是说,在响应数据没有输出8KB之前,数据都是存放在缓冲区中,而不会立刻发送到客户端。当Servlet执行结束后,服务器才会去刷新流,使缓冲区中的数据发送到客户端。 如果希望响应数据马上发送给客户端:
    向流中写入大于8KB的数据; 调用response.flushBuffer()方法来手动刷新缓冲区;
负责向客户端(浏览器)发送响应头的相关方法
  • addDateHeader(String name ,long date) 该方法是添加只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
  • addHeader(String name,String value) 该方法是添加有多个值的响应头,参数name表示响应头名称,参数value表示响应头的值
  • addIntHeader(String name,int value) 该方法是添加有多个值且值的类型为int类型的响应头
  • setHeader(String name,String value) 该方法是设置只有一个值的响应头,参数name表示响应头名称,参数value表示响应头的值
  • setDateHeader(String name,long value) 该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间
  • setIntHeader(String name,int value) 该方法是设置只有一个值且值的类型为int类型的响应头,例如Content-Length响应头,该响应头是代表响应内容有多少字节数
response.setHeader(“content-type”, “text/html;charset=utf-8”); 
//设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。
而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”); 
response.setHeader("Refresh","5; URL=http://www.itcast.cn")://5秒后自动跳转到传智主页。 
//设置浏览器禁止缓存 
response.setDateHeader(“expries”, -1); 
response.setHeader(“Cache-Control”, “no-cache”); 
response.setHeader(“Pragma”, “no-cache”);

关于重定向的在上文HTTP协议中介绍了
这里总结

重定向是两次请求;
重定向的URL可以是其他应用,不局限于当前应用;
重定向的响应头为302,并且必须要有Location响应头;
重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常;

HttpServletResponse对象常见应用
使用OutputStream流和PrintWriter流向客户端浏览器输出数据
@WebServlet("/ServletDemo5")
public class ServletDemo5 extends HttpServlet {
    private static final long serialVersionUID = 4312868947607181532L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        outputData(response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }

    public void outputData(HttpServletResponse response) throws IOException{
        /**使用OutputStream输出注意问题:
                  * 在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开,
                  * 比如:outputStream.write("中国".getBytes("UTF-8"));//使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出
                  * 此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码,那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?
                  * 可以通过设置响应头控制浏览器的行为,例如:
                  * response.setHeader("content-type", "text/html;charset=UTF-8");//通过设置响应头控制浏览器以UTF-8的编码显示数据
                  */
        String data = "i miss guanshuqiao very much";
        OutputStream outputStream = response.getOutputStream();//获取outputstream输出流
        response.setHeader("content-type","text/html;charset=UTF-8");
        byte[] dataByteArr = data.getBytes("UTF-8");//将字符转换成字节数组,指定以UTF-8编码进行转换
        outputStream.write(dataByteArr);//使用OutputStream流向客户端输出字节数组
    }
}

打开浏览器访问http://localhost:8080/ServletDemo5

中英文都可以的

@WebServlet("/ServletDemo6")
public class ServletDemo6 extends HttpServlet {
    private static final long serialVersionUID = 4312868947607181532L;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriterData(response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
    public void PrintWriterData(HttpServletResponse response) throws IOException{
        String data = "我很是想念 guanshuqiao";
        response.setContentType("text/html;charset=utf-8");
        /*
        如果不使用response.setContentType()这个方法就要使用
        response.setHeader("content-type", "text/html;charset=UTF-8"); //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
        response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
         */
        PrintWriter printWriter = response.getWriter();
        printWriter.write(data);

    }
}

访问http://localhost:8080/ServletDemo6

访问结果

response.setContentType("text/html;charset=utf-8");等价于response.setHeader("content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");

如果使用的是后者,则需要在获取printwrite输出流之前就要setContentType和setHeader,否则无法生效。
当需要向浏览器输出字符数据时,使用PrintWriter比较方便,省去了将字符转换成字节数组那一步。

在开发过程中,如果希望服务器输出什么浏览器就能看到什么,那么在服务器端都要以字符串的形式进行输出。如果使用PrintWriter流输出数字,那么也要先将数字转换成字符串后再输出

        
        
才疏学浅之处,切莫在意。
                          ;——2019.7.12上午

参考博文:
HttpServletResponse对象(一)
一文看懂HttpServletResponse
javaweb学习总结(七)——HttpServletResponse对象(一)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容