HTTP:


  • 概念:Hyper Text Transfer Protocol 超文本传输协议

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

      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

Request:


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

    1. request和response对象是由服务器创建的。我们来使用它们
    2. request对象是来获取请求消息,response对象是来设置响应消息
  2. request对象继承体系结构:

    ServletRequest -- 接口

    | 继承

    HttpServletRequest -- 接口

    | 实现

    org.apache.catalina.connector.RequestFacade 类(tomcat)

  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
          6. 获取协议及版本:HTTP/1.1
            • String getProtocol()
          7. 获取客户机的IP地址:
            • String getRemoteAddr()
      2. 获取请求头数据

        • 方法:

          • String getHeader(String name):通过请求头的名称获取请求头的值
          • Enumeration尖括号String> getHeaderNames():获取所有的请求头名称
      3. 获取请求体数据:

        • 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
        • 步骤:
          1. 获取流对象

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

      package cn.servletDemo.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;
      import java.io.BufferedReader;
      import java.io.IOException;
      import java.util.Enumeration; @WebServlet("/RequestDemo02")
      public class ServletRequest extends HttpServlet {
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String methopd = req.getMethod(); String contextPath = req.getContextPath(); String servletPath = req.getServletPath(); String requestURI = req.getRequestURI(); StringBuffer RequsetURL = req.getRequestURL(); String requestProtocol = req.getProtocol(); String IP = req.getRemoteAddr(); Enumeration<String> headerNames = req.getHeaderNames(); System.out.printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n", methopd,contextPath,servletPath,requestURI, RequsetURL,requestProtocol,IP); while(headerNames.hasMoreElements()){
      String name = headerNames.nextElement(); String value = req.getHeader(name); System.out.printf("%s\t:%s\n",name,value);
      } }
      /***结果
      GET
      /req
      /RequestDemo02
      /req/RequestDemo02
      http://localhost:8080/req/RequestDemo02
      HTTP/1.1
      0:0:0:0:0:0:0:1
      host :localhost:8080
      connection :keep-alive
      upgrade-insecure-requests :1
      user-agent :Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
      sec-fetch-user :?1
      accept :text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,; q=0.8,application/signed-exchange;v=b3;q=0.9
      sec-fetch-site :none
      sec-fetch-mode :navigate
      accept-encoding :gzip, deflate, br
      accept-language :zh-CN,zh;q=0.9
      cookie :JSESSIONID=4973752F177A01DFD0BC110AB93AEA40; Idea-fe3516c6=e1f7407c-f751-4f0d-99cf-6bbfd9ff1826; goSessionid=wqXEMF4WFNSPwE3L9lcUSMXcLjCnLUgizfec2DipoDI%3D; SL_G_WPT_TO=zh-CN; SL_GWPT_Show_Hide_tmp=undefined; SL_wptGlobTipTmp=undefined; JSESSIONID=7DB8D0F83015408AC113950CB3E0A18B
      ***/ @Override
      protected void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException { //获取请求消息体
      //获取字符流
      BufferedReader br = req.getReader();
      //读数据
      String line = null;
      while((line = br.readLine()) != null){
      System.out.println(line);
      } //结果username=315019748%40qq.com&password=%E9%98%BF%E6%96%AF%E8%BE%BE
      }
      }
      • html代码

      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <title>注册页面</title>
      </head>
      <body> <form action="/req/RequestDemo02" method="post">
      <input type="text" placeholder="请输入用户名" name="username"><br>
      <input type="text" placeholder="请输入密码" name="password"><br>
      <input type="submit" value="注册"> </form>
      </body>
      </html>
      • 结果
    2. 其他功能:

      1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数

        1. String get(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集合
        • 中文乱码问题:

          • get方式:tomcat 8 已经将get方式乱码问题解决了
          • post方式:会乱码
            • 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
      • 代码示例

      @WebServlet("/RequestDemo03")
      public class ServletRequest01 extends HttpServlet {
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //get获取请求参数 //根据请求参数名称获取请求参数值
      String username = req.getParameter("username");
      System.out.println("get:"+username); } @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //post请求参数 req.setCharacterEncoding("utf-8");
      //根据请求参数名称获取请求参数值
      String username = req.getParameter("username");
      System.out.println("post:"+username);
      }
      }
      1. 请求转发:一种在服务器内部的资源跳转方式

        1. 步骤:

          1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
          2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
        2. 特点:
          1. 浏览器地址栏路径不发生变化
          2. 只能转发到当前服务器内部资源中,不能访问外部资源。
          3. 转发实质是同一次请求
      2. 共享数据:

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

        • ServletContext getServletContext()

