(五)Respose 知识点总结 (来自那些年的笔记)


目录


HttpServletResponse简介

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的 response对象

Requestresponse 对象,既然代表请求和响应,那么我们要 获取客户端提交过来的数据,只要找到request对象就OK了;要向客户机输出数据,只要找response对象就OK了


向客户机写数据

需要一个响应行响应头响应数据 ;这些 HttpServletResponse 对象都提供方法来完成 ;

  • 响应行就是一个状态码:

    设置状态码: setStatus(int) ;

  • 响应头

    写响应头 : setHeader(键,值)
    添加响应头: addHeader(键,值)

    response.setHeader("xxxx","yyyy");

    二者区别:如果已经有某一个头存在了。那么前者会覆盖掉这个头,后者会添加新的 ;

    关于添加和写响应头,Sun 公司还提供了另个添加特别的头的方法:
    添加整数: setIntHeader(头名字,int)
    添加时间: setDataHear(头名字,long)

    不然,我们将时间、整数转换为字符串,还需要做特定转换;

    HttpServletResponse 并没有输出流的方法,他输出流的方法,来自其父类ServlrtResponse ,这个类有两个输出流,一个字节流,一个字符流

//  字字流输出
    ServletOutputStream getOutputStream() throws IOException;
//  字符流输出
    PrintWriter getWriter() throws IOException;
  • 检测是否包含某个头

    containsHeader(头名字)


HttpServletResponse应用

下面都是具体的应用

打印中文,让浏览器显示不乱码 ;

思路:在往 response 里面写数据的时候,我们要 指定数据的解码方式;并且还要 添加响应头来告诉浏览器用什么码表来编码 ,否则,虽然我们对网页指定了编码,但是浏览器不知道我们是啥码表编码的;


  • 方式一(通过响应头来控制浏览器--使用OutputStream)
//      准备发送给浏览器的汉字
          String name = "中国";
//      在响应头中写上编码方式
        response.setHeader("content-type", "text/html;charset=utf-8");
//      因为我们使用的是字节流,因此,将字符串转换为字节
//      通过getByte()方法,是可以指定解码的码表,不写就是默认按照平台的码表
        response.getOutputStream().write(name.getBytes("utf-8"));

  • 方式二(通过meta标签)
  meta 标签是可以控制浏览器的行为的;

<meta http-equiv='content-type' content='text/html;charset=utf-8'>


这句标签的意思是告诉,向你输出的是一个HTML页面,编码是utf-8

//        准备发送给浏览器的汉字
        String name = "我独自穿越这条伤心的街
" +
                "
" +
                "怎么忘记你回过头的身影
" +
                "
" +
                "我鼓起勇气忘记这个距离
" +
                "
" +
                "怎么告诉你爱已慢慢烧尽
" +
                "
" +
                "不如远走高飞自己解围";
//        获取输出流
        ServletOutputStream outputStream = response.getOutputStream();

//     meta标签这句话全是英文,英文无论在哪个码表,码值都是一样的,
//     因此,可以使用任何一张码表进行解码,这里 getBytes() 没有指定使用什么码表,
//     因此默认使用平台的编码表
        outputStream.write("<meta http-equiv='content-type' content='text/html;charset=utf-8'>".getBytes());
        outputStream.write("<hr>".getBytes());
        //name是汉字字符串,因此进行编码
        outputStream.write(name.getBytes("utf-8"));

  • 方式三(通过PrintWriter 标签)

上面两种方式,都是通过字节流输出文字的,第三种则通过字符流输出 ;

 String message = "你都如何回忆我" +
                "<br>" +
                "带着笑或是很沉默";
//      避免乱码问题,我们要为response指定码表
//      写数据,这里不指定码表的话,它会默认使用老外的iso码表 ;
//      这张码表里面根本就没有汉字;因此,汉字编码时查表都是问号 ??
        response.setCharacterEncoding("utf-8");
//      还要告诉浏览器,我们的编码方式
        response.setHeader("content-type","text/html;charset=utf-8");
////       这一句代码可以完成上面的两步操作
//        response.setContentType("text/html;charset=utf-8");

