Request(请求)和 Response(响应)

本文详细介绍了HTTP请求与响应的工作原理,包括请求行、请求头、请求体等组成部分的解析方法,以及响应行、响应头、响应体的设置技巧。同时,还探讨了请求转发与重定向的区别和实现方式。

请添加图片描述

  • Request:获取请求数据
  • Respone:设置响应数据

Request

Request 继承体系

请添加图片描述1.Tomcat 需要解析请求数据,封装为 request 对象 ,并且创建 request 对象传递到service对象方法中。
2.使用 request 对象,查阅 JavaEE API文档的 HttpServletRequest 接口。

Request 获取请求数据
  • 请求数据分为 3 部分
    1.请求行:
    请添加图片描述

获取请求方式: GET

String getMethod()

获取虚拟目录(项目访问路径): /request-demo

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.请求头
请添加图片描述所以根据请求头名称获取对应值的方法为:

String getHeader(String name)

3.请求体
请添加图片描述对于请求体中的数据,Request对象提供了如下两种方式来获取其中的数据,分别是:

  • 获取字节输入流,如果前端发送的是字节数据,比如传递的是文件数据,则使用该方法
ServletInputStream getInputStream()
该方法可以获取字节
  • 获取字符输入流,如果前端发送的是纯文本数据,则使用该方法
BufferedReader getReader()
Request 通过方式获取请求数据
  • GET 方式
String getQueryString()
  • POST 方式
BufferedReader getReader()

思考:GET 请求方式和 POST 请求方式区别主要在于获取请求参数的方式不一样,是否可以提供一种统一获取请求参数的方式,从而统一 doGet 和doPost 方法内

request对象为我们提供了如下方法:

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

使用通用方式获取请求参数后,屏蔽了GET和POST的请求方式代码的不同,则代码可以定义如下格式:
请添加图片描述
不管是GET还是POST请求,在发送的请求参数中如果有中文,在后台接收的时候,都会出现中文乱码的问题。
解决方案:

  • POST:设置输入流的编码
req.setCharacterEncoding("UTF-8");
  • 通用方式(GET/POST):先编码,再解码
  new String(username.getBytes("ISO-8859-1"),"UTF-8");
/**
 * 中文乱码问题解决方案
 */
@WebServlet("/req4")
public class RequestDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 解决乱码:POST,getReader()
        //request.setCharacterEncoding("UTF-8");//设置字符输入流的编码

        //2. 获取username
        String username = request.getParameter("username");
        System.out.println("解决乱码前:"+username);

        //3. GET,获取参数的方式:getQueryString
        // 乱码原因:tomcat进行URL解码,默认的字符集ISO-8859-1
       /* //3.1 先对乱码数据进行编码:转为字节数组
        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
        //3.2 字节数组解码
        username = new String(bytes, StandardCharsets.UTF_8);*/

        username  = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);

        System.out.println("解决乱码后:"+username);

    }

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

另外需要说明一点的是Tomcat8.0之后,已将GET请求乱码问题解决,设置默认的解码方式为UTF-8

请求转发
  • 请求转发(forward):一种在服务器内部的资源跳转方式。
    请添加图片描述
  • 实现方式:
req.getRequestDispatcher("资源B路径").forward(req,resp);
  • 请求转发资源间共享数据:使用 Request 对象
    此处主要解决的问题是把请求从/req5转发到/req6的时候,如何传递数据给/req6
    需要使用request对象提供的三个方法:

1.存储数据到request域[范围,数据是存储在request对象]中

void setAttribute(String name,Object o);

2.根据key获取值

Object getAttribute(String name);

3.根据key删除该键值对

void removeAttribute(String name);

请求转发的特点

  • 浏览器地址栏路径不发生变化

    虽然后台从/req5转发到/req6,但是浏览器的地址一直是/req5,未发生变化

  • 只能转发到当前服务器的内部资源

    不能从一个服务器通过转发访问另一台服务器

  • 一次请求,可以在转发资源间使用request共享数据

    虽然后台从/req5转发到/req6,但是这个只有一次请求

Respone

Respone 设置相应数据功能介绍

相应数据分为3部分:
1.相应行:
对于响应头,比较常用的就是设置响应状态码:

void setStatus(int sc);

请添加图片描述
2.相应头:
设置响应头键值对:

void setHeader(String name,String value);

请添加图片描述
3.响应体:
对于响应体,是通过字符、字节输出流的方式往浏览器写,

获取字符输出流:

PrintWriter getWriter();

获取字节输出流

ServletOutputStream getOutputStream();

请添加图片描述

Respone完成重定向

重定向(Redirect):一种资源跳转方式
请添加图片描述实现方式:

resp.setStatus(302);
resp.setHeader("location","资源B的访问路径");
//简化重定向方法
response.sendRedirect("资源B的访问路径");

重定向的特点:

  • 浏览器地址栏路径发送变化
  • 可以重定向到任何位置的资源(服务内容、外部均可)
  • 两次请求,不能在多个资源使用request共享数据
路径问题

问题1:明确路径谁实用

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

练习:

  • <a href='路劲'>
  • <form action='路径'>
  • req.getRequestDispatcher(“路径”)
  • resp.sendRedirect(“路径”)

答案:

1.超链接,从浏览器发送,需要加
2.表单,从浏览器发送,需要加
3.转发,是从服务器内部跳转,不需要加
4.重定向,是由浏览器进行跳转,需要加。

动态获取虚拟目录

 String contextPath = request.getContextPath();
    response.sendRedirect(contextPath+"/resp2");
Response 响应字符数据

使用:

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

注意:

  • 该流不需要关闭,随着相应结束,response对象销毁,该服务器关闭。
  • 中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1
    resp.setContentType("text/html;charset=utf-8");
Response 响应字符数据
  • 使用:
	通过Response对象获取字节输出流: ServletOutputStream outputStream = resp.getOutputStream();
	通过字节输出流写数据: outputStream.write(字节数据);
  • IOUtils 工具类使用
    1.导入坐标
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

2.使用

//fis:输入流
//os:输出流
IOUtils.copy(fis,os);
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值