案例:用户登录


  • 用户登录案例需求:

    1.编写login.html登录页面

    username & password 两个输入框

    2.使用Druid数据库连接池技术,操作mysql,day14数据库中user表

    3.使用JdbcTemplate技术封装JDBC

    4.登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您

  • 开发步骤

    1. 创建项目,导入html页面,配置文件,jar包
    	<!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>登录</title>
    </head>
    <body>
    <form action="/test/LoginServlet" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br> <input type="submit" value="登录"> </form> </body>
    </html>
    1. 创建数据库环境

    CREATE DATABASE day14;
    USE day14;
    CREATE TABLE USER( id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(32) UNIQUE NOT NULL,
    PASSWORD VARCHAR(32) NOT NULL
    );
    1. 创建包package cn.test.domain;,创建类User

    package cn.test.domain; /*
    用户的实体类
    */
    public class User {
    private int id;
    private String username;
    private String password; public int getId() {
    return id;
    } public void setId(int id) {
    this.id = id;
    } public String getUsername() {
    return username;
    } public void setUsername(String username) {
    this.username = username;
    } public String getPassword() {
    return password;
    } public void setPassword(String password) {
    this.password = password;
    }
    }
    1. 创建包cn.test.util,编写工具类JDBCUtils,加载配置文件
    package cn.test.util;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Properties; /*
    JDBC工具类,使用的是Druid连接池
    */
    public class JDBCUtils { private static DataSource dataSource; /*
    静态代码块加载配置文件,初始化连接池
    */
    static {
    try {
    //1.加载配置文件
    Properties pro = new Properties();
    //使用ClassLoader加载配置文件,获取字节输入流
    InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
    pro.load(inputStream); //2.初始化连接池对象
    dataSource = DruidDataSourceFactory.createDataSource(pro); } catch (Exception e) {
    e.printStackTrace();
    }
    } /*
    获取连接池对象
    */
    public static DataSource getDataSource(){
    return dataSource;
    } /*
    获取Connection对象
    */
    public static Connection getConnection() throws SQLException {
    return dataSource.getConnection();
    }
    }
    1. 创建包cn.test.dao,创建类UserDao,提供login方法

    package cn.test.dao; import cn.testT.domain.User;
    import cn.testT.util.JDBCUtils;
    import org.springframework.dao.DataAccessException;
    import org.springframework.jdbc.core.BeanPropertyRowMapper;
    import org.springframework.jdbc.core.JdbcTemplate; /*
    操作数据库User表
    */
    public class UserDao {
    //声明JDBCTemplate对象,实现共用
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); //登录逻辑的完成
    public User login(User loginUser){
    try {
    //1.编写sql
    String sql = "select * from user where username = ? and password = ?"; //2.调用querry方法
    User user = template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),
    loginUser.getUsername(),loginUser.getPassword()); return user;
    } catch (DataAccessException e) {
    e.printStackTrace(); //一般在此处处理日志
    return null;
    }
    }
    }
    1. 编写cn.test.web.servlet.LoginServlet类

    package cn.testT.web.servlet; import cn.testT.dao.UserDao;
    import cn.testT.domain.User; 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("/LoginServlet")
    public class LoginServlet extends HttpServlet { @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //设置编码
    req.setCharacterEncoding("utf-8"); //获取请求参数
    String username = req.getParameter("username");
    String password = req.getParameter("password"); //封装user对象
    User loginUser = new User();
    loginUser.setUsername(username);
    loginUser.setPassword(password); //调用UserDao的login方法
    UserDao dao = new UserDao();
    User user = dao.login(loginUser); //判断user
    if (user == null) {
    //登录失败,内部转发
    req.getRequestDispatcher("/FailServlet").forward(req, resp);
    }
    else {
    //登录成功
    //存储数据 req.setAttribute("user",user);
    //转发
    req.getRequestDispatcher("/SuccessServlet").forward(req,resp);
    }
    } @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    this.doGet(req, resp);
    }
    }
    1. 编写FailServlet和SuccessServlet类

    package cn.testT.web.servlet; 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("/FailServlet")
    public class FailServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //给页面写一句话 //设置页面的编码
    response.setContentType("text/html;charset=utf-8");
    //输出
    response.getWriter().write("输入错误,登录失败");
    } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }
    } ------------------------------------------------------------------------------------------------------------------ package cn.testT.web.servlet; import cn.testT.domain.User; 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("/SuccessServlet")
    public class SuccessServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取request域中共享的user对象
    User user = (User) request.getAttribute("user");
    //给页面写一句话
    //设置页面的编码
    response.setContentType("text/html;charset=utf-8");
    //输出
    response.getWriter().write("登录成功");
    } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }
    }
    1. login.html中form表单的action路径的写法

      • 虚拟目录/Servlet的资源路径
    2. BeanUtils工具类,简化数据封装

      • 用于封装JavaBean的

      package cn.testT.web.servlet; import cn.testT.dao.UserDao;
      import cn.testT.domain.User;
      import org.apache.commons.beanutils.BeanUtils; 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;
      import java.lang.reflect.InvocationTargetException;
      import java.util.Map; @WebServlet("/LoginServlet")
      public class LoginServlet extends HttpServlet { @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //设置编码
      req.setCharacterEncoding("utf-8"); // //获取请求参数
      // String username = req.getParameter("username");
      // String password = req.getParameter("password");
      // //封装user对象
      // User loginUser = new User();
      // loginUser.setUsername(username);
      // loginUser.setPassword(password); //获取所有请求参数
      Map<String, String[]> parameterMap = req.getParameterMap();
      //创建user对象
      User loginUser = new User;
      //使用BeanUtils封装
      try {
      BeanUtils.populate(loginUser,parameterMap);
      } catch (IllegalAccessException e) {
      e.printStackTrace();
      } catch (InvocationTargetException e) {
      e.printStackTrace();
      } //调用UserDao的login方法
      UserDao dao = new UserDao();
      User user = dao.login(loginUser); //判断user
      if (user == null) {
      //登录失败,内部转发
      req.getRequestDispatcher("/FailServlet").forward(req, resp);
      }
      else {
      //登录成功
      //存储数据 req.setAttribute("user",user);
      //转发
      req.getRequestDispatcher("/SuccessServlet").forward(req,resp);
      }
      } @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      this.doGet(req, resp);
      }
      }
      1. JavaBean:标准的Java类(上述User类,一般再domain目录下)

        1. 要求:

          1. 类必须被public修饰
          2. 必须提供空参的构造器
          3. 成员变量必须使用private修饰
          4. 提供公共setter和getter方法
        2. 功能:封装数据
      2. 方法:
        1. setProperty()与getProperty()
        2. populate(Object obj , Map map):将map集合的键值对信息,封装到对应的JavaBean对象中
        • 注意:以上操作的是属性:setter和getter方法截取后的产物,例如:getUsername() --> Username--> username,不是JavaBean的成员变量

