day13 --> (Servlet、HTTP、Request)

Servlet:

 1、概念

2、步骤

3、执行原理

4、生命原理

5、3.0以上的注解配置

6、体系结构

Servlet -- 接口

GenericServlet -- 抽象类 

将Servlet接口中的其他方法做了默认的空实现,只将service()方法作为抽象,将来定义Servlet类时,可以继承GenernicServlet,实现service()方法即可

HttpServlet --抽象类 【常用】:对HTTP协议的一种封装,简化操作

1、定义类继承HttpServlet

2、重写doGet/doPost方法

7、Servlet相关配置:

1、urlpattern : Servlet 访问路径可以定义多个:

@WebServlet({"/d4","/dd4","/ddd4"})

2、路径的定义规则:

1. /xxx

2. /xxx/xxx :多层路径,目录结构

3. *.do : 任意字符.do 【注意:没有斜杠!】

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协议中有9种请求方式,常用的有2种

GET :

1、请求参数在请求行中,在url后

2、请求的url长度有限制

3、不太安全

POST:

1、请求参数在请求体中

2、请求的url长度没有限制的

3、相对安全

2.请求头:

键值对格式 --> 请求头名称:请求头值

常见的请求头:

1.User-Agent : 浏览器告诉服务器,我(当前的请求)访问你使用的浏览器的版本信息

可以在服务器端获取改头的信息,解决浏览器的兼容性问题【火狐、谷歌、Edge】

2.Referer:http://localhost:8080/login.html : 浏览器告诉服务器,我(当前的请求)从哪里来

作用:

1、防盗链

2、统计工作

 

3.请求空行

空行,用于分割POST请求的请求头和请求体

4.请求体(正文)

GET方式没有请求体,用来封装Post请求消息的请求体

Request :

1、request对象和response对象的原理:

1. request 和 response 对象是由服务器创建的,我们仅作为使用者;

2. request 对象来获取请求消息,response对象来设置响应消息。

2、request对象的继承体系结构:

ServletRequest    -- 接口

|  继承

HttpServletRequest  --接口

|  实现

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:8080/day14/demo1【中华人民共和国】

6.获取协议及版本:HTTP/1.1

  String getProtocol()

7.获取客户机的IP地址:

  String getRemoteAddr()

2.获取请求头数据

方法:

String getHeader(String name) : 通过请求头的名称获取请求头的值

Enumeration<String> getHeaderNames() : 获取所有请求头的名称,补充:Enumeration可以当作一个迭代器使用

3.获取请求体数据

只有POST方式才有请求体,在请求体中封装了POST请求的请求参数

步骤:

1、获取流对象

BufferedReader getReader() : 获取字符输入流,只能操作字符数据

ServletInputStream getInputStream() : 获取字节输入流,可以操作所有类型数据 【文件上传】

2、从流对象中拿数据

2.【都常用】其他功能

1.获取请求参数通用方式

1.String getParameter(String name) : 根据参数名称获取参数值: username=zhangsan&password=123

2.String[ ] getParameterValues(String name) : 根据参数名称获取参数值的数组 : hobby=xx&hobby=yy&hobby=zz

3.Enumeration<String> getParameterNames() : 获取所有请求的参数名称

4.Map<String,String[ ]> getParameterMap() : 获取所有键值对的集合

中文乱码问题:

get方式 :tomcat 8 版本以上的get方式已经将乱码问题解决了

post方式:会乱码

解决

2.请求转发:一种在服务器内部的资源跳转的方式【从AServlet --> BServlet : 各个Servlet分工合作】

1、步骤:

1.通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path) 

2.使用RequestDispatcher来进行转发:forward(ServletRequest request,ServletResponse response)

2、特点:

1.浏览器地址栏路径没有发生变化

2.只能转发到当前服务器的内部资源中

3.转发是一次请求【如下图,并没有requestDemo9的资源,但是在控制台中可以看到requestDemo9的确是被访问到了】

3.共享数据:

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

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

方法:

1.void setAttribute(String name,Object obj) : 存储数据

2.Object getAttribute(String name) : 通过键来获取值

3.void removeAttribute(String name) : 通过键移除值

4.获取ServletContext对象:

ServletContext getServletContext()

案例:用户登录

用户登录案例需求:

  1. 编写login.html登录界面username & password 两个输入框
  2. 使用Druid数据库连接池技术,操作mysql,day14数据库中user表
  3. 使用JdbcTemplate技术封装JDBC
  4. 登录成功跳转到SuccessServlet展示:登录成成功!用户名,欢迎您
  5. 登录失败跳转到FailServlet展示:登录失败,用户名或者密码错误

步骤分析:

 

 开发步骤:

1、创建项目,导入html页面,配置文件,jar包

2、创建数据库环境

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
);

 

 3.创建一个包:cn.itcast.domain,创建User类

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.创建utils工具包,提供获取数据库连接池和获取连接Connection的方法

public class JDBCUtils{
    private static DataSource dataSource;

    static {
        //1.加载配置文件
        Properties properties = new Properties();
        InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //2.初始化数据库连接池对象
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //1、获取数据库连接池对象
    public static DataSource getDataSource(){
        return dataSource;
    }

    //2、获取连接Connection对象
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

} 

5.创建包cn.itcast.dao,创建类UserDao,提供login的方法

public class UserDao {

    //声明JDBCTemplate对象共用
    private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

    /*
     * 登录方法
     * @param loginUser 用户名+密码
     * @return 包含用户全部数据
     */
    public User login(User loginUser) {
        try {
            //定义sql
            String sql = "select * from user where username = ? and password = ?";
            //执行sql
            User user = jdbcTemplate.queryForObject(sql,
                    new BeanPropertyRowMapper<>(User.class),
                    loginUser.getUsername(), loginUser.getPassword());
            return user;
        } catch (DataAccessException e) {
            return null;
        }
    }
}

 

 6.创建cn.itcast.web.servlet.LoginServlet类

7.login.html中form表单的action路径的写法:

虚拟目录 + Servlet的资源路径

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码格式
        req.setCharacterEncoding("utf-8");
        //根据参数名称获取参数值
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //创建对象封装数据
        User loginUser = new User();
        loginUser.setUsername(username);
        loginUser.setPassword(password);
        //调用dao包下的登录验证方法
        UserDao userDao = new UserDao();
        User user = userDao.login(loginUser);
        if (user == null){
            //登录失败
            req.getRequestDispatcher("/failServlet").forward(req,resp);
        }else {
            //登录成功
            //1、保存用户数据
            req.setAttribute("user",user);
            //2、转发
            req.getRequestDispatcher("/successServlet").forward(req,resp);
        }
    }
}

 

 FailServlet :

@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("登录失败,用户名或者密码错误");
    }
}

 

 SuccessServlet :

@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置(页面)编码
        response.setContentType("text/html;charset=utf-8");
        //1.获取用户数据
        User user = (User) request.getAttribute("user");
        response.getWriter().write("登录成成功!" + user.getUsername() + ",欢迎您");
    }
}

 

 8.BeanUtils的基本使用:

导入 commons-beanutils-1.8.0.jar 包,注释部分可被替换:

 

 BeanUtils工具类的简单介绍:

作用:封装JavaBean,简化数据封装

JavaBean:标准的Java类要求:

1.类必须被public修饰

2.必须提供空参的构造器

3.成员变量必须使用private修饰

4.提供公共setter和getter方法

功能:封装数据

概念:

成员变量:

属性:setter和getter方法截取后的产物,

例如:getUsername() -- > Username --> username

 

 

posted @ 2022-11-07 19:08  羽梦齐飞  阅读(22)  评论(0编辑  收藏  举报