[Java] HTTP,Request

36 篇文章 0 订阅
3 篇文章 0 订阅

第一章 HTTP

1.1 概述

HTTP(Hyper Text Transfer Protocol): 超文本传输协议

  • 传输协议 : 定义了客户端和服务器通信时,发送数据的格式

  • 特点:

    1. 基于 TCP/IP 的高级协议
    2. 默认端口号: 80
    3. 基于请求/响应模型的(一次请求,对应一次响应)
    4. 无状态的协议: 每次请求之间相互独立
  • 历史版本

    • 1.0: 每一次请求都会建立一个新的连接
    • 1.1: 会复用前面的连接

1.2 HTTP请求消息数据格式

  1. **请求行 **: 说明请求的参数,请求的url,请求的协议
    • 格式: 请求方式 请求url 请求版本/协议
    • 例子GET /JavaWeb_war_exploded/hello-servlet HTTP/1.1
    • 请求方式不同, 参数的位置也会不同
      1. GET方式: 请求参数在请求行中, 在url之后 (可能会不安全,因为参数暴露在url后面) ,例如:localhost:8080/JavaWeb_war_exploded/haha?username = xxx
      2. POST方式, 请求的参数在方法体中
      3. GET请求的url长度有限制 ,POST没有限制
  2. 请求头 : 请求行下面紧接着就是请求头,客户端的服务器告诉服务器的一些信息
    • 格式: 请求头名称: 请求头值有多个
    • 代码有很多,下面有例子
    • 常见的请求头里面的参数
      1. User-Agent : 浏览器告诉服务器我的浏览器及其版本信息,解决兼容性问题,同时也可以用来进行爬虫的伪装
      2. Accept: 告诉服务器我可以响应和解析什么样的数据格式 (我是浏览器)
      3. Accept-Language: 我这个浏览器支持什么语言
      4. Accept-Encoding: 浏览器可以接受的压缩格式
      5. Referer:告诉服务器 , 我(当前请求)从哪里来
        • 作用
          1. 防盗链: 判断referer是不是来自我想要他来自的网页
          2. 统计工作: 统计不同referer出现的次数
      6. Connection: 连接是否可以被复用 ,现在一般都是Keep-alive
  3. 请求空行 : 就是一个空行,作用是 分割请求头和请求体
  4. 请求体: 封装POST请求消息的请求参数的
    • get方式没有请求体,POST有
    • 格式 :上传的数据的名字 = xxx
    • 例子: username=213214 (我是通过表单提交,跳转到这个页面之后才有的这个数据)

HTML代码

<form action="/JavaWeb_war_exploded/haha" method="post">
    <input type="text" name="username">
    <input type="submit" value="提交">
</form>

跳转到页面之后我输入了213214然后提交 ,跳转页面之后,页面的请求消息的数据格式如下

POST /JavaWeb_war_exploded/haha HTTP/1.1   //1 这个是请求行
Host: localhost:8080	//2 下面都是请求头
Connection: keep-alive
Content-Length: 15
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Microsoft Edge";v="90"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.56
Origin: http://localhost:8080
Content-Type: application/x-www-form-urlencoded
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: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/JavaWeb_war_exploded/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh-TW;q=0.9,zh;q=0.8,en;q=0.7,en-GB;q=0.6,en-US;q=0.5
Cookie: JSESSIONID=1A4D131E4EDDA8E07B9B8561358319BF; Idea-874da8ff=e5d280ff-d15e-4ffc-9d9a-7deff96ccca0; Idea-874dacbf=2a6e965e-f65a-49e9-8b63-726ad404dc88
	  //3 这一行是请求空行
username=213214    //4 这个就是请求体

第二章 Request

2.1 Request和Response的原理

resquest对象和response对象的原理

  • 这两个对象都是由服务器创建的,我们来使用它
  • request对象就是用来获取请求消息,response用来设置响应消息

