JavaWeb学习的第十二天(Servlet_HTTP协议_HttpServletRequest的学习_登录案例的演示)

一、Servlet的学习

1.tomcat的本质:接收请求、处理请求和响应数据
2.学习Servlet的前提

1.1	Servlet不是由我们去启动的,而是一些动态资源,最终这些资源会放到tomcat上,由tomcat去找这些资源并处理,不需要我们自己去启动和干涉
1.2 Servlet是针对不同的请求进行不同的处理

3.Servlet作用:是用来处理请求的
4.Servlet的执行流程

http://localhost:8080/day01/web,根据虚拟路径/day01去定位到具体的项目,再根据具体要请求的资源/web,去web.xml里面找
配置了一个servlet和一个servlet-mapping去找到对应的url-pattern,然后再找serlvet-name,然后再定位到具体的Servlet的全限定类名


5.Servlet的生命周期

5.1 对象的生命周期:对象创建到销毁的过程
5.2 生命周期方法:init:对象创建之后立马会执行; destroy:Servlet对象被销毁之前调用--对象都没有了何谈调用方法;处理用户请求的方法Service()
	Servlet的创建:Servlet默认情况下是在用户第一次去请求这个Servlet的时候创建,Servlet创建的时候会执行init方法(init方法只会被执行一次),Servlet对象只会被创建一次
	Servlet的处理请求:用户的每一次请求都会(创建新的线程--会使用线程池)执行Servlet的service方法处理请求,处理请求的代码一定是多线程的代码,只不过不需要我们去关注这些多线程,我们写的代码只是一些资源,由tomcat帮我们执行
	Servlet的销毁:关闭tomcat服务器的时候,Servlet会被销毁,并且销毁的时候执行destroy方法
结论:Servlet对象是一个单例对象,只会被创建一次

5.3 多个人怎么同时去访问同一个Servlet资源??
    每一次用户请求唯一对应着服务器里面的一个线程,那么服务器的线程会非常多--会出现服务器的性能优化...

5.4 细节:Servlet的创建时机除了默认情况还有哪些情况 value="/web" loadOnstartup=-1
    value="/web" loadOnstartup=-1  默认情况 Servlet会在用户第一次请求的时候创建
    loadOnstartup=正整数(最好不要去配0) Servlet会在服务器启动的时候创建
    除了注解,还可以在web.xml中的<servlet><load-on-startup>1</load-on-startup></servlet>
    tomcat在启动的时候会加载的一些配置信息<init-param><param-name>-role <param-vale>-admin </init-param> 在init里面去调用这个方法servletconfig.getInitParameter("role");获取创建时的一些配置信息

二、HTTP协议的学习

1.HTTP到底是用来干什么的??---规范浏览器和服务器交互的消息格式
2.HTTP协议(超文本传输协议)是基于TCP协议,HTTP在传输数据之前先要建立安全连接
3.HTTP协议有不同的版本(三个版本) http1.0 http1.1(现在一般用的是这种) http2.0

HTTP相对于TCP而言会自动关闭连接
1.0:客户端发送请求到服务器,建立连接,传输数据,关闭连接,浏览器展示数据
1.1:客户端发送请求到服务器,建立连接(连接可复用),进行多次的数据传输,关闭连接,浏览器展示数据
2.0:由于http2.0还没有普及开来,所以暂时不做考虑

4.HTTP协议的默认端口是80,HTTP是无连接的,HTTP是无状态的(没有记忆能力,下一次数据传输和上一次数据传输之间没有联系)
5.HTTP协议多次请求之间无法共享数据
6.传输过程中数据格式的问题:

1.HTTP协议是基于请求/响应模型(一旦建立连接,一次请求必须对应唯一的一次响应)
2.默认端口 80
3.无状态的协议(每次请求之间相互独立,不能共享数据)
4.基于TCP/IP协议的一个安全协议(不是https的安全)数据只要正确的传输就是安全的
5.格式要求:
	http请求的消息格式:
	get请求:只包含请求行和请求头
	    请求行 请求方式/请求资源路径/协议版本
	    请求头:键值对
	    请求参数会拼接到请求行的资源路径后缀/web?username=张三&password=12345
	get请求会把请求参数放在地址栏上
	
	post请求的消息格式:
	post请求:除了请求行、请求头还包含请求体
	    请求行 请求方式/请求资源路径/协议版本
	    请求头:键值对
	    请求体:post请求的请求参数是放在请求体中




7.get请求和post请求的区别

1.get请求的请求参数是放在浏览器地址栏中提交的
  post请求的请求参数是放在请求体中
2.get请求相对安全,post请求相对安全
3.get请求提交的请求数据大小有限制(1Kb),post请求没有大小限制

8.tomcat接收到请求的第一件事情

接收客户端所有数据,并且把这些数据封装成对象Request对象,返回数据,使用封装好的Response对象,设置响应数据
浏览器中展示的都是响应体的内容

9.HTTP请求方法有九种,但是HTTPServlet只实现了七种,但是我们只学习其中的get和post请求



