JavaWeb核心修炼手册08---Http协议概述、Request

一、今日内容

1. Http协议概述
2. Request

二、Http、Request

1. Http协议概述
* 概念:Hyper Text Transfer Protocol 超文本传输协议
    * 传输协议:定义了客户端与服务器端通信时,发送数据的格式
    * 特点:
        1. 基于TCP/IP的高级协议
        2. 默认端口号: 80
        3. 基于请求/响应模型:一次请求对应一次响应
        4. 无状态的:每次请求之间是相互独立的,不进行数据交流
    * 历史版本:
        1. 1.0:每次请求并相应完毕后都会断开,下次建立新的连接
        2. 1.1:复用连接(短时间内复用)
* 请求消息数据格式:
    1. 请求行
        * 格式:
            请求方式 请求url 请求协议/版本
            GET /login.html http/1.1
            
            * 请求方式:
                * HTTP协议有7中请求方式,常用的有2种
                    * GET:
                        1. 请求参数在请求行中,在url后。
                        2. 请求的url长度有限制的
                        3. 不太安全
                    * POST:
                        1. 请求参数在请求体中
                        2. 请求的url长度没有限制的
                        3. 相对安全
    2. 请求头:客户端浏览器告诉服务器一些信息
        * 格式:键值对形式
            请求头名称: 请求头值
        * 常见的请求头:
            1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
                * 可以在服务器端获取该头的信息,解决浏览器的兼容性问题
            2. Referer:http://localhost/login.html
                * 告诉服务器,我(当前请求)从哪里来?
                    * 作用:
                        1. 防盗链
                        2. 统计工作
    3. 请求空行
        * 空行,就是用于分割POST请求的请求头,和请求体的。
    4. 请求体
        * 封装POST请求消息的请求参数的
            * setCharacterEncoding()只是对请求体有效,所以只是对post请求有效,对get请求无效

    eg:一个字符串形式的请求信息:
        POST /login.html    HTTP/1.1
        Host: localhost
        User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
        Accept-Encoding: gzip, deflate
        Referer: http://localhost/login.html
        Connection: keep-alive
        Upgrade-Insecure-Requests: 1
        
        username=zhangsan   

防盗链示意图:
[图片上传失败...(image-9d3edb-1584450004312)]

2. Request

(1)request对象和response对象的原理

1. request和response对象是由服务器创建的。我们来使用它们
2. request对象是来获取请求消息,response对象是来设置响应消息
在这里插入图片描述

(2)request对象继承体系结构

ServletRequest      --  接口
        |   继承
HttpServletRequest  -- 接口
        |   实现
org.apache.catalina.connector.RequestFacade 类(tomcat)

继承于HttpServlet抽象类的servlet类重写的doPost/doGet方法参数有 HttpServletRequest req,其中reqorg.apache.catalina.connector.RequestFacade类的实例化对象。

(3)request功能

1. 获取请求消息数据
    1. 获取请求行数据
        * GET /day14/demo1?name=zhangsan HTTP/1.1
        * 方法:
            1. 获取请求方式 :GET
                * String getMethod()  
            2. (*)获取项目的虚拟目录:/day14
                * String getContextPath()
            3. 获取Servlet虚拟路径: /demo1
                * String getServletPath()
            4. 获取get方式请求参数:name=zhangsan
                * String getQueryString()
            5. (*)获取请求URI:/day14/demo1
                * String getRequestURI():       /day14/demo1
                * StringBuffer getRequestURL()  :http://localhost/day14/demo1

                * URL:统一资源定位符 : http://localhost/day14/demo1    中华人民共和国
                * URI:统一资源标识符 : /day14/demo1                    共和国
                * 注意:URI的范围比URL的范围大
            6. 获取协议及版本:HTTP/1.1
                * String getProtocol()
            7. 获取客户机的IP地址:
                * String getRemoteAddr()
    2. 获取请求头数据
        * 方法:
            * (*)String getHeader(String name):通过请求头的名称获取请求头的值
            * Enumeration<String> getHeaderNames():获取所有的请求头名称
                * 举例:
                    Enumeration<String> headerNames = request.getHeaderNames();
                    if (headerNames.hasMoreElements()) {
                        String name = headerNames.nextElement();
                        String value = request.getHeader(name);
                        System.out.println(name + "--" + value);
                    }
    3. 获取请求体数据:
        * 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
        * 步骤:
            1. 获取流对象
                *  BufferedReader getReader():获取字符输入流,只能操作字符数据
                *  ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
            2. 再从流对象中拿数据
            * 举例
                //1.获取流对象
                BufferedReader reader = request.getReader();
                //2.读取请求体中的数据
                String line = null;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }

2. 其他功能:
    1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
        1. String getParameter(String name):根据参数名称获取参数值    username=zs&password=123
        2. String[] getParameterValues(String name):根据参数名称获取参数值的数组  hobby=xx&hobby=game
        3. Enumeration<String> getParameterNames():获取所有请求的参数名称
        4. Map<String,String[]> getParameterMap():获取所有参数的map集合
        * 举例:
            Map<String, String[]> parameterMap = request.getParameterMap();
            Set<String> keys = parameterMap.keySet();
            for (String key : keys) {
                System.out.println(key);
                String[] values = parameterMap.get(key);
                for (String value : values) {
                    System.out.println(value);
                }
                System.out.println("-----");
            }

        * 中文乱码问题:
            * get方式:tomcat 8 已经将get方式乱码问题解决了
            * post方式:会乱码
                * 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
    
            
    2. 请求转发:一种在服务器内部的资源跳转方式
        1. 步骤:
            1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
            2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response) 

        2. 特点:
            1. 浏览器地址栏路径不发生变化
            2. 只能转发到当前服务器内部资源中。
            3. 转发是一次请求


    3. 共享数据:
        * 域对象:一个有作用范围的对象,可以在范围内共享数据
        * request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
        * 方法:
            1. void setAttribute(String name,Object obj):存储数据
            2. Object getAttitude(String name):通过键获取值
            3. void removeAttribute(String name):通过键移除键值对

    4. 获取ServletContext:
        * ServletContext getServletContext()

(4)知识补充

1. form表单的action路径的写法
    * 虚拟目录+Servlet的资源路径
2. BeanUtils工具类,简化数据封装
    * 用于封装JavaBean的
        1. JavaBean:标准的Java类
            1. 要求:
                1. 类必须被public修饰
                2. 必须提供空参的构造器
                3. 成员变量必须使用private修饰
                4. 提供公共setter和getter方法 ---因为设置属性的时候调用的getter和setter方法设置的
            2. 功能:封装数据
        2. 概念:
            成员变量
            属性:setter和getter方法截取后的产物
                例如:getUsername() --> Username--> username
                                |                               |                       |
                            去掉get               首字符小写           类的属性
                * 注意:成员变量和类的属性绝大多数情况下是相同的,因为getter/setter的名字可以更改,会造成成员变量和类的属性可能不一样的情况
        3. 方法:
            1. setProperty(JavaBean对象, 属性名, 属性值)    ---调用的是属性对应的setter方法
            2. getProperty(JavaBean对象, 属性名)     ---调用的是属性对应的getter方法
            3. populate(Object obj , Map map):将map集合的键值对信息,封装到对应的JavaBean对象中
3. 案例

实现一个登入界面的功能:
servlet层代码如下:

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置编码
        request.setCharacterEncoding("utf-8");
        //2.获取所有请求参数及参数值
        Map<String, String[]> parameterMap = request.getParameterMap();
        //3.建立用户对象
        User loginUser = new User();
        System.out.println(loginUser.toString());
        //4.将参数封装到用户对象中
        try {
            BeanUtils.populate(loginUser, parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //5.用户登入
        UserDao userDao = new UserDao();
        User user = userDao.select(loginUser);
        System.out.println(user.toString());
        //6.登入是否成功
        if (user == null) {
            System.out.println("登入失败!");
        } else {
            System.out.println("登入成功!");
        }
    }
}

注意:如果使用BeanUtils来封装对象,一定注意传入的参数名称一定要和对象的成员变量名一致!!!

在这里插入图片描述

在这里插入图片描述
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容