requset请求处理与BeanUtils封装的更多相关文章

  1. 使用BeanUtils封装数据时数据类型的转换

    //获得表单数据 Map<String, String[]> properties = request.getParameterMap(); User user = new User(); ...

  2. java使用BeanUtils封装file类型表单数据到一个对象中

    package com.cc.web.servlet; import java.io.FileOutputStream; import java.io.IOException; import java ...

  3. 使用beanUtils封装对象的servlet

    package com.hopetesting.web.servlet;import com.hopetesting.dao.UserDao;import com.hopetesting.domain ...

  4. BeanUtils封装对象时一直提示ClassNotFoundException:org.apache.commons.beanutils.BeanUtils

    导包明明正确了,依赖包也全都导对了,还是出错. 困扰了3天. 后来看到这篇博文,https://blog.csdn.net/yanshaoshuai/article/details/81624890 ...

  5. Magicodes.WeiChat——后台JS框架封装

    Magicodes.WeiChat同时也致力于提高后台开发效率,因此对在后台前端这块也做了一定的封装.我们先来说说主要的框架JS——mwc.js和mwc_elements.js.这两个JS文件位于Sc ...

  6. 第13天 JSTL标签、MVC设计模式、BeanUtils工具类

    第13天 JSTL标签.MVC设计模式.BeanUtils工具类 目录 1.    JSTL的核心标签库使用必须会使用    1 1.1.    c:if标签    1 1.2.    c:choos ...

  7. beanUtils的用法

    举例1:使用BeanUtils工具封装用户提交的数据. public static void main(String[] args)throws Exception { // 模拟用户的输入的数据如下 ...

  8. 几种封装javaBean的方法

    开发框架时,经常需要使用java对象(javaBean)的属性来封装程序的数据,封装javaBean的方法有很多,比如反射,内省,以及使用工具类.下面从反射开始介绍. 1.javaBean介绍: 简介 ...

  9. asp.net的HTTP请求处理过程

    1.asp.net的HTTP请求处理过程 说明: (1).客户端浏览器向服务器发出一个http请求,此请求会被inetinfo.exe进程截获,然后转交给aspnet_isapi.dll进程,接着它又 ...

随机推荐

  1. HDU 5455:Fang Fang 查cff个数

    Fang Fang Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total ...

  2. df 、dh

    查看磁盘 不挂载获取文件系统 [root@localhost ~]# file -s /dev/sda1/dev/sda1: SGI XFS filesystem data (blksz 4096, ...

  3. 【分类问题中模型的性能度量(二)】超强整理,超详细解析,一文彻底搞懂ROC、AUC

    文章目录 1.背景 2.ROC曲线 2.1 ROC名称溯源(选看) 2.2 ROC曲线的绘制 3.AUC(Area Under ROC Curve) 3.1 AUC来历 3.2 AUC几何意义 3.3 ...

  4. spring boot 异常(exception)处理

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  5. vue-cli3.x 搭建项目目

    安装文档 https://cli.vuejs.org/zh/guide/ 安装条件 npm 更至最新 node >=8.9 可以用npm -v 查看npm的版本号 1.关于旧版本 Vue CLI ...

  6. Oracle 基础1

    oracle基础 表空间: Oracle数据库对数据的管理是基于表空间的概念来的, 各种数据的以及存储数据的优化, 实际上也是通过优化表空间来实现的 表空间分类: 永久表空间 用来存放表的数据, 视图 ...

  7. BZOJ 4033: [HAOI2015]树上染色

    题解: 树形DP 思路,考虑每条边的贡献,即这条边两边的黑点数量相乘+白点数量相乘再成边长 #include<iostream> #include<cstdio> #inclu ...

  8. 题解 P1403 【[AHOI2005]约数研究】

    题目 看到题解区很多人直接给出结论:答案为 \(\displaystyle \sum_{i=1}^n\lfloor{n\over i}\rfloor\) ,没给出证明,这里给出证明 [分析] 首先,我 ...

  9. PAT Advanced 1106 Lowest Price in Supply Chain (25) [DFS,BFS,树的遍历]

    题目 A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)– everyone in ...

  10. split和join合写

    小骆驼 第一章 简介 1. // input 和截取字符 #!usr/bin/perl use strict; use warnings; while ( <> ) { chomp; pr ...