10.tomcat调用Servlet处理请求的完整过程

1.浏览器通过get/post向服务器发送请求
2.服务器接收请求,并且创建代表请求的Request对象和代表响应的Response对象
3.tomcat会根据请求的路径去找到对应的Servlet(路径匹配的过程),执行Servlet的生命周期,然后执行servlet的service方法
4.tomcat将代表请求的request对象和代表响应的Response对象作为参数传递到service方法中
5.在servlet的service方法中通过request对象获取客户端传过来的数据,处理业务逻辑,通过response设置响应数据

11.一次请求---一个request对象---一个线程

三、HttpServletRequest的学习

1.request对象有什么样的功能??

1.获取客户端传过来的三部分信息
	请求行:请求方式/请求资源路径/请求协议
	   request.getMethod();/获取请求方式
	   getRequestURL().toString();/获取请求资源路径 协议+主机+端口+URI
	   getRequestURI();/获取请求资源路径
	   getProtocol();/获取请求协议
	   getQueryString();/获取请求参数(只能在get请求上面用)
	请求头:一般是浏览器告诉服务器本次请求的基本信息
	   getHeader("Host");/主机
	 **getHeader("User-Agent");/告诉服务器本次请求的浏览器版本信息(兼容/电脑/手机)
	   getHeader("Accept");/告诉服务器本次请求的数据的格式 text/html/xml
	   getHeader("Accept-language"); /支持的语言
	   getHeader("Accept-Encoding"); /支持的压缩格式
	 **getHeader("Referer"); /告诉服务器本次请求的来源(防盗链) http://localhost:8080/
	   getHeader("Connection");/HTTP1.1 支持长连接 keep-alive
	post请求的请求体:
	   getInputStream();/获取请求体的字节输入流
	   getReader();/获取请求体的字符输入流
	   rs.readline();/读取一行信息
	   username=root&password=123
缺点:request在获取请求参数的时候由于get请求和post请求参数所在的位置不一样,所以导致get请求和post请求的处理代码也不一样

2.HttpServletRequest对象中又给我们封装了一些统一的方便的获取请求参数相关的方法

解决get和post代码有差异的问题,httpservletRequest对get和post都适用(方法一致)
	request.getParameter("username"); /root
	request.getParameter("password"); /123
	getParameterValues("hobby");  /主要利用在多选框上面,一个名字对应多个值
	getParameterMap();/一次性获取所有请求参数,然后遍历map集合  map的key是请求参数名称 value是请求参数值对应的数组
	getParameterNames(); /获取名称 hasMoreElements/判断  nextElement()/遍历获取名称

3.乱码问题:当我们输入中文的时候,get请求没问题,post请求的时候服务器显示的时候是乱码

post请求中文乱码问题解决方法:
    设置request缓冲区的编码 setCharacterEncoding("utf-8");/在获取请求参数之前设置编码格式

tomcat8.5之前的get请求中文乱码问题解决方法:
    get请求中文乱码问题在tomcat8.5之后自动解决,在tomcat8.5之前会有乱码问题,get请求的请求参数是在请求行中提交过去
    http协议本身不支持中文,由协议本身决定的 "编译"-->URLEncoding格式--%E7%94...(16进制) tomcat默认设置的编码-ISO-8859-1,然后我们再用utf-8去解肯定不行
    标题-utf-8-二进制-ISO-8859-1-????-ISO-8859-1(反向设置)-二进制-utf-8-标题
    1.代码解决
        byte[] bytes=username.getBytes("ISO-8859-1");/数组
        username=new String(bytes,"utf-8");/这样就不会出现乱码问题了
    2.指定tomcat的编码
        找到tomcat/config/server.xml,将默认的ISO-8859-1的方式改成URIEncoding="utf-8"

4.请求/资源的转发

作用:资源跳转的一种方式 request得到转发器,然后调用方法进行请求转发
	request.getRequestDispatcher("/success.html").forward(request,response);
业务场景:客户端发送请求,请求服务器某一个资源的时候,这个资源处理不了请求,然后再把请求交给其它资源处理
特点:
    浏览器只会发生了一次请求
    浏览器地址栏不会发生变化
    请求转发的时候只能跳转到服务器内容资源

四、利用tomcat+druid+servlet+bootstrap实现登录案例

1.在IDEA上集成tomcat---至于如何集成在博主上一篇文章中有详细的说明!!
2.创建一个web项目--day01


3.将bootstrap的三个文件夹css/fonts/js拷贝到web文件夹下

链接:https://pan.baidu.com/s/13bkr-kW6sJPVhzbEvqpD5A 
提取码:rf9x


4.删除index,jsp,在web目录下新建一个index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Bootstrap 101 Template</title>
    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
    <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html5shiv.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dest/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div class="container">
    <br>
    <hr width="50%">
    <form class="form-horizontal" action="/day01/web" method="post">
        <div class="form-group">
            <label for="username" class="col-sm-4 control-label">请输入用户名</label>
            <div class="col-sm-3">
                <input type="text" class="form-control" id="username" name="username">
            </div>
        </div>
        <div class="form-group">
            <label for="password" class="col-sm-4 control-label">请输入密码</label>
            <div class="col-sm-3">
                <input type="password" class="form-control" id="password" name="password">
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-4 col-sm-10">
                <button type="submit" class="btn btn-default">登录</button>
            </div>
        </div>
    </form>
    <hr width="50%">