Tomcat对请求的处理原理

  1. tomcat服务器会根据请求url中的资源路径,创建对应的Servlet实现类的对象。
  2. tomcat服务器,会创建resquest和response对象,resquest中封装了请求消息数据
  3. tomcat将这两个对象传进service方法中,并调用service方法(关键步骤),里面怎么处理,响应什么,由我们程序员决定(定义service方法中的具体实现)
  4. 服务器在给浏览器做响应之前,会从response对象中拿到程序员设置的响应消息数据。

下面给出图解

在这里插入图片描述

2.2 Request对象继承体系结构

  • ServletRequest 接口
    • HttpServletRequest 接口
      • Tomcat的实现类: org.apache.catalina.connector.RequestFacade

2.3 Request获取请求行数据

请求行数据的格式示例

POST /JavaWeb_war_exploded/haha HTTP/1.1

下面的方法都是基于接口HttpServletRequest

方法介绍

  1. 获取请求方式

    • String getMethod() 
          
      Returns the name of the HTTP method with which this request was made, for example, GET, POST, or PUT. 
      
  2. (*) 获取虚拟目录

    • String getContextPath() 
      Returns the portion of the request URI that indicates the context of the request. 
      
    • 对于上面那个例子,返回的就是/JavaWeb_war_exploded

  3. 获取Servlet实现类的urlpattern路径

    • String getServletPath() 
      Returns the part of this request's URL that calls the servlet. 
      
    • 对于上面的例子,返回的就是/haha

  4. 获取GET方式的请求参数

    • String getQueryString() 
      Returns the query string that is contained in the request URL after the path. 
      
    • 对于上面的例子,返回的就是null

  5. (*) 获取请求的URI(统一资源标识符)

    • String getRequestURI() 
      Returns the part of this request's URL from the protocol name up to the query string in the first line of the HTTP request. 
      
    • 对于上面的例子,返回的就是/JavaWeb_war_exploded/haha

  6. 获取请求的URL(统一资源定位符)

    • StringBuffer getRequestURL() 
      Reconstructs the URL the client used to make the request. 
      
    • 上面的例子,返回的就是http://localhost/JavaWeb_war_exploded/haha

    • 注意: 它返回的是StringBuffer类

  7. 获取浏览器的协议以及版本: (这个方法在ServletRequest接口里面)

    • String getProtocol() 
      Returns the name and version of the protocol the request uses in the form protocol/majorVersion.minorVersion, for example, HTTP/1.1. 
      
    • 对于上面的例子,返回的就是HTTP/1.1

  8. 获取客户机的IP地址

    • String getRemoteAddr() 
      Returns the Internet Protocol (IP) address of the client or last proxy that sent the request. 
      
    • 对于上面的例子,返回的就是0:0:0:0:0:0:0:1

代码实现

@WebServlet("/haha")
public class ServletDemo3 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(req.getMethod());
        System.out.println(req.getContextPath());
        System.out.println(req.getServletPath());
        System.out.println(req.getQueryString());
        System.out.println(req.getRequestURL());
        System.out.println(req.getRequestURI());
        System.out.println(req.getProtocol());
        System.out.println(req.getRemoteAddr());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}
//输出结果
//GET
///JavaWeb_war_exploded
///haha
//null
//http://localhost/JavaWeb_war_exploded/haha
///JavaWeb_war_exploded/haha
//HTTP/1.1
//0:0:0:0:0:0:0:1

2.4 Request获取请求头数据

方法介绍

  1. 通过参数的名称获取对应的请求头的参数的值 (常用)
  • String getHeader(String name) 
    Returns the value of the specified request header as a String. 
        
    Enumeration<String> getHeaders(String name) 
    Returns all the values of the specified request header as an Enumeration of String objects. 
    

    注意: 这里的name参数是不区分大小写的

  1. 获取请求头中所有的参数的名字

    • Enumeration<String> getHeaderNames() 
      Returns an enumeration of all the header names this request contains. 
      

枚举的用法和Iterator十分像,稍微介绍一下

 boolean hasMoreElements() 
          Tests if this enumeration contains more elements. 
              
 E nextElement() 
          Returns the next element of this enumeration if this enumeration object has at least one more element to provide. 

代码实现

