zoukankan      html  css  js  c++  java
  • JavaWeb学习笔记(四)—— response

    一、response概述

      response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作

    二、response的运行流程

    三、response的功能

      通过抓包工具抓取Http响应

      

      因为response代表响应,所以我们可以通过该对象分别设置Http响应的响应行,响应头和响应体。

    3.1 设置响应行

      setStatus(int sc)

    • 200表示成功
    • 302表示重定向
    • 404表示客户端错(访问的资源不存在)
    • 500表示服务器端错

    3.2 设置响应头

      可以使用response对象的setHeader()方法来设置响应头!使用该方法设置的响应头最终会发送给客户端浏览器!

    • 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.baidu.cn"):5秒后自动跳转到百度主页。

      禁用浏览器缓存:
      response.setHeader("Cache-Control", "no-cache");
      response.setHeader("pragma", "no-cache");
      response.setDateHeader("expires", -1);

    3.3 设置响应体

    【两个流】

      response是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象:

    • PrintWriter out = response.getWriter():获取字符流;
    • ServletOutputStream out = response.getOutputStream():获取字节流;

       当然,如果响应正文内容为字符,那么使用response.getWriter(),如果响应内容是字节,例如下载时,那么可以使用response.getOutputStream()。

      注意,在一个请求中,不能同时使用这两个流!也就是说,要么你使用repsonse.getWriter(),要么使用response.getOutputStream(),但不能同时使用这两个流。不然会抛出IllegalStateException异常。

    【解决中文乱码问题】

      

      在使用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.setContentType("text/html;charset=UTF-8")必须在getWriter()方法之前调用!

    3.4 重定向

      

      重定向是服务器通知浏览器去访问另一个地址,即再发出另一个请求。

    【重定向的实现方式】

    /**
     * 重定向:
     * 1.设置Location
     * 2.发送302状态码
     */
    // response.setHeader("Location", "/day01/CServlet");
    // 快捷的重定向方法
    response.sendRedirect("/day01/CServlet");

    【重定向的特点】

    • 重定向是两次请求(访问服务器两次或多次);
    • 重定向的URL可以是其他应用,不局限于当前应用;
    • 地址栏的地址发生变化
    • 重定向的响应头为302,并且必须要有Location响应头;

      注意:重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常;

    四、文件下载

      下载就是向客户端响应字节数据。原来我们响应的都是html的字符数据,下载就是把一个文件变成字节数组,使用response.getOutputStream()来各应给浏览器。

    4.1 下载的要求

    【两个头】

    • Content-Type:你传递给客户端的文件是什么MIME类型,例如:image/pjpeg(通过文件名称调用ServletContext的getMimeType()方法,得到MIME类型!)
    • Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开!设置attachment;filename=xxx,表示浏览器弹出下载框,在filename=后面跟随的是显示在下载框中的文件名称!

    【一个流】

      要下载的文件数据。FileInputStream input = new FileInputStream(filename)

    4.2 下载实例

      download.jsp:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <a href="/WEB14/download/a.jpg">a.jpg</a><br>
        <a href="/WEB14/downLoadServlet2?filename=美女.jpg">美女.jpg</a><br>
    </body>
    </html>

      DownloadServlet:

    public class DownloadServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            /**
             * 两个头、一个流
             * 1.Content-Type
             * 2.Content-Disposition
             * 3.流:下载文件的数据
             */
            // 获取要下载的文件名称
            String filename = request.getParameter("filename"); // ??.jpg
            // 为了使下载框中显示中文名称时不乱码
            filename = new String(filename.getBytes("ISO8859-1"), "UTF-8"); //美女.jpg
    
            // 获取请求头中的User-Agent
            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(this.getServletContext().getMimeType(filename));
            // 告诉客户端该文件不是直接解析,而是以附件的形式打开(下载)
            response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoder);
            // 获取文件的绝对路径
            String realPath = this.getServletContext().getRealPath("download/" + filename);
            // 获取该文件的输入流
            InputStream inputStream = new FileInputStream(realPath);
            // 获得输出流——通过response获得的输出流,用于向客户端写内容
            ServletOutputStream outputStream = response.getOutputStream();
            // 文件拷贝的模板代码
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
            }
    
            inputStream.close();
            // outputStream.close();  response获得流不用手动关闭,会自动关闭
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }
  • 相关阅读:
    315,谁来保护手游开发者的利益
    微信小程序之提高应用速度小技巧
    Python-爬虫-Beautifulsoup解析
    Python-爬虫-requests
    Python-form表单标签
    设计模式のTemplatePattern(模板模式)----行为模式
    链接
    python入门007
    007作业
    005作业
  • 原文地址:https://www.cnblogs.com/yft-javaNotes/p/10467014.html
Copyright © 2011-2022 走看看