</div>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
</body>
</html>

5.在src下新建如下的一些包

dao--用来处理一些操作的包
domain--用来创建一个对象用来封装数据库的参数
servlet--用来处理浏览器传来的请求
util--处理数据库操作的工具类


6.在servlet新建一个ServletDemo3

package com.bianyiit.servlet;

import com.bianyiit.dao.StudentDao;

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("/web")
public class ServletDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收get请求并处理
       doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收post请求并处理
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        boolean login = false;
        StudentDao dao=new StudentDao();
        login = dao.findByUsernameAndPassword(username, password);
        //进行判断
        if(login){
            //resp.setContentType("text/html;charset=UTF-8");
            //resp.getWriter().write("登录成功");
            resp.sendRedirect("/day01/study01.html");
        }else{
            /*resp.setContentType("text/html;charset=UTF-8");
            resp.getWriter().write("登录失败");*/
            resp.sendRedirect("/day01/study02.html");
        }
    }
}

7.在WEB-INF目录下新建一个lib文件夹(记住只能名为lib),导入一个数据库驱动jar包,两个druid数据库连接池jar包,四个spring对jdbc封装的jar包

链接:https://pan.baidu.com/s/1LzoXblcTQedtnx57aahtdw 
提取码:mkr1


8.添加jar包的依赖


9.在src下创建druid.properties配置文件,在配置文件中录入如下信息

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/login
username=root
password=123
#初始化时连接池中连接对象的个数
initialSize=5
#最大的连接对象的个数
maxActive=10
#超时时间(延迟三秒报错)
maxWait=3000

10.在util包下新建一个工具类--DruidUtils

package com.bianyiit.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

//Druid连接池的工具类
/*
 * 1.获取连接池对象
 * 2.获取连接对象
 * 3.归还连接对象的方法
 * 4.静态代码块(因为在创建连接池对象之前就需要加载好配置文件中的所有信息)
 * */
public class DruidUtils {
    private static DataSource ds;
    //用来加载配置文件并创建好一个连接池对象
    static {
        Properties ps=new Properties();
        try {
            ps.load(DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            ds = DruidDataSourceFactory.createDataSource(ps);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接对象的方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
    //有没有必要提供一个获取连接池对象的方法??---框架中可能只需要连接池对象,不需要连接对象
    public static DataSource getDataSource(){
        return ds;
    }
    //归还连接对象的方法
    //有一种是有结果集的连接(查询),
    public static void close(PreparedStatement psmt, Connection con, ResultSet rs){
        try {
            if(psmt!=null){
                psmt.close();
                psmt=null;
            }
            if(con!=null){
                con.close();
                con=null;
            }
            if(rs!=null){
                rs.close();
                rs=null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    //有一种没有结果集的连接(增删改)
    public static void close(PreparedStatement psmt, Connection con){
        try {
            if(psmt!=null){
                psmt.close();
                psmt=null;
            }
            if(con!=null){
                con.close();
                con=null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

11.在domian包下创建一个Student类

package com.bianyiit.domain;

public class Student {
    private String username;
    private String password;

    public Student() {
    }

    public Student(String username, String password) {
        this.username = username;
        this.password = password;
    }

    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 "Student{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

12.在dao包下创建一个StudentDao类

package com.bianyiit.dao;

import com.bianyiit.domain.Student;
import com.bianyiit.util.DruidUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.util.List;

//data Access object
public class StudentDao {
    public boolean findByUsernameAndPassword(String username,String password){
        //创建ds对象
        DataSource ds = DruidUtils.getDataSource();
        //2.创建用于简化sql语句的JDBCTemplate对象,必须依赖于连接池对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
        //定义一个sql语句
        String sql = "SELECT * from message where username=? and password=?";
        //执行sql语句
        List<Student> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Student>(Student.class),username,password);
        if(list==null || list.size() ==0){
            return false;
        }else{
            return true;
        }
    }
}

13.在web目录下创建两个html文件--study01.html和study02.html,里面分别写入登录成功和登录失败

14.开启IDEA将项目发布到tomcat上

15.tomcat启动成功之后会自动打开浏览器,随之进行浏览器的结果演示
index.html的默认登录界面

登录成功之后的页面

登录失败之后的页面

16.tomcat启动成功之后的控制台的结果演示

17.整个项目的结构目录如下所示

18.数据库中的message表中数据

19.源码分享

链接:https://pan.baidu.com/s/1da3YrmPvwLzZJaTRwGFFpg 
提取码:szp9
发布了73 篇原创文章 · 获赞 11 · 访问量 2442

猜你喜欢

转载自blog.csdn.net/weixin_43908333/article/details/103703928
今日推荐