@WebServlet("/haha")
public class ServletDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration<String> request = req.getHeaderNames();

        while(request.hasMoreElements()){
            String s = request.nextElement();
            System.out.println(s + " : " +  req.getHeader(s));
        }
    }=
}

//运行结果
//host : localhost
//connection : keep-alive
//cache-control : max-age=0
//sec-ch-ua : " Not A;Brand";v="99", "Chromium";v="90", "Microsoft Edge";v="90"
//sec-ch-ua-mobile : ?0
//upgrade-insecure-requests : 1
//user-agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.56
//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
//sec-fetch-user : ?1
//sec-fetch-dest : document
//accept-encoding : gzip, deflate, br
//accept-language : zh-CN,zh-TW;q=0.9,zh;q=0.8,en;q=0.7,en-GB;q=0.6,en-US;q=0.5
//cookie : JSESSIONID=548F53F7E4C684314F1315B2348D4A27; Idea-874da8ff=e5d280ff-d15e-4ffc-9d9a-7deff96ccca0; Idea-874dacbf=2a6e965e-f65a-49e9-8b63-726ad404dc88



//注意,这里无关的一些代码我都删掉了

注意: 如果我是直接通过浏览器输入地址进去的网站,那么 referer就是null

2.5 Request获取请求体数据

注意: 要想有请求体,那么请求方式必须是POST

步骤:

  1. 获取流对象 ( 若用户输入的账号密码等,那么就使用字符流 ) (若用户是上传图片等,那么我们就使用字节流 )

    1. 获取字符输入流,只能操作字符数据(但是它方便)

      • BufferedReader getReader() 
            
        Retrieves(检索) the body of the request as character data using a BufferedReader. 
        
    2. 获取字节输入流,可以操作所有类型的数据

      • ServletInputStream getInputStream() 
            
        Retrieves the body of the request as binary data using a ServletInputStream. 
        
  2. 再从流对象中拿取数据 (以前的知识,懂得都懂)

代码实现

这里实现一个字符流的

@WebServlet("/haha")
public class ServletDemo3 extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //将请求参数的字符流放入br里面
        BufferedReader br = req.getReader();
        //读取数据
        String line = null;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
    }
}

2.6 其他功能

下面的方法都很常用

2.6.1 获取请求参数通用方式(Get和Post的请求方式参数都能获取)

  1. String getParameter(String name): 根据参数名称获取参数值,不存在就返回null
  2. String[] getParameterValues(String name): 根据参数名称获取参数值的数组 (多用于复选框)
  3. Enumeration getParameterNames(): 获取所有请求的参数名称
  4. Map<String, String[]> getParameterMap(): 获取所有参数的键值对的集合
方法演示
@WebServlet("/haha")
public class ServletDemo3 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求参数
        //方法1
        System.out.println(req.getParameter("username"));
        //方法2
        System.out.println(Arrays.toString(req.getParameterValues("hobby")));
        //方法3
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> strings = parameterMap.keySet();
        for (String name : strings) {
            System.out.print(name + ":");
            //根据name来获取值
            String[] values = parameterMap.get(name);
            System.out.println(Arrays.toString(values));
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
//我们会发现无论是post还是get都是会返回我们想要的请求参数的值
中文乱码问题

tomcat8以下会出现这个乱码问题(无论是get还是post都会)

解决方法: 在获取参数前,设置编码(设置的编码和网页的编码保持一致,一般是utf-8)

void setCharacterEncoding(String env) 
Overrides the name of the character encoding used in the body of this request. 

例如: setCharacterEncoding("utf-8")

2.6.2 请求转发

请求转发: 一种在服务器内部资源跳转的方式

实现步骤
  1. 通过request对象获取请求转发器对象:

    • RequestDispatcher getRequestDispatcher(String path) 
      Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path. 
      
  2. 使用RequestDispatcher进行转发(下面这个方法就是属于RequestDispatcher接口的)

    • void forward(ServletRequest request, ServletResponse response) 
      Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. 
      

特点

  1. 浏览器的地址栏没有发生变化
  2. 资源只能转发到内部服务器里的其他servlet
  3. 通过抓包,我们知道: 转发是一次请求,即我们访问原来的网页之后就没有其他任何请求了
代码实现
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo5被访问了");
        //我现在要转发资源
        req.getRequestDispatcher("/demo6").forward(req,resp);

    }

