(JavaWeb)servletContext、Response、Request知识点总结

1. servletContext 对象

1.1 定义

在Tomcat服务器中的web的项目 也叫做WEB应用程序。在java中 万物皆对象,那么,应用程序也是对象。

在Java Web开发中,使用ServletContext对象表示WEB应用程序。
在这里插入图片描述

  • 说明:
    1. 在一个WEB应用程序中,只能存在一个ServletContext对象。
    2. 每个应用程序,都有它自己所对应的一个ServletContext对象。
    3. 在服务器启动的时候,为每个web应用程序创建一个单独的ServletContext对象。
    4. ServletContext是接口, 此接口的实现类是tomcat引擎提供

1.2 ServletContext对象的作用

  • 获取WEB应用程序的初始化参数
  • 获取WEB应用程序下任意资源的绝对路径
  • ServletContext作为域对象,存储数据

1.2.1 获取WEB应用程序的初始化参数:

因为一个web应用程序只有一个ServletContext对象,所以这个对象对整个应用程序的相关内容都是了解的

  • web.xml 配置WEB应用程序的初始化参数
<!-- 配置的是WEB程序的初始化参数-->
<context-param>
    <param-name>bit</param-name>
    <param-value>java</param-value>
</context-param>
  • API操作
方法返回值描述
getInitParameter(String name)String获取web应用程序的初始化参数
  • 代码演示:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     * 获取ServletContext对象
     * 父类的方法
     * org.apache.catalina.core.ApplicationContextFacade实现接口ServletContext
     */
    ServletContext context = getServletContext();
    System.out.println(context);
    //context对象,获取配置文件中的初始化参数
    String value = context.getInitParameter("bit");
    System.out.println(value);
}

1.2.2 获取WEB应用程序下任意资源的绝对路径

方法返回值描述
getRealPath(String path)String接收一个资源的相对路径,返回真实路径(完整路径)的字符串
  • 获取web目录下的a.txt绝对路径
  • 获取web目下WEB-INF目录下的b.txt绝对路径
  • 获取src目录下的c.txt绝对路径
  • 获取web02 module下的d.txt绝对路径,获取不到

在这里插入图片描述

代码演示:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取servletContext对象
    ServletContext servletContext = super.getServletContext();
    //获取web目录下的a.txt绝对路径
    String apath = servletContext.getRealPath("a.txt");
    System.out.println("apath = " + apath);
    //获取web目录下WEB-INF目录下的b.txt绝对路径
    String bpath = servletContext.getRealPath("WEB-INF/b.txt");
    System.out.println("bpath = " + bpath);
    //获取src目录下的c.txt绝对路径
    String cpath = servletContext.getRealPath("WEB-INF/classes/c.txt");
    System.out.println("cpath = " + cpath);
}

1.1.3 ServletContext作为域对象

  • ServletContext是在服务器启动的时候为每个web项目 单独创建一个ServletContext对象。当web项目从服务器中移除,或者是关闭服务器的时候ServletContext对象会被销毁。向ServletContext中保存的数据一直存在(当服务器关闭的时候ServletContext对象被销毁,然后里面数据才会失效)。

  • ServletContext作用范围:整个web应用。

方法返回值描述
setAttribute(String key, Object value)void向域对象存储数据
getAttribute(String key)Object取出域对象数据
removeAttribute(String key)void移除域对象数据

代码演示:

第一个Servlet:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取servletcontext对象
    ServletContext context = super.getServletContext();
    //存储数据 heima=java
    context.setAttribute("bit","java");
    //读取数据 heima的值
    Object value = context.getAttribute("bit");
    System.out.println("Context4Servlet bit= " + value);
}

第二个Servlet:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取ServletContext域对象
    ServletContext context = super.getServletContext();
    //获取域对象中 指定键的值
    Object value = context.getAttribute("bit");
    System.out.println("Context5Servlet bit= " + value);
}

2. Response对象

2.1 Response对象概述

方向: 服务器 -> 浏览器

负责对浏览器进行响应的对象

什么是响应: 服务器接收到请求需要进行处理,将处理以后的结果显示回浏览器端(将这个过程称为是响应Response)。

  • 查看Servlet中的service方 法得知, Servlet中使用的ServletResponse接口, 而我们使用的是ServletResponse的子接口HttpServletResponse, 它继承自ServletResponse, 是与HTTP协议相关的Response响应对象
  • 我们使用的子接口HttpServletResponse, 此接口对象由Tomcat引擎提供
  • 可以实现对客户端的响应, 响应内容包括: 响应行,响应头,响应体
  • 在这里插入图片描述

