HTTP以及Request的获取

本文深入解析HTTP协议的概念、特点和历史版本,详细介绍了请求与响应消息的数据格式,包括请求行、请求头、请求体以及响应消息的构成。同时,探讨了Servlet中request对象的功能和使用方法,如获取请求信息和请求参数。

HTTP

  • 概念: HTTP HyperText Transfer Protocol 超文本传输协议、

    • 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
    • 特点:
      1. 基于TCP/IP的高级协议
      2. 默认端口号:80
      3. 基于请求/响应模型的:一次请求对应一次响应
      4. 无状态的:每次请求之间相互独立,不能交互数据
    • 历史版本:
      • 1.0:每一次请求都会建立新的连接
      • 1.1: 复用连接
  • 请求消息数据格式
    1、请求行

    • 请求方式 / 请求url 请求协议 / 版本
      GET/day13_servlet/demo3 HTTP / 1.1
    • 请求方式
      HTTP协议中有七种请求方式,常用的有两种GET和POST
      • GET
        1.请求参数在请求行中,url里面
        2.请求的url长度有限制
        3.不太安全

      • POST
        1.请求参数在请求体中
        2.请求的url长度没有限制的
        3.相对安全

2、请求头

  • 请求头名称:请求头值
    • 常见的请求头:
      1、 User-Agent:浏览器告诉服务器,我用什么版本的浏览器的信息
      可以在服务器端获取该头信息,解决浏览器的兼容问题
      2、 Referer:获取从哪里来的地址
      • 防盗链:
      • 统计工作:

3、请求空行
空行 用于分割POST请求的请求头和请求体的
4、请求体(正文)
封装post请求消息的请求参数的

字符串格式:
GET/day13_servlet/demo3 HTTP / 1.1
Accept: text/html, application/xhtml+xml, application/xml; q=0.9, /; q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-Hans-CN, zh-Hans; q=0.5
Cache-Control: max-age=0
Connection: Keep-Alive
Host: localhost:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363

  • 响应消息数据格式

Request

  1. request对象和response对象的原理

    • request和response对象是由服务器创建的。我们来使用他们
    • request对象获取请求信息,response对象设置响应消息
  2. request对象继承体系结构:
    ServletRequest --接口
        | 继承
    HttpServletRequest --接口
        | 实现
    org.apache.catalina.connector.RequestFacade 类(tomcat)

  3. request功能:

    • 获取请求消息:
      • 获取请求行数据:GET/day13_servlet/demo3 HTTP / 1.1
        • 方法
          • 获取请求方式:GET
            String getMethod()

          • (*)获取虚拟目录:/day13_servlet
            getContextPath()

          • 获取Servlet路径:/demo3
            get ServletPath()

          • 获取get方式的请求参数
            String getQueryString()

          • (*)获取请求URI:
            String getRequestURI(); /day13_servlet/demo3
            StringBuffer getRequestURL(); http://localhost/day13_servlet/demo3

          • 获取协议及版本:HTTP/1.1
            String getProtocol()

          • 获取客户机的IP地址:
            String getRemoteAddr()

          • 注意点URL和URI的区别:
            URI包含了URL和URN,URL是统一资源定位符,可以说是家庭地址,URN是统一资源标识符可以说是身份证号码。两者都可以唯一确定某一资源。

举例获取请求行数据

package cn.itcast.web.request;

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

/**
 * 演示Request对象获取请求方式
 */

@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {

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


        //获取请求方式:GET
        String method = request.getMethod();
        System.out.println(method);

        //(*)获取虚拟目录:/dayshisan_war_exploded
        String contextPath = request.getContextPath();
        System.out.println(contextPath);

        //获取Servlet路径:/requestDemo1
        String servletPath = request.getServletPath();
        System.out.println(servletPath);

        //获取get方式的请求参数
        String queryString = request.getQueryString();
        System.out.println(queryString);

        //(*)获取请求URI:
        String requestURI = request.getRequestURI();//  /dayshisan_war_exploded/requestDemo1
        StringBuffer requestURL2 = request.getRequestURL();// http://localhost:8080/dayshisan_war_exploded/requestDemo1
        System.out.println(requestURI);
        System.out.println(requestURL2);

        //获取协议及版本:HTTP/1.1
        String protocol = request.getProtocol();
        System.out.println(protocol);

        //获取客户机的IP地址: 0:0:0:0:0:0:0:1
        String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);
    }
}

运行结果