2.6.3 共享数据(域对象)

域对象: 一个有作用范围的对象,可以在范围之内共享数据

request域: 代表一次请求的范围 , 一般用于请求转发的多个资源中共享数据

相关方法

来自ServletRequest接口

  1. 这次请求中存储数据

    • void setAttribute(String name, Object o) 
      Stores an attribute in this request. 
      
  2. 得到数据,没有返回null

    • Object getAttribute(String name) 
      Returns the value of the named attribute as an Object, or null if no attribute of the given name exists. 
      
  3. 删除request域中的数据(通过键来删除)

    • void removeAttribute(String name) 
      Removes an attribute from this request. 
      
代码实现
//这是demo5
@WebServlet("/demo5")
public class ServletDemo5 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo5被访问了");

        //存储资源
        req.setAttribute("name","YourFather");

        //我现在要转发资源
        req.getRequestDispatcher("/demo6").forward(req,resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

//这是demo6
@WebServlet("/demo6")
public class ServletDemo6 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo6被访问了");

        System.out.println(req.getAttribute("name"));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}


//我们只访问了http://localhost/JavaWeb_war_exploded/demo5
//打印台输出
//demo5被访问了
//demo6被访问了
//YourFather

2.6.4 获取ServletContext(这里了解即可,后面会详细讲)

相关方法
ServletContext getServletContext() 
Gets the servlet context to which this ServletRequest was last dispatched. 

第三章 Request 综合案例

3.1 需求介绍

  1. 编写login.html登录页面 (username和password)
  2. 使用Druid数据库连接池技术, 操作mysql中我们创建的user表
  3. 使用jdbcTemplate技术封装JDBC
  4. 登陆成功跳转到SuccessServlet展示: 登陆成功! [用户名],欢迎您~
  5. 登录失败跳转到FailServlet展示: 登陆失败,用户名或者密码有错误

3.2 需求分析

在这里插入图片描述

