Servlet的Request和Response

一、学习目标

  • 掌握Request和Response对象的概念和使用
  • 能够完成用户登录注册案例的实现
  • 能够完成SqlSessionFactory工具类的抽取

二、Request和Response概述

1. Request: 获取请求数据

  • 浏览器会发送HTTP请求到后台服务器[Tomcat]
  • HTTP的请求中会包含很多请求数据[请求行+请求头+请求体]
  • 后台服务器[Tomcat]会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中
  • 所存入的对象即为request对象,所以我们可以从request对象中获取请求的相关参数
  • 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务

2. Response: 设置请求数据

  • 业务处理完后,后台就需要给前端返回业务处理的结果即响应数据
  • 把响应数据封装到response对象中
  • 后台服务器[Tomcat]会解析response对象,按照[响应行+响应头+响应体]格式拼接结果
  • 浏览器最终解析结果,把内容展示在浏览器给用户浏览

三、Request对象

3.1 Request继承体系

在这里插入图片描述
从图中可以看出,ServletRequestHttpServletRequest都是Java提供的,两者是继承关系,并且都是接口,接口无法创建对象,所以service方法参数中的对象都是由Tomcat创建,因此就要用到Request继承体系中的**RequesrFacade**

  • 该类实现了HttpServletRequest接口,也间接实现了ServletRequest接口
  • Servlet类中的service方法、deGet方法还有doPost方法最终都由Web服务器Tomcat来调用,所以Tomcat提供了方法参数接口的具体实现类,并完成了对象的创建

3.2 Request获取请求数据

HTTP请求数据一共包括三部分:请求行、请求头、请求体,三部分数据获取方式如下

(1)获取请求行数据

请求行包括三部分内容,分别是请求方式请求资源路径HTTP协议及版本
在这里插入图片描述
对于这三部分内容,request对象都提供了对应的方法来获取:

  • 获取请求方式GET
String getMethod()
  • 获取虚拟目录(项目访问路径)/request-deom
String getContextPath()
  • 获取URL(统一资源定位符)http://localhost:8080/request-demo/req1
StringBuffer getRequestURL()
  • 获取URI(统一资源标识符)/request-demo/req1
String getRequestURI()
  • 获取请求参数(GET方式)username=zhangsan&password=123
String getQueryString()

(2)获取请求头数据

对于请求头数据,格式为key:value,如下
在这里插入图片描述
根据请求头名称获取对应值的方法为:

String getHeader(String name)

(3)获取请求体数据

浏览器在发送GET请求的时候是没有请求体的,所以要把请求方式变更为POST请求体中的数据格式如下:
在这里插入图片描述
Request对象提供了两种方式来获取请求体中的数据:

  • ServletInputStream getInputStream():获取字节输入流,如果前端发送的是字节数据,比如传递的是文件数据,则使用该方法

  • BufferedReader getReader():获取字符输入流,如果前端发送的是纯文本数据,则使用该方法

(4)获取请求参数

请求参数是请求数据的部分内容
GET请求的请求参数在请求行中
POST请求的的请求参数在请求体中

Ⅰ、
请求参数的获取常用的两种方式

  • GET方式
String getQueryString()
  • POST方式
BufferedReader getReader()


request提供的通用的方式

  • 获取所有参数的Map集合
Map<String, String[]> getParameter()
  • 根据名称获取参数值(数组)
String[] getParameterValues(String name)
  • 根据名称获取参数值(单个值)
String getParameter(String name)

小结
req.getParameter()方法使用的频率会比较高
以后我们再写代码的时候,就只需要按照如下格式来编写:

public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //采用request提供的获取请求参数的通用方式来获取请求参数
       //编写其他的业务代码...
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

3.3 Request请求转发

请求转发(forward):一种在服务器内部的资源跳转方式
在这里插入图片描述
(1)浏览器发送数据给服务器,服务器中对应的资源A接收到请求
(2)资源A处理完请求后将请求发给资源B
(3)资源B处理完后将结果响应给浏览器
(4)请求从资源A到资源的B的过程就叫请求转发

(1)请求转发的实现方式

reuest.getRequestDispatcher("资源路径").forward(request, responce)
在这里插入图片描述
具体实现步骤代码为:

/**
 * 请求转发
 */
@WebServlet("/req5")
public class RequestDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo5...");
        //请求转发
        request.getRequestDispatcher("/req6").forward(request,response);
    }

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

(2)请求转发资源间共享数据:使用Request对象

