Servlet学习3 -- Response对象和Servlet

2022-04-11  本文已影响0人  张氏小毛驴

一.Response对象

  1. Response的作用

    Response对象是用来设置HTTP响应消息的,包括了响应行,响应头,响应体。

  2. Response继承体系

    ServletResponse -- 接口
    | 继承
    HttpServletResponse -- 接口
    | 实现
    org.apache.catalina.connector.ResponseFacade 类(tomcat)

  3. Response的功能API

    • 设置响应行(格式:HTTP/1.1 200 ok)

      setStatus(int sc):设置状态码

    • 设置响应头

      setHeader(String name, String value)

    • 设置响应体

      设置响应体有两种方式:

      1. PrintWriter getWriter():字符输出流

      2. ServletOutputStream getOutputStream():字节输出流

        ServletOutputStream是OutputStream的子类,可以当做OutputStream对待,输出字节流,当需要输出二进制格式的响应时需要使用getOutputStream()。

      注意:两个方法getWriter()和getOutputStream()都可以发送响应消息体,但是两个不能同时使用,会出现异常

    • 重定向功能

      重定向是一种资源跳转的方式。

      方法为:void sendRedirect(String path)

      重定向特点:

      1. 重定向,浏览器的地址栏会变化。
      2. 重定向可以访问其他服务器的站点资源。
      3. 重定向是两次请求,无法使用request对象共享数据。

      重定向和转发的区别:

      1. 重定向是response发出的响应,转发是request调用
      2. 因为重定向是response发出的响应,浏览器拿到后会再去请求,所以重定向是两次请求,而转发是服务器内部的,对于浏览器来说并没有再次请求,只有一次请求。
      3. 重定向是response返回给浏览器的,浏览器再去请求,因此可能下一次请求是其他服务器的资源(比如www.baidu.com),因此地址栏是会变化的,而转发是服务器内部,浏览器并不知道,所以地址栏不会变化,当然也无法访问其他服务器的资源了,只能访问当前服务器下的资源。
  4. 关于路径的书写问题

    使用规则:判断路径是给谁使用

    给服务器使用:不需要加虚拟目录(比如转发)

    给浏览器使用:需要加虚拟目录(比如重定向),虚拟目录最好使用方法获取,request.getContextPath()

  5. response乱码问题

    原因:response缓冲区的默认编码是ISO8859-1,这个码表是没有中文的,所以需要手动更改response的编码方式。

    解决方式:在获取响应输出流之前设置编码:response.setContentType("text/html;charset=utf-8")

二.ServletContext对象

  1. 什么是ServletContext对象

    ServletContext对象在Tomcat启动的时候就会创建,代表着整个web应用,可以和程序的容器(服务器)通信。

  2. ServletContext对象作用

    • ServletContext代表着整个Web应用,那么所有的Servlet都共享同一个ServletContext对象,因此Servlet之间可以通过ServletContext对象实现通信
    • ServletContext可以获取整个web应用的配置信息
    • 利用ServletContext能够读取web应用的资源文件
  3. ServletContext对象获取

    • 通过request对象获取

      request.getServletContext()

    • 通过HttpServlet获取

      this.getServletContext()

  4. ServletContext对象功能

    1. 获取MIME类型

      MIME类型:是在互联网通信过程中定义的一种文件数据类型,格式为:大类型/小类型,比如text/html,image/jpg等

      方法:String getMimeType(String file)

    2. 域对象(共享数据)

      • setAttribute(String name, Object value)
      • getAttribute(String name)
      • removeAttribute(String name)

      注意:ServletContext的范围是对所有的Servlet

    3. 获取资源文件的路径

      以前获取文件路径,只需要指定文件的绝对路径或相对路径即可,但在web应用中不可行,因为web应用是部署在服务器上的,对于路径的获取有以下几种情况:

      1. 如果资源文件在src下某个包中,则路径该是:/WBE-INF/classes/包名/文件名
      2. 如果资源文件在Web根目录下,则路径是:/文件名
      3. 如果资源文件在WEB-INF目录下:则路径是:/WEB-INF/文件名

      获取资源文件路径的方法有两种:

      • getResourceAsStream(String path):获取的是相对路径
      • getRealPath(String path):获取的是绝对路径

      示例:

      假设有如下文件:

      src文件夹下包com.zzy.web有一个a.txt

      WEB-INF文件夹下有一个b.txt

      WEB-INF文件夹下的lib文件夹有一个c.txt

      WEB-INF根目录下有一个d.txt

      ServletContext-path.png
      @WebServlet("/PathServlet")
      public class PathServlet extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 1. 获取a.txt
              InputStream aInput = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/zzy/web/a.txt");
              System.out.println(aInput);
      
              String aPath = this.getServletContext().getRealPath("/WEB-INF/classes/com/zzy/web/a.txt");
              System.out.println(aPath);
              System.out.println("-----------------");
              // 2. 获取b.txt
              InputStream bInput = this.getServletContext().getResourceAsStream("/WEB-INF/b.txt");
              System.out.println(bInput);
      
              String bPath = this.getServletContext().getRealPath("/WEB-INF/b.txt");
              System.out.println(bPath);
              System.out.println("-----------------");
              // 3. 获取c.txt
              InputStream cInput = this.getServletContext().getResourceAsStream("/WEB-INF/lib/c.txt");
              System.out.println(cInput);
      
              String cPath = this.getServletContext().getRealPath("/WEB-INF/lib/c.txt");
              System.out.println(cPath);
              System.out.println("-----------------");
              // 4. 获取d.txt
              InputStream dInput = this.getServletContext().getResourceAsStream("/d.txt");
              System.out.println(dInput);
      
              String dPath = this.getServletContext().getRealPath("/d.txt");
              System.out.println(dPath);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              doPost(request, response);
          }
      }
      
      

      输出如下:

      java.io.ByteArrayInputStream@623dd620
      F:\IDEATest\JavaWebTest\out\artifacts\BlogTest_war_exploded\WEB-INF\classes\com\zzy\web\a.txt
      -----------------
      null
      F:\IDEATest\JavaWebTest\out\artifacts\BlogTest_war_exploded\WEB-INF\b.txt
      -----------------
      java.io.ByteArrayInputStream@76d00c1b
      F:\IDEATest\JavaWebTest\out\artifacts\BlogTest_war_exploded\WEB-INF\lib\c.txt
      -----------------
      java.io.ByteArrayInputStream@5315f6de
      F:\IDEATest\JavaWebTest\out\artifacts\BlogTest_war_exploded\d.txt
      

      注意:

      ServletContext.getResourceAsStream("/WEB-INF/b.txt"),实测找不到文件,返回了null,但用getRealPath()可以获取到绝对路径。所以在这个目录下的文件还是用getRealPath()去获取吧。

      这个问题还不清楚是为啥,知道了再补上。

上一篇下一篇

猜你喜欢

热点阅读