3.3 代码实现

  1. 首先创建一个mavenweb项目

  2. 然后我们要实现准备好一个登录的html,druid的配置文件(放在/main和/test的resources文件夹里面), JDBCUtils ,还有你的面对bug的斗志

    1. 看看我们的工具类长什么样子吧

      package com.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;
      
      /*
       * 连接池工具类
       * */
      public class JDBCUtils {
          private static DataSource ds;
      
          //我们这里来初始化连接池
          static {
              try {
                  Properties pro = new Properties();
                  InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
                  pro.load(is);
                  ds = DruidDataSourceFactory.createDataSource(pro);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
      
          //获取连接池对象
          public static DataSource getDatasource() {
              return ds;
          }
      
          //获取Connection对象
          public static Connection getConnection() throws SQLException {
              return ds.getConnection();
          }
      
      
      }
      
      
    2. 再来看看我们的pom.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
      
          <groupId>example</groupId>
          <artifactId>Login</artifactId>
          <version>1.0-SNAPSHOT</version>
          <name>Login</name>
          <packaging>war</packaging>
      
          <properties>
              <maven.compiler.target>1.8</maven.compiler.target>
              <maven.compiler.source>1.8</maven.compiler.source>
              <junit.version>5.7.1</junit.version>
          </properties>
      
          <dependencies>
              <dependency>
                  <groupId>javax.servlet</groupId>
                  <artifactId>javax.servlet-api</artifactId>
                  <version>4.0.1</version>
                  <scope>provided</scope>
              </dependency>
              <dependency>
                  <groupId>org.junit.jupiter</groupId>
                  <artifactId>junit-jupiter-api</artifactId>
                  <version>${junit.version}</version>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>org.junit.jupiter</groupId>
                  <artifactId>junit-jupiter-engine</artifactId>
                  <version>${junit.version}</version>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.12</version>
                  <scope>compile</scope>
              </dependency>
      
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>8.0.25</version>
              </dependency>
      
          </dependencies>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-war-plugin</artifactId>
                      <version>3.3.1</version>
                  </plugin>
              </plugins>
          </build>
      </project>
      
      
    3. 我们再看看html文件

      <form action="/Login_war_exploded/loginServlet" method="post">
                      <h2>邮箱账号登录</h2>
                      <input type="text" placeholder="请输入邮箱账号" autocomplete="off" name="username">
                      <input type="password" placeholder="请输入密码"  name="password">
                      <div class="third"><input type="checkbox">十天内免登录<span><a href="#">忘记密码?</a></span></div>
                      <input type="submit" value="&nbsp;">
                  </form>
      
  3. 封装一个数据库登录表的实体类,代码如下

    1. 	package com.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;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "id=" + id +
                      ", username='" + username + '\'' +
                      ", password='" + password + '\'' +
                      '}';
          }
      }
      
      
  4. 写一个登录方法的实现类

    1. package com.dao;
      
      
      import com.domain.User;
      import com.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());
      
      
          /**
           * 登录方法
           *
           * @param loginUser 只有用户名和密码
           * @return 包含用户的全部数据,没有就返回null
           */
          public User login(User loginUser) {
              try {
                  //        1 编写sql
                  String sql = "select * from user where username = ? AND password = ?";
      
                  //        2 调用query方法
                  User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class),
                          loginUser.getUsername(), loginUser.getPassword());
      
      
                  return user;
              } catch (DataAccessException e) {
                 e.printStackTrace();
                  return null;
              }
          }
      
      }
      
      
  5. 写一个测试类(注意运行这里的时候,我们的source是在src/test/resources文件夹下的)

    1. package com.test;
      
      import com.dao.UserDao;
      import com.domain.User;
      import org.junit.Test;
      
      public class UserDaoTest {
          @Test
          public void testLogin() {
      
              User user = new User();
              user.setUsername("admin");
              user.setPassword("123456");
      
              UserDao dao  = new UserDao();
      
              User login = dao.login(user);
      
              System.out.println(login);
          }
      
      }
      
      
  6. 测试成功之后,我们就可以开始搞Servlet类了,先来搞一个登录之后参数首先传到的一个的Servlet类

    1. package com.servlet;
      
      
      import com.dao.UserDao;
      import com.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 {
              //        2 获取请求参数
              String username = req.getParameter("username");
              String password = req.getParameter("password");
      //        3 封装user对象
              User user = new User();
              user.setUsername(username);
              user.setPassword(password);
      
      //        4 调用UserDao的login方法
              UserDao dao = new UserDao();
              User login = dao.login(user);
      
              System.out.println(login);
      
      //        5 判断login是否是空
              if (login == 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 {
      //        super.doPost(req, resp);
              //        1 设置编码
              req.setCharacterEncoding("utf-8");
      //        2 获取请求参数
              String username = req.getParameter("username");
              String password = req.getParameter("password");
      
      //        3 封装user对象
              User user = new User();
              user.setUsername(username);
              user.setPassword(password);
      
      //        4 调用UserDao的login方法
              UserDao dao = new UserDao();
              User login = dao.login(user);
      
              System.out.println(login);
      
      //        5 判断login是否是空
              if (login == null) {
                  //登录失败
                  req.getRequestDispatcher("/failServlet").forward(req, resp);
              } else {
                  //登录成功
                  //存储数据
                  req.setAttribute("user", user);
                  //转发
                  req.getRequestDispatcher("/successServlet").forward(req, resp);
              }
          }
      }
      
      
  7. 写一个登录成功的Servlet类

    1. package com.servlet;
      
      import com.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 {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      //        super.doGet(request, response);
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
              response.setContentType("text/html;charset=utf-8");
      
              //获取用户名
              User user = (User) request.getAttribute("user");
      
              if (user != null) {
                  response.getWriter().write("<h1>登录成功," + user.getUsername() + ",你真是个小机灵鬼!</h1>");
              }
          }
      }
      
      
  8. 最后再写一个登录失败的Sevlet类

    1. package com.servlet;
      
      import com.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 {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      //        super.doGet(request, response);
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
              response.setContentType("text/html;charset=utf-8");
      
              //获取用户名
              User user = (User) request.getAttribute("user");
      
              if (user != null) {
                  response.getWriter().write("<h1>登录成功," + user.getUsername() + ",你真是个小机灵鬼!</h1>");
              }
          }
      }
      
      