此处主要解决的问题的传递数据
需要使用Request对象提供的三个方法:

  • 存储数据到request域[范围,数据存储在request对象]中
    void setAttribute(String name, Object o)

  • 根据key获取值
    Object getAttribute(String name)

  • 根据key删除该键值对
    void removeAttribute(String name)

四、Reponse对象

4.1 Response继承体系

在这里插入图片描述

4.2 Response设置请求数据功能介绍

  • 响应行
    在这里插入图片描述
    设置响应状态码void setStatus(int sc)

  • 响应头
    在这里插入图片描述
    设置响应头键值对void setHeader(String name, String value)

  • 响应体
    在这里插入图片描述
    对于响应体,是通过字符、字节输出流的方式往浏览器写

获取字符输出流PrintWriter getWriter()

获取字节输出流ServletOutputStream getOutputStream()

4.3 Response请求重定向

Response重定向(redirect):一种资源跳转方式
在这里插入图片描述
(1)浏览器发送数据给服务器,服务器中对应的资源A收到请求
(2)资源A无法处理该请求,就会给服务器响应一个302
的状态码+location的一个访问资源B的路径
(3)浏览器收到响应状态码为302就睡重新发送请求到location对应的访问地址去访问资源B
(4)资源B收到请求后进行处理并最终给浏览器响应结果,这个过程就叫做重定向

(1)重定向的实现方式

response.setStatus(302)
response.setHeader("location", "资源B的访问路径")

简化版的实现方式
response.sendRedirect("资源B的访问路径")

(2)重定向和请求转发的区别

在这里插入图片描述

(3)路径问题

  • 问题1:转发的时候路径上没有加/request-demo而重定向加了,那么到底什么时候需要加,什么时候不需要加呢?
    在这里插入图片描述

其实判断的依据很简单,只需要记住下面的规则即可:

浏览器使用:需要加虚拟目录(项目访问路径)
服务端使用:不需要加虚拟目录

对于转发来说,因为是在服务端进行的,所以不需要加虚拟目录
对于重定向来说,路径最终是由浏览器来发送请求,就需要添加虚拟目录。

4.4 Response响应字符数据

要将字符数据写回到浏览器,需要两个步骤

  • 通过Response对象获取字符输出流:PrintWriter writer = response.getWriter()
  • 通过字符输出流写数据:writer.write("aaa")

(1)返回一个简单的字符串“aaa”

/**
 * 响应字符数据:设置字符数据的响应体
 */
@WebServlet("/resp3")
public class ResponseDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //1. 获取字符输出流
        PrintWriter writer = response.getWriter();
		 writer.write("aaa");
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

(2)返回一串html字符串,并且能被浏览器解析

PrinteWriter writer = response.getWriter();
//content-type,告诉浏览器返回的数据类型是HTML类型数据,这样浏览器才会解析HTML标签
response.setHeader("content-type","text/html");
writer.write("<h1>aaa</h1>");

(3)返回一个中文字符串,需要注意设置响应数据的编码格式为utf-8

//设置响应的数据格式及数据的编码
response.setContentType("text/html;charset=utf-8");
writer.write("您好")

4.4 Response响应字节数据

将字节数据写回到浏览器,需要两个步骤

  • 通过Response对象获取字节输出流:ServletOutputStream outputStream = response.getOutputStream()
  • 通过字节输出流写数据:outputStream.write(字节数据)

(1)返回一个图片文件到浏览器

/**
 * 响应字节数据:设置字节数据的响应体
 */
@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 读取文件
        FileInputStream fis = new FileInputStream("d://a.jpg");
        //2. 获取response字节输出流
        ServletOutputStream os = response.getOutputStream();
        //3. 完成流的copy
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = fis.read(buff))!= -1){
            os.write(buff,0,len);
        }
        fis.close();
    }

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

(2)上述代码中,对于流的copy的代码还是比较复杂的,所以我们可以使用别人提供好的方法来简化代码的开发,具体的步骤是:

  • 添加pom.xml依赖
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
  • 调用工具类方法
//fis:输入流
//os:输出流
IOUtils.copy(fis,os);

优化后的代码

/**
 * 响应字节数据:设置字节数据的响应体
 */
@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 读取文件
        FileInputStream fis = new FileInputStream("d://a.jpg");
        //2. 获取response字节输出流
        ServletOutputStream os = response.getOutputStream();
        //3. 完成流的copy
      	IOUtils.copy(fis,os);
        fis.close();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值