GET
/dayshisan_war_exploded
/requestDemo1
null
/dayshisan_war_exploded/requestDemo1
http://localhost:8080/dayshisan_war_exploded/requestDemo1
HTTP/1.1
0:0:0:0:0:0:0:1
  1. 获取请求头数据

    • 方法:
      • String getHeader(String name); 通过请求头的名称获取请求头的值
      • Enumeration<String> getHeaderNames(); 获取所有的请求头名称
        Enumeration接口和迭代器有些类似,基本上被迭代器取代
  2. 获取请求体数据
    请求体:只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数
    方法:

    • 获取流对象:
      BufferedReader getReader() 获取字符输入流,只能操作字符数据
      ServletInputStream getInputStream() 获取字节输入流,可以操作所有类型数据
    • 再从流对象中拿数据
  3. 其它功能:

    • 获取请求参数通用方式(GET和POST都可以)
      • getParameter(String name); 根据参数名获取参数值
      • String[] getParameterValues(String name); 根据参数名获取参数值的数组 这是当一个键对应多个值的时候用的
      • Enumeration<String> getParameterNames(); 获取所有请求的参数名称
      • Map<String,String[]> getParameterMap();获取所有参数的Map集合
      • 中文乱码问题
        • tomcat8.0往后,get方式不会产生乱码
        • post方式会产生乱码,在doPost方法的第一行设置一下流的编码,改成和html页面的一样就行了,这里设置为utf-8
          req.setCharacterEncoding(“utf-8”);

代码举例:
这是对应的HTML页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/day14/requestDemo4" method="post">    <!--这儿的day14需要加上,从模块开始一直到所要连接的对象-->
        <input type="text" placeholder="请输入用户名" name = "username"><br/>
        <input type="text" placeholder="请输入密码" name="password"><br/>

        <input type="checkbox" name="hobby" value="play ball">打球  <!--复选框checkbox-->
        <input type="checkbox" name="hobby" value="play games">游戏

        <input type="submit" value="注册">
    </form>
</body>
</html>

这是Java后台写的doPost方法

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /* 根据name获取单个value
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println("username " + username);
        System.out.println("password " + password);
        */

        /* 如果某个name有多个value,可以这样获取,获取到value的数组形式
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies
             ) {
            System.out.println(hobby);
        }
        */

        /* 获取所有的name,再根据name用getParameter方法将每一个name的值获取到
        这里有一个name对应多个value没有改,所以hobby选两个的话,这儿还是只会输出一个,
        把方法改成获取数组类型就可以了
        Enumeration<String> parameterNames = req.getParameterNames();
        while(parameterNames.hasMoreElements()) {
            String str = parameterNames.nextElement();
            System.out.println(str);

            String value = req.getParameter(str);
            System.out.println(value);
            System.out.println("--------------------------");
        }
         */

        /* 上述的修改后,可以将复选框中选中的两个值都输出出来
        Enumeration<String> parameterNames = req.getParameterNames();
        while(parameterNames.hasMoreElements()) {
            String str = parameterNames.nextElement();
            System.out.println(str);

            String[] parameterValues = req.getParameterValues(str);
            for (String parametervalue : parameterValues
                 ) {
                System.out.println(parametervalue);
            }

            System.out.println("--------------------------");
        }
         */

        /* 根据Map集合获取键值对,再用Set来迭代输出key和values
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> keyset = parameterMap.keySet();

        for (String name : keyset
             ) {
            System.out.println(name);
            String [] values = parameterMap.get(name);
            for (String value : values
            ) {
                System.out.println(value);
            }
            System.out.println("---------------");
        }
         */
    }
  1. 请求转发:是一种发生在服务器内部的资源跳转方式

    • 步骤:
      • 第一步:通过request对象获取请求转发器对象:RequestDispatcher path = req.getRequestDispatcher(“要跳转到的路径”);
      • 第二步:使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response);
    • 特点:
      • 浏览器地址栏不发生变化
      • 只能转发到当前服务器内部资源中
      • 转发是一次请求
  2. 共享数据

    • 域对象:一个有作用范围的对象,可以在范围内共享数据
    • request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
    • 方法:
      • void setAttribute(String name,Object obj);存储数据
      • Object getAttribute(String name); 通过键获取值
      • void removeAttribute(String name); 通过键移除键值对
    • 注意:要转发前存储数据
  3. 获取ServletContext
    ServletContext getServletContext()
    这个方法在之后细讲

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值