3.4 效果展示

登录页面

在这里插入图片描述

如果登录成功

在这里插入图片描述

登录失败

在这里插入图片描述

第四章 BeanUtils的基本使用

4.1 基本使用

上面的LoginServlet类中,我们发现有一段代码很麻烦,如下

//        2 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");

//        3 封装user对象
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

我们可以试想一下,如果表单提交的数据能有十几个,难道我们要调用十几次req.getParameter()和十几次setUsername()? 不可能,所以我们要寻找更好的办法

因此,org.apache.commons.beanutils.BeanUtils这个包就排上用场了

我们直接看看怎么用

 Map<String, String[]> parameterMap = req.getParameterMap();
 
User user = new User();

 try {
     BeanUtils.populate(user,parameterMap);
} catch (IllegalAccessException | InvocationTargetException e) {
     e.printStackTrace();
}

你没看错,就这三句话,懂得都懂

4.2 BeanUtils介绍

BeanUtils作用: 用于封装JavaBean的

首先,我们需要了解: 什么是JavaBean?

JavaBean: 标准的Java类 ,满足下列要求

  1. 类必须被public修饰
  2. 必须提供空参的构造方法
  3. 成员变量必须使用pricate修饰
  4. 提供公共setter和getter方法

JavaBean功能: 封装数据

BeanUtils的概念

BeanUtils操作的是类的属性

  1. 类的成员变量: 就是private修饰的那些沙雕东西
  2. 属性: setter和getter方法截取之后的产物
    1. 例如: getUsername()--> Username --> username

也就是说,一般情况下,属性和成员变量是一样的,除非你的getter和setter方法你少写了或者多写了一些很奇怪的东西

BeanUtils的方法
  1. setProperties(Obj obj,String name, String value):给Javabean实例对象设置属性

    1.  @Test
          public void test(){
              User user = new User();
      
              try {
                  BeanUtils.setProperty(user,"username","你爹");
                  BeanUtils.setProperty(user,"username","尼玛");
              } catch (IllegalAccessException | InvocationTargetException e) {
                  e.printStackTrace();
              }
              System.out.println(user);//User{id=0, username='尼玛', password='null'}
      
          }
      
  2. getProperties(Object obj,String name, String value):获取属性

    1.    @Test
          public void test(){
              User user = new User();
      
              try {
                  BeanUtils.setProperty(user,"username","你爹");
      
              } catch (IllegalAccessException | InvocationTargetException e) {
                  e.printStackTrace();
              }
      
              try {
                  System.out.println(BeanUtils.getProperty(user, "username"));//你爹
              } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                  e.printStackTrace();
              }
      
          }
      
  3. populate(Object obj ,Map map): 将map集合中的键值对信息,封装到对应的JavaBean对象中(重点掌握)

              BeanUtils.setProperty(user,"username","你爹");
               BeanUtils.setProperty(user,"username","尼玛");
           } catch (IllegalAccessException | InvocationTargetException e) {
               e.printStackTrace();
           }
           System.out.println(user);//User{id=0, username='尼玛', password='null'}
    
       }
    
    
    
  4. getProperties(Object obj,String name, String value):获取属性

    1.    @Test
          public void test(){
              User user = new User();
      
              try {
                  BeanUtils.setProperty(user,"username","你爹");
      
              } catch (IllegalAccessException | InvocationTargetException e) {
                  e.printStackTrace();
              }
      
              try {
                  System.out.println(BeanUtils.getProperty(user, "username"));//你爹
              } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                  e.printStackTrace();
              }
      
          }
      
  5. populate(Object obj ,Map map): 将map集合中的键值对信息,封装到对应的JavaBean对象中(重点掌握)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值