2.2 Response设置响应行

方法返回值描述
setStatus(int sc)void设置响应的状态码
  • 设置响应的状态码
    • 200 正确
    • 302 重定向
    • 304 查找本地缓存
    • 404 请求资源不存在
    • 500 服务器内部错误
response.setStatus(500);

2.3 Response设置响应头

HTTP协议的响应头,数据格式键值对 k:v

包含指导性信息,指导客户端

方法返回值描述
addHeader(String key,String value)void添加响应头,值为String类型
addIntHeader(String key,int value)void添加响应头,值为int类型
addDateHeader(String key,long l)void添加响应头,值为日期类型
setHeader(String key,String value)void更改响应头,值为String类型
setIntHeader(String key,int value)void更改响应头,值为int类型
setDateHeader(String key,long l)void更改响应头,值为日期类型
  • add开头的方法:针对一个key对应多个value的情况。

比如已有一个响应头 bit:java
然后执行 addHeader(“bit”,”java2222”);
最终得到响应头的结果:bit:java,java2222

  • set开头的方法:针对一个key对应一个value的情况。

    比如已有一个响应头 bit:java
    然后执行 setHeader(“bit”,”java2222”);
    最终得到响应头的结果:bit:java2222

演示:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     * response对象设置响应头
     */
    response.addHeader("bit","java");

    /*
     * addHeader() 添加,实现一个键对应多个值
     * setHeader() 设置,原来的键覆盖
     */
    response.setHeader("bit","java2222");
}

2.4 重定向

在这里插入图片描述
浏览器进行重新的定向:

  • 设置302状态码: setStatus(302)
  • 设置重定向资源的地址: setHeader(“location”,“资源”)

通过HttpServletResponse对象中的以下方法实现重定向

方法返回值描述
sendRedirect(String location)void重定向

2.4.1 重定向的代码实现

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/demo07")
public class ServletDemo07 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 解决服务器给浏览器的数据中文乱码问题
        response.setContentType("text/html;charset=utf-8");

        System.out.println("77777777777777777777777");

        // 需求: 演示重定向: 访问 demo07 跳转到 demo08
        // 合并式
        response.sendRedirect("/web0201/demo08");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

2.5 Response设置响应体

HTTP的响应体,就是页面的正文部分

2.5.1 字符流向浏览器写数据

方法返回值描述
write()PrintWriter使用字符串数据,没有差别, 输出是整数,查询编码表
print()PrintWriter无论是什么,原样打印
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     * response对象方法getWriter()
     * 打印流的响应体
     * write() 使用字符串数据,没有差别, 输出是整数,查询编码表
     * print() 无论是什么,原样打印
     */
     PrintWriter pw =  response.getWriter();
     pw.write(100);
     pw.print(100);
}

2.5.2 字符流的中文乱码问题

产生乱码原因: 编码和解码不一致

  • 注意:在Servlet中编写以下代码,向页面输出中文会产生乱码
response.getWriter().print("中文");
  • 原因:
    • 字符流是有缓冲区的,response获得字符流,response设计默认的缓冲区编码是ISO-8859-1。这个字符集不支持中文的。
  • 解决:
    • 设置response获得字符流缓冲区的编码 与 设置浏览器默认打开时候采用的字符集一致即可。
方法放回值描述
setHeader(“Content-Type”, “text/html;charset=UTF-8”)void设置浏览器打开页面时采用的字符集
setContextType(String type)void设置浏览器打开页面时采用的字符集
// 设置浏览器默认打开的时候采用的字符集:
// response.setHeader("Content-Type", "text/html;charset=UTF-8");
// 简化代码
response.setContentType("text/html;charset=UTF-8");
// 输出中文汉字
response.getWriter().println("中文");

2.5.3 字节流向浏览器写数据

方法返回值描述
getOutputStream()OutputStream返回字节输出流OutputStream,响应非文本类型的数据
  • 举例:用字节输出流向客户端浏览器输出图片
package response;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;

/**
 *  字节输出流:全能
 *  response方法  getOutputStream()返回字节输出流
 */
@WebServlet(urlPatterns = "/body")
public class Body2Servlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletOutputStream outputStream = response.getOutputStream();
        // 字节流 ,写数据,字节或者字节数组

        // 获取图片2.png的绝对路径,先要获取ServletContext对象
        ServletContext context = getServletContext();
        String path = context.getRealPath("WEB-INF/2.png");
        //字节输入流,读取图片
        FileInputStream fis = new FileInputStream(path);
        byte[] bytes = new byte[1024];
        int len = 0;
        while ((len = fis.read(bytes) )!= -1){
            outputStream.write(bytes,0,len);
        }
        fis.close();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

