我对于response(响应对象的理解)

response

response响应过程
    在去发送一个请求时, 会找到tomcat引擎
    引擎会找到对应的web应用
        并且会创建request对象和response对象
    找到应用后, 会执行应用的web.xml再去根据url-patten的内容创建Servlet对象
    并且会调用Servlet对象的service方法,并且把创建的request对象和response对象传入到方法当中
    拿到response对象后,  自己可以往响应当中写入一些自己给客户端的内容
        通过response.getwrite().wirte("写的内容")方法进行写入
    写的内容,是存到一个response缓冲区当中
    当方法执行结束之后, tomcat就会从response缓冲区当中取出数据
        取出你的数据同时,它自己还会自动的往里面添加一些服务器相关的信息进去
        所以响应给浏览器时, 可以看到除了自己写的内容, 还会有一些服务器相关的信息
学习响应
    通过response设置响应行,响应头 ,响应体

设置响应行
    response.setState(Int code)

设置响应头 
    add
        add代表添加新的内容
        addHeader(String name,String value)
        addIntHeader(String name,int value)
        addDateHeader(String name,date)
        示例
            
                
    set
        set代表设置,已经存在的内容
        setHeader(String name,String value)
        setIntHeader(String name,int value)
        setDateHeader(String name,Date value)
        添加两个相同的name
            
    重定向
        什么是重定向
            到服务器当中去找servlet1
            servlet1当中没有这个资源,告诉你去找servlet2
            再去发送一个请求到servlet2
        状态码
            302
        特点
            要访问两次服务器
                第一次访问是人为的去访问
                第二次是自动的访问
            浏览器地址栏已经发生变化
        设置重定向
            设置响应码
            设置响应头
                
        封装的重写向
            每次都要写状态码,和location比较麻烦
            就给封装了一个方法
                response.sendRedirect("/bei/servlet2")
                    
        定时刷新重定向
            response.setHeader("refresh","5;url=http://www.baidu.com")
                5代表5秒
                url的值为5秒后要去跳转的地址
设置响应体
    1.通过write方法来写
        response.getwrite().wirte(“要写的内容”)
        默认情况下写的中文内容会乱码
            把写的内容存到缓存区中使用的是ISO8859
            ISO8859不支持中文,所以会乱码
        在存之前设置可以设置存放的编码
            response.setCharacterEncoding("UTF-8")
        告知浏览器使用的是utf-8编码
            response.setHeader("Content-Type", "text/html;charset=UTF-8");
        示例
            
        上面代码只需要写第二句就行, tom看到设置了为utf-8的编码,它在存在的时候也会使用utf-8的编码
        使用封装写法
            response.setContentType("text/html;charset=UTF-8");
    2.通过OutPutStream来写
        FileInputSteam
            read方法读取一个字节
                
            read(byte[] b)
                一次读取多个字节,并存放到数组b中
                上面是一次一滴一滴给你,这种是一次装一水桶再给你
                    
            读取全部的数据
                
        FileOutputSteam
            write()
                一次性写一个字符
            write(buffer)
                一个性写多个字符
            write(buffer,0,len)
                一次性写指定个数的字符
    response注意点
        getWrite()和getOutputSteam不能同时调用                    

下载功能
    需求
        把服务器当中的文件直接下载到电脑当中
    下载文件
        1.直接使用a标签来去下载
            有些内容会浏览器自动解析
            浏览器不能解析的文件才会被下载
                
        2.通过发送Servlet请求来去下载
            通过发送一个Servlet请求,把文件名发送给服务器
            发送给服务器后,接收到文件名参数,获取文件的绝对地址
            通过流的形式来去写到浏览器
            还得要告诉文件是什么类型
                浏览器是以MIME的类型来识别类型
                    this.getServletContext().getMimeType(“文件名称”)
                设置响应的类型
                    res.setContentType("MIME类型")
            设置响应头,告诉浏览器不要去解析,是以附件的形式打开,
                res.setHeader("Content-Dsiposition","attachment;filename="+文件名)
            步骤
                1.接收文件名参数
                2.获取mime类型
                3.设置浏览器响应类型
                4.告诉浏览器以附件形式下载
                5.获取文件的绝对路径
                6.读取文件流
                7.获取输出流
                8.把内容写出到输出流
            示例代码
                
                                //1.接收文件名参数
        String filename = request.getParameter("filename");
        String mime = this.getServletContext().getMimeType(filename);
        response.setContentType(mime);
        response.setHeader("Content-Disposition", "attachment;filename="+filename);
        //2.获取文件的绝对路径
        String path = this.getServletContext().getRealPath("download/"+filename);
        System.out.println(path);
        //3.读取文件流
        FileInputStream in = new FileInputStream(path);
        //4.获取输出流
        ServletOutputStream out = response.getOutputStream();
        //5.把内容写出到输出流
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
    解决中文名称乱码问题
        获取中文参数报错问题
            高版本tomcat中的新特性:就是严格按照 RFC 3986规范进行访问解析,而 RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])
            .../conf/catalina.properties中,找到最后注释掉的一行 #tomcat.util.http.parser.HttpParser.requestTargetAllow=|  ,改成tomcat.util.http.parser.HttpParser.requestTargetAllow=|{},表示把{}放行
        1.把获取的字符串参数的字节码获取,再重新使用utf-8编码
        2.在设置以附件形式打开时, 不同的浏览器会对默认的名字进行解码
        所以根据不同的浏览器,要对名称进行编码之后,再放入文件名
        对文件名进行编码
            不同的浏览器编码不一样
            要先获取agent,取出浏览器的类型
            根据不同的浏览器类型进行编码
        步骤
            1.接收文件名称
            2.获取mimeType
            3.设置浏览器响应类型
            4.先对传入的参数转成二进制流,再使用UTF-8进行编码
            5.获取浏览器的信息
            6.判断是哪一种浏览器,根据不同的浏览器获取一个编码的文件名
            7.设置以附件形式下载,传的名称是编码过的名称 
            8.获取文件的绝对路径
            9.读取文件流
            10.获取输出流
            11.把文件写到响应当中
            示例代码
                
                            // 获取客户端信息
        String agent = request.getHeader("User-Agent");
        // 定义一个变量记录编码之后的名字
        String filenameEncoder = "";
        if (agent.contains("MSIE")) {
            // IE编码
            filenameEncoder = URLEncoder.encode(filename, "utf-8");
            filenameEncoder = filenameEncoder.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐编码
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filenameEncoder = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 浏览器编码
            filenameEncoder = URLEncoder.encode(filename, "utf-8");
        }


            
        

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值