//        获得printWriter
        PrintWriter writer = response.getWriter() ;

        writer.write(message);

下载文件

只要在浏览器的响应头中,添加一个响应头:content-disposition","attachment;filename=

如果下载文件的名字是中文的话,需要URL编码 : URLEncoder.encode(name,"UTF-8")

//        下载文件,需要获取文件的名字,因此使用获得绝对路径的方法
       String path = this.getServletContext().getRealPath("/download/古风.jpg") ;
//        从绝对路径中截取出文件的名字
        String name = path.substring(path.lastIndexOf("\")+1) ;

//        告诉浏览器用下载的方式打开文件
//        下载文件的文件的文件名是中文,
//        需要URL编码,URLEncoder.encode
//        这里写明URL编码,
        response.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(name,"UTF-8"));

//        读取照片资源,
        InputStream in = new FileInputStream(path) ;
//        将数据写回到浏览器
        ServletOutputStream out = response.getOutputStream();
        int len = 0 ;
        byte[] buf = new byte[1024] ;
        while((len = in.read(buf))!=-1){
            out.write(buf,0,len);
            out.flush();
        }

        in.close();
        out.close();

输出随机图片(验证码)

BufferImage 类,在内存创建图片(明日更新)


不要缓存

注意:在输出验证码的时候,需要告诉浏览器,不要缓存验证码图片 ;,我们需要把三个头都写上,为了所有浏览器都能不缓存;

  • 代码控制

response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");

  • <mate>标签控制

当然我们还可以使用标签来模拟响应头,控制浏览器的行为 ;

  1. <meta http-equiv="Expires" content="0">
  2. <meta http-equiv="Cache-Control", content="no-cache">
  3. <meta http-equiv="Progma" content="no-cache">

图片的src地址

图片的 src 地址,跟在浏览器中访问的地址是一样的,但是不需要写明端口 ;
验证码: <img src="/javaWeb/suiji"><br>


点击图片就换一张图

需要使用到JavaScript的知识;so easy
   <script type="text/javascript">
        function changeImg(img){
//      点击图片,再次将图片的src赋值为当前的src
//      就是重新去访问,图片的地址,达到换一张图片的目的
//      但是,我们需要在这个地址后面,加上一些东西
//      否则,点击图片,不会去重新访问服务器的
//      直接拿之前的缓存,这里的缓存跟前面的缓存,不是一回事
            img.src = img.src + "?" + new Date().getDate() ;
        }
    </script>

让鼠标在图片上变成小手样式

style="cursor: hand" 在标签属性里面写上 ;


控制浏览器缓存

向浏览器发送一个响应头,字段为:expires ;后面的参数为 当前时间+要缓存的时间千万不要直接写缓存时间,这个时间是从1970 开始计算的

获取当前系统的时间的方法:System.currentTimeMills()


控制浏览器定时刷新

发送头:refresh ,参数是 时间 ;两个都是字符串;

  • 定时刷新

    每3秒刷新一次

response.setHeader("refresh", "3");
  • 可以完成指定浏览器访问某地址 ;

    可在第二个参数里面添加url地址。这样,时间到,就会跳转到那个地址

response.setHeader("refresh", "3;url='https://www.baidu.com'");

实现请求重定向

实现方式: sendRedirect(地址)

       response.sendRedirect("/javaWeb/1.html");

实现原理:利用 302状态码和localtion头

方法的出现,是为了简化代码 ;

重定向能不用,就不用,它请求两次,会加重服务器压力


response细节

getOutputStreamgetWriter 方法分别用于得到 输出二进制数据、输出文本数据的servletOutputStreamPrintWriter 对象 ;

  • 方法互斥

getOutputStreamgetWriter 这两个方法相互排斥,调用了其中的任何一个方法后,就不能再调用另一个方法

  • response中数据——> http正文

Servlet程序向ServletOutputStream或者PrintWriter对象中写入的数据被Servlet引擎从response里面获取,Servlet引擎将这些数据当做响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端

  • 关闭close

Servlet的service方法结束后,Servlet引擎将检查getWriter或者getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,servlet引擎将调用close方法关闭输出流对象

原文地址:https://www.cnblogs.com/young-youth/p/11665728.html