3. Request对象

3.1 Request对象概述

方向: 浏览器 -> 服务器

负责获取客户端的请求数据

request对象是从客户端向服务器发出请求,包括用户提交的信息以及客户端的一些信息。客户端可通过HTML表单或在网页地址后面提供参数的方法提交数据,然后服务器通过request对象的相关方法来获取这些数据。

  • 查看Servlet中的service方法得知, Servlet中使用的ServletRequest接口, 而我们使用的是ServletRequest的子接口HttpServletRequest, 它继承自ServletRequest, 是与HTTP协议相关的Request请求对象

  • 我们使用的子接口HttpServletRequest, 此接口对象由Tomcat引擎提供

  • 可以实现客户端向服务器发出请求, 请求内容包括: 请求行,请求头,请求体
    在这里插入图片描述

3.2 Request对象获取请求行

  • API
方法返回值描述
getMethod()String获取提交的方式 (GET,POST)
getRequestURI()String获取请求的参数,请求服务器路径
getRequestURL()StringBuffer获取请求的参数,请求服务器路径
getQueryString()String获取请求行 问号后面的参数 (GET)
getContextPath()String获取WEB应用名称
  • 代码演示
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //request对象方法 getMethod()获取客户端的请求方式
    String method = request.getMethod();
    System.out.println(method);
    //方法 String getRequestURI() 获取请求服务器路径
    //方法 StringBuffer getRequestURL() 获取请求服务器路径
    String URI = request.getRequestURI();
    StringBuffer URL = request.getRequestURL();
    System.out.println("URI=="+URI);//   /web04/line
    System.out.println("URL=="+URL);//  http://localhost:8080/web04/line

    //方法 String getQueryString()获取请求行,?后面的所有参数
    String query = request.getQueryString();
    System.out.println(query);//user=tom&pass=123&

    //获取WEB应用名称  String getContextPath()
    String path = request.getContextPath();
    System.out.println(path);//   /web04
    //获取WEB应用名称, 结合重定向使用
    //response.sendRedirect(request.getContextPath()+"/ddd");
}

3.3 Request对象获取请求头

​ 请求头数据格式键值对, k:v

​ 指导性信息,指导服务器

方法返回值描述
getHeader(String name)String获得一个key对应一个value的请求头
getHeaderNames()Enumeration获取所有的请求头的键
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     * Enumeration getHeaderNames() 获取所有的请求头的键
     * 返回值Enumeration接口 (向量枚举)
     * 集合:1.0-1.1 Enumeration    集合1.2  迭代器
     * Iterator迭代器接口:  hasNext()   next()
     * Enumeration接口:  hasMoreElement()  nextElement()
     */
    Enumeration<String> enums  = request.getHeaderNames();
    while (enums.hasMoreElements()){
         key = enums.nextElement();
         String value = request.getHeader(key);
        System.out.println(key+"=="+value);
    }
}

3.4 Request获取请求参数

重点 重点 重点

方法返回值描述
getParameter(表单中的name值)String获得提交的参数(一个name对应一个value)
getParameterValues(表单中的name值)String[]获得提交的参数(一个name对应多个value)
getParameterMap()Map<String,String[]>获得提交的参数,将提交的参数名称和对应值存入到一个Map集合中
  • 示例代码
  • 网页代码
<body>
    <form action="/web02/param" method="post">
        用户名:<input type="text" name="username"><br/>
        密 码:<input type="password" name="password"><br/>
        爱 好:<input type="checkbox" name="hobby" value="Basketball">篮球
                <input type="checkbox" name="hobby" value="football">足球
                <input type="checkbox" name="hobby" value="pingpang">乒乒球 <br/>
        <input type="submit">
    </form>
</body>
@WebServlet(urlPatterns = "/param")
public class ParamServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获得提交的参数(一个name对应一个value)
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username +" == " +password);
        //获得提交的参数(一个name对应多个value)
        String[] hobbies = request.getParameterValues("hobby");
        System.out.println("hobbies = " + Arrays.toString(hobbies));
        //获得提交的参数,将提交的参数名称和对应值存入到一个Map集合中
        Map<String, String[]> map = request.getParameterMap();
        for(String key : map.keySet()){
            String[] values = map.get(key);
            System.out.println(key + " == " + Arrays.toString(values));
        }
    }

3.5 Request对象接收表单请求参数的中文乱码处理

3.5.1 POST方式接收中文

  • 产生乱码的原因:
    • post方式提交的数据是在请求体中,request对象接收到数据之后,放入request的缓冲区中。缓冲区就有编码(默认ISO-8859-1:不支持中文).
  • 解决方案:
    • 将request的缓冲区的编码修改了即可。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //将request的缓冲区的编码修改
    request.setCharacterEncoding("utf-8");

    //获取请求参数
    String user = request.getParameter("user");
    System.out.println("user = " + user);
}

3.5.2 GET方式接收中文(了解)

Tomcat8.5版本之后, Tomcat自动处理了get请求的中文乱码问题

但在Tomcat8.5之前的版本中, get请求的中文乱码需要自行处理

  • 产生乱码原因:
    • get方式提交的数据在请求行的url后面,在地址栏上其实就已经进行了一次URL的编码了。
  • 解决方案:
    • 将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     get方式提交的数据在 请求行中
     Tomcat8.5之后, Tomcat自动处理了get请求的中文乱码问题, 但在之前的Tomcat版本中,get请求的中文乱码需要自行处理
     老版本Tomcat中文乱码的解决:将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码。
     */
    String user = request.getParameter("username"); //

    //将存入到request缓冲区中的值以ISO-8859-1的方式获取到
    byte[] bytes = user.getBytes("iso-8859-1");
    //以UTF-8的方式进行解码
    String value = new String(bytes, "utf-8");

    System.out.println("user = " + user);
}

3.6 Request域对象

Request作为域对象的API

3.6.1 Request作为域对象作用范围

Request对象其实就是从客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向Request中所保存的数据有效期也是一次请求范围。

一次请求范围:从客户端浏览器向服务器发送一次请求,服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。

每次请求都会创建新的request对象, 当响应结束后立刻销毁request对象.

  • API
方法返回值描述
setAttribute(String name, Object obj)void向Request域中保存数据
getAttribute(String name)Object从Request域中获取数据
removeAttribute(String name)void从Request域中移除数据
  • 代码演示

servlet1

@WebServlet(urlPatterns = "/my1")
public class MyServlet1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //向request域对象中 存值
        request.setAttribute("bit","java");
        //从request域对象中 取值
        Object value = request.getAttribute("bit");
        System.out.println("MyServlet1 value = " + value);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

servlet2

@WebServlet(urlPatterns = "/my2")
public class MyServlet2 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //从request域对象中 取值
        Object value = request.getAttribute("bit");
        System.out.println("MyServlet2 value = " + value);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

这样是获取不到数据的,输出是MyServlet2 value = null

7. 请求转发

3.7.1 原理

在这里插入图片描述

3.7.2 请求转发的写法

通过ServletRequest对象获得RequestDispatcher对象

方法返回值描述
getRequestDispatcher(String path)RequestDispatcher获得RequestDispatcher对象

再根据RequestDispatcher中的方法进行请求转发

方法返回值描述
forward(ServletRequest request, ServletResponse response)void进行请求转发

3.7.3 转发的实现步骤

  • request对象方法获取转发器 RequestDispatcher getRequestDispatcher(“转发地址”)返回值就是转发器
  • 使用转发器对象的方法 forward

代码实现

servlet1

@WebServlet(urlPatterns = "/my1")
public class MyServlet1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //向request域对象中 存值
        request.setAttribute("heima","java");
        //从request域对象中 取值
        Object value = request.getAttribute("heima");
        System.out.println("MyServlet1 value = " + value);

        //进行请求转发
        request.getRequestDispatcher("/my2").forward(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

servlet2

@WebServlet(urlPatterns = "/my2")
public class MyServlet2 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //从request域对象中 取值
        Object value = request.getAttribute("bit");
        System.out.println("MyServlet2 value = " + value);

        //响应回浏览器
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("我是MyServlet2 页面数据");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

4. 请求转发和重定向联系与区别

在这里插入图片描述

  • 联系:浏览器看到的结果是servlet2执行的结果

  • 区别:

    • 请求转发是一次请求一次响应,而重定向是两次请求两次响应。
    • 请求转发地址栏不会变化的,重定向地址栏发生变化。
    • 请求转发路径不带工程名,重定向需要带工程名路径。
    • 请求转发只能在本网站内部,重定向可以定向到任何网站。
  • 注意:

    • 如果需要使用request进行值传递,需要通过请求转发完成。
    • 如果页面需要跳转到其他网站上必须使用重定向, 不能使用request进行值传递。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值