Java篇-HttpServletResponse

一 : 简介

HttpServletResponse : 当创建Servlet时会覆盖service()方法,或doGet()doPost这些方法中都会有requestresponse参数,分别代表请求和响应.
doGet()与doPost方法的response类型是HttpServletResponse而service方法的类型是ServletResponse,HttpServletResponseServletResponse的子接口,功能更加强大.

二 : HttpServletResponse过程

其中tomcat内核引擎会把请求信息封装成resquest对象,并且创建一个response对象,但是这个response对象是空的,没有东西,我们将写好后的内容暂时放入response缓冲区,再由tomcat去该缓冲区获取设置的内容,最后tomcat从response中获取设置内容组装一个http响应,由页面进行解析显示.

图解

三 : HttpServletResponse方法

  • response设置响应行
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //手动设置http响应行状态码
        response.setStatus(302);
    }
  • response设置响应头
`add`表示添加, `set`表示设置
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //设置响应头
        Date date = new Date(0);
        response.setHeader("name", "xuefu");
        response.addIntHeader("age", 18);
        response.addDateHeader("birthday",date.getTime());
        response.addHeader("name", "xueli");
        response.setIntHeader("age", 20);
    }   

设置定时刷新的头

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

重定向头

    //没有响应,告知客户端重定向到servlet2
    //1设置状态码
    response.setStatus(302);
    //2.设置响应头Location
    response.setHeader("Location", "/WEBpro/servlet2");

封装成一个重定向的方法

response.sendRedirect("/WEBpro/servlet2");

重定向是多次请求,且浏览器地址栏会发生变化

图解重定向


重定向
  • response设置响应体
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();
        writer.write("你真美");
    }

四 : 中文乱码的原因及解决

原因 :
response缓冲区的默认编码是iso8859-1,此码表中没有中文,需要通过response的setCharacterEncoding(String charset)设置response的编码.
此时页面还是不能显示成中文,因为浏览器的默认编码是本地系统的编码,有可能默认编码是GBK,需要手动修改浏览器的编码为UTF-8,当然还可以在代码中指定浏览器解析页面的方式,通过response的setContentType(String type)方法指定页面解析时编码是UTF-8.
setContentType(String type)不仅能指定浏览器解析页面时的编码,同时也内含setCharacterEncoding(String charset)功能,所以在实际开发中只写setContentType(String type)就好.

解决

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        //设置response查询码表
//      response.setCharacterEncoding("UTF-8");
        
        //通过头Content-Type告知客户端使用何种码表,写这个上面的可以不用写
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        
        //封装的,等价于上面
//      response.setContentType("text/html;charset=UTF-8");
        
        PrintWriter writer = response.getWriter();
        writer.write("百华真美");
    }

五 : 文件下载

  • 使用ServletOutputStream完成服务器到客户端的文件拷贝
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //使用response获得字节输出流
        ServletOutputStream out = response.getOutputStream();
        
        //获得服务器上图片
    
        ServletContext context = getServletContext();
        String path = context.getRealPath("timg.jpeg");
        InputStream in = new FileInputStream(path);
        int len = 0;
        byte[] buffer = new byte[1024];
        
        while((len = in.read(buffer)) != -1) {
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }

在下载过程中,我们需要告知浏览器文件的类型可文件的打开方式比如,要告诉浏览器这就是一个附件,不需要解析显示.还有在下载中文文件会出现中文乱码或者不显示文件名的情况,原因是不同浏览器对下载文件的编码方式不同,还要解决浏览器兼容问题.

        //获取要下载的文件名称
        String filename = request.getParameter("filename");
        
        //解决中文参数乱码
        filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");
        
        //获得请求头
        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");             
                }
        //获取文件类型,客户端通过MIME类型区分
        response.setContentType(getServletContext().getMimeType(filename));
        
        //告诉客户端不是直接解析,而是以附件的形式打开(下载) filename="+filename 客户端默认对名字进行解码
        response.setHeader("content-DisPosition", "attachement;filename="+filenameEncoder);
        
        //获取绝对路径
        String path = getServletContext().getRealPath("download/"+filename);
    
        //获取文件的输入流
        InputStream in = new FileInputStream(path);
        
        //获得输出流
        ServletOutputStream out = response.getOutputStream();
        
        //文件拷贝
        int len = 0;
        byte[] buffer = new byte[1024];
        while((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        in.close();
        out.close();//这个会其实会自动关闭,写不写都行
    }

其中response获得的流不需要手动关闭,Tomcat容器会帮助我们关闭
getWritergetOutPutStream不能同时调用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,819评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 32,342评论 18 399
  • 六 下了地铁他带我去了宾馆,到了宾馆我看到他腰间垮着我和儿子共同给他从京东精选的...
    做一个无愧于心的人阅读 1,742评论 0 1
  • The Temple of Heaven
    小筐81阅读 1,229评论 0 0
  • 不知不觉,2017年已经过去一大半,而我加入猫叔的社群已经7个多月了,最近复盘了这半个年多的成长,发现跟我进群的时...
    碎碎念的又又阅读 2,701评论 0 0

友情链接更多精彩内容