Ego的JavaWeb笔记

JDBC

概念:Java Database Connectivity ,Java数据库连接,即Java语言操作数据库

JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

步骤

  1. 导入驱动jar包
  2. 注册驱动
  3. 获取数据库连接对象 Connection
  4. 定义sql
  5. 获取执行sql语句的对象 Statement
  6. 执行sql,接收返回结果
  7. 处理结果
  8. 释放资源
import java.sql.*;

/**
 * @Author: 2019012364 袁梦达 3班
 */
public class JdbcDemo01 {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf-8&useSSL=false", "root", "root");
            String sql = "insert into account values(5, 'ego', 2000)";
            statement = connection.createStatement();
            int count = statement.executeUpdate(sql);
            System.out.println(count);
            if(count > 0){
                System.out.println("打印成功!");
            }else {
                System.out.println("打印失败!");
            }
        } catch (ClassNotFoundException classNotFoundException) {
            classNotFoundException.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }

}

DriverManager:驱动管理对象

功能:

  1. 注册驱动:告诉程序该使用哪一个数据库驱动jar

    static void registerDriver(Driver driver):注册与给定的驱动程序DriverManager

    写代码使用:Class.forName(“com.mysql.jdbc.Driver”);

    因为com.mysql.jdbc.Driver类中存在静态代码块

    static {
            try {
                DriverManager.registerDriver(new Driver());
            } catch (SQLException var1) {
                throw new RuntimeException("Can't register driver!");
            }
        }
    

    注意:mysql5之后的驱动jar包可以省略注册驱动的步骤

  2. 获取数据库连接

    方法:static Connection getConnection(String url, String user, String password)

    参数:

    • url:指定连接的路径

      语法:jdbc:mysql://ip地址(域名):端口号/数据库名称

      例子:jdbc:mysql://localhost:3306/db3

      细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则可以简写为jdbc:mysql:///数据库名称

    • user:用户名

    • password:密码

Connection:数据库连接对象

功能:

  1. 获取执行sql对象
    • Statement createStatement( )
    • PreparedStatement preparedStatement(String sql)
  2. 管理事务
    • 开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
    • 提交事务:commit( )
    • 回滚事务:rollback( )

Statement:执行sql的对象

功能:

执行sql:

  • boolean execute(String sql):可以执行任意的sql

  • int executeUpdate(String sql):执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句

    返回值:影响的行数,可以通过影响的行数判断DML是否执行成功

  • ResultSet executeQuery(String sql):执行DQL(select)语句

ResultSet:结果集对象

  • boolean next( ):游标向下移动一行

  • getXxx( 参数):获取数据,Xxx代表数据类型

    参数:

    1. int:代表列的编号,从1开始
    2. String:代表列的名称
import java.sql.*;

/**
 * @Author: 2019012364 袁梦达 3班
 */
public class JdbcDemo01 {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf-8&useSSL=false", "root", "root");
            String sql = "select * from account";
            statement = connection.createStatement();
            rs = statement.executeQuery(sql);
            rs.next();
            int id = rs.getInt("id");
            String name = rs.getString("name");
            int money = rs.getInt("money");
            System.out.println(id + "----" + name + "-----" + money);
        } catch (ClassNotFoundException classNotFoundException) {
            classNotFoundException.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }

}

PreparedStatement:执行sql的对象

  1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题

    例如:随便输入用户名,密码输入’a’ or ‘a’ = ‘a’,则sql语句为:select * from user where username = ‘fdsff’ and password = ‘a’ or ‘a’ = ‘a’

  2. 解决sql注入问题:使用PreparedStatement对象

  3. 预编译的SQL:参数使用?作为占位符

  4. 步骤:

    1. 导入驱动jar包

    2. 注册驱动

    3. 获取数据库连接对象 Connection

    4. 定义sql

      • 注意:sql的参数使用?作为占位符。如:select * from user where username = ? and password = ?
    5. 获取执行sql语句的对象 PreparedStatement:Connection.preparedStatement(String sql)

    6. 给?赋值

      方法:setXxx(参数1, 参数2)

      参数1:?的位置编号,从1开始

      参数2:?的值

    7. 执行sql,接收返回结果,不需要传递sql语句

    8. 处理结果

    9. 释放资源

JDBC工具类

目的:抽取共性方法,简化书写

import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;

/**
 * @Author: 2019012364 袁梦达 3班
 */
public class JDBCUtils {
    private static String url;
    private static String user;
    private static String password;
    private static String driver;

    /**
     * 文件的读取,只需执行一次即可拿到这些值,使用静态代码块
     */
    static {
        //读取资源文件获取值

        try{
            //1.创建Properties集合
            Properties pro = new Properties();
            //获取src路径下文件的方式----ClassLoader类加载器
            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
            URL resource = classLoader.getResource("jdbc.properties");
            String path = resource.getPath();

            //2.加载文件
            pro.load(new FileReader(path));

            //3.获取数据,赋值
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");

            //4.注册驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取连接
     * @return 连接对象
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    /**
     * 释放资源
     * @param stmt
     * @param conn
     */
    public static void close(Statement stmt, Connection conn){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    /**
     * 释放资源
     * @param stmt
     * @param conn
     * @param rs
     */
    public static void close(Statement stmt, Connection conn, ResultSet rs){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

import java.sql.*;

/**
 * @Author: 2019012364 袁梦达 3班
 */
public class JdbcDemo01 {
    public static void main(String[] args) {
        Connection conn= null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "select * from account";
            statement = conn.createStatement();
            rs = statement.executeQuery(sql);
            while (rs.next()){
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int money = rs.getInt("money");
                System.out.println(id + "----" + name + "-----" + money);
            }

        }catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JDBCUtils.close(statement, conn, rs);
        }
    }

}

数据库连接池

概念

其实就是一个容器(集合),存放数据库连接的容器。

当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户访问数据库时,从容器中获取连接对象用户访问完之后,会将连接对象归还给容器。

好处:节约资源,用户访问高效

实现

  1. 标准接口:DataSource javax.sql包下的

    方法:

    1. 获取连接:getConnection( )
    2. 归还连接:Connection.close( )。如果连接对象Connection是从连接池中获取的,那么调用close( )方法不会关闭连接,而是归还连接
  2. 一般我们不去实现它,由数据库厂商来实现

    1. C3P0:数据库连接池技术
    2. Druid:数据库连接池实现技术,由阿里巴巴提供

C3P0

步骤:

  1. 导入jar包
  2. 定义配置文件:
    • 名称:c3p0.properties 或者 c3p0-config.xml
    • 路径:直接将文件放在src目录下即可
  3. 创建核心对象:数据库连接池对象 ComboPooledDataSource
  4. 获取连接:getConnection

Druid

步骤:

  1. 导入jar包
  2. 定义配置文件:
    1. 是properties形式的
    2. 可以叫任意名称,可以放在任意目录下
  3. 加载配置文件
  4. 获取数据库连接池对象:通过工厂类来获取 DruidDataSourceFactory
  5. 获取连接:getConnection
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

/**
 * @Author: 2019012364 袁梦达 3班
 */
public class DruidDemo {
    public static void main(String[] args) throws Exception {
        //1.加载配置文件
        Properties pro = new Properties();
        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);

        //2.获取数据库连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);

        //3.获取连接
        Connection conn = ds.getConnection();
        System.out.println(conn);
    }
}

Druid连接池工具类

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @Author: 2019012364 袁梦达 3班
 */
public class DruidUtils {
    private static DataSource ds;

    static {
        try {
            //1.加载配置文件
            Properties pro = new Properties();
            pro.load(DruidUtils.class.getClassLoader().getResourceAsStream("druid.propertis"));
            //2.获取DataSource
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    /**
     * 释放资源
     */
    public static void close(Statement stmt, Connection conn){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    public static void close(Statement stmt, Connection conn, ResultSet rs){
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    /**
     * 获取连接池
     */
    public static  DataSource getDataSource(){
        return ds;
    }
}

JdbcTemplate

Spring框架对JDBC简单封装,提供了一个JdbcTemplate对象简化JDBC的开发

步骤:

  1. 导入jar包

  2. 创建JdbcTemplate对象,依赖于数据源DataSource

    JdbcTemplate template = new JdbcTemplate(ds);

  3. 使用JdbcTemplate方法来完成CRUD的操作

    • update( ):执行DML(增删改)语句

    • queryForMap( ):查询结果将结果集封装为map集合。将列名作为key,将值作为value。注意:这个方法查询的结果集长度只能是1,即只能查询一行

    • queryForList( ):查询结果将结果集封装为list集合。将每一条记录封装为一个Map集合,再将Map集合装载到List集合中

    • query( ):查询结果将结果封装为JavaBean对象。

      query参数:RowMapper

      ​ 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装。

      ​ new BeanPropertyRowMapper<类名>(类名.class)

    • queryForObject( ):查询结果将结果封装为对象

      一般用于聚合函数的查询

XML

概述

  1. 概念:Extensible Markup Langu 可扩展标记语言

    可扩展:标签都是自定义的。

  2. 功能:

    存储数据

    1. 配置文件
    2. 在网络中传输
  3. 与html的区别:

    1. xml标签都是自定义的,html标签都是预定义的
    2. xml语法严格,html语法松散
    3. xml是存储数据的,html是展示数据的

语法

  • 基本语法

    1. xml文档的后缀名 .xml
    2. xml第一行必须定义为文档声明
    3. xml文档中有且仅有一个根标签
    4. 属性值必须使用引号(单双都可以)引起来
    5. 标签必须正确关闭
    6. xml标签名称区分大小写
  • 快速入门

    <?xml version='1.0' ?>
    <users>
    	<user id='1'>
    		<name>zhangsan</name>
    		<age>18</age>
    	</user>
    	<user id='2'>
    		<name>lisi</name>
    		<age>18</age>
    	</user>
    </users>
    
  • 组成部分

    1. 文档声明

      1. 格式:<?xml 属性列表 ?>

      2. 属性列表:

        1. version:版本号,必须写的属性

        2. encoding:编码方式。告知解析引擎当前文档使用的字符集,默认值:IOS-8859-1

        3. standalone:是否独立

          取值:

          ​ yes:不依赖其他文件

          ​ no:依赖其他文件

    2. 指令:结合CSS

      ​ <?xml-stylesheet type="text/css" href="a.css" ?>

    3. 标签:标签名称自定义的

      规则:

      1. 名称可以含字母、数字以及其他的字符
      2. 名称不能以数字或者标点符号开始
      3. 名称不能以字符 “xml”(或者 XML、Xml)开始
      4. 名称不能包含空格
    4. 属性:id属性值唯一

    5. 文本:

      CDATA区:在该区域中的数据会被原样展示

      格式:<![CDATA[ 数据 ]]>

    6. 文本

约束

概念:规定xml文档的书写规则

分类:

1. DTD:一种简单的约束技术
2. Schema:一种复杂的约束技术

DTD:

  • 引入dtd文档到xml文档中
    • 内部dtd:将约束规则定义在xml文档中
    • 外部dtd:将约束规则定义在外部的dtd文件中
      • 本地:
      • 网络:

解析

概念:操作xml文档,将文档中的数据读取到内存中

操作xml文档:

  1. 解析(读取):将文档中的数据读取到内存中
  2. 写入:将内存中的数据保存到xml文档中。持久化的存储

解析xml的方式:

  1. DOM:将标记语言文档一次性加载进内存,在内存中形成一颗DOM树

    优点:操作方便,可以对文档进行CRUD的所有操作

    缺点:占内存

  2. SAX:逐行读取,基于事件驱动的。

    优点:不占内存

    缺点:只能读取不能增删改

xml常见的解析器:

  1. JAXP:sun公司提供的解析器,支持dom和sax
  2. DOM4J:一款非常优秀的解析器
  3. Jsoup
  4. PULL:Android操作系统内置的解析器,sax方式
Jsoup

步骤:

  1. 导入jar包
  2. 获取Document对象
  3. 获取对应的标签(Element对象)
  4. 获取数据
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;

/**
 * @Author: 2019012364 袁梦达 3班
 */
public class JsoupDemo {
    public static void main(String[] args) throws IOException {
        String path = JsoupDemo.class.getClassLoader().getResource("a.xml").getPath();
        Document document = Jsoup.parse(new File(path), "GBK");
        Elements elements = document.getElementsByTag("name");
        Element element = elements.get(0);
        System.out.println(element.text());
    }
}

对象:

  1. Jsoup:工具类,可以解析html或xml文档,返回Document

    parse:解析html或xml文档,返回Document

    ​ parse(File in, String charsetName):解析xml或html文件

    ​ parse(String html):解析xml或html字符串

    ​ parse(URL url, int timeoutMillis):通过网络路径获取指定的html或xml的文档对象

  2. Document:文档对象。代表内存中的DOM树

    获取Element对象

    ​ getElementById(Stirng id):根据id属性值获取唯一的element对象

    ​ getElementByTag(String tagName):根据标签名获取元素对象集合

    ​ getElementByAttribute(String key):根据属性名获取元素对象集合

    ​ getElementByAttributeValue(String key,String value):根据属性名和shu’xing值获取元素对象集合

  3. Elements:元素Element对象的集合。可以当作ArrayList来使用

  4. Element:元素对象

    1. 获取子元素对象

      getElementById(Stirng id):根据id属性值获取唯一的element对象

      ​ getElementByTag(String tagName):根据标签名获取元素对象集合

      ​ getElementByAttribute(String key):根据属性名获取元素对象集合

      ​ getElementByAttributeValue(String key,String value):根据属性名和shu’xing值获取元素对象集合

    2. 获取属性值

      String attr(String key):根据属性名称获取属性值

    3. 获取文本内容

      String text( ):获取纯文本内容

      String html( ):获取标签体的所有内容(包括子标签的标签和文本内容)

  5. Node:节点对象

    是Document和Element的父类

快捷查询方式
  1. selector:选择器

    方法:Element select(String cssQuery)

    参数的语法和css的选择器一样

  2. XPath:

    1. JXDocument jxDocument = new JXDocument(document);

    2. 根据XPath语法查询。

Tomcat

服务器:安装了服务器软件的计算机

服务器软件:接收用户的请求,处理请求,做出响应

web服务器软件:接收用户的请求,处理请求,做出响应,可以部署web项目,让用户通过浏览器来访问这些项目

常见的java相关的web服务器软件:

  1. webLogic:oracle公司,大型的JavaEE服务器,支持所有JavaEE规范
  2. webSphere:IBM公司
  3. JBOSS:JBOSS公司
  4. Tomcat:Apache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范,开源的。

配置:

​ 部署项目的方式:

  1. 直接将项目放到webapps目录下即可

    简化部署:将项目打成一个war包,再将war包放置webapps目录下,war包会自动解压缩

    1. 配置conf\server.xml文件

    在标签体中配置

    docBase:项目存放的路径

    path:虚拟目录

    1. 在conf\Ctalina\localhost创建任意名称的xml文件。在文件中编写

    虚拟目录:xml文件的名称

java动态项目的目录结构:

​ --项目的根目录

​ --WEB-INF目录

​ --web.xml:web项目的核心配置文件

​ --classes目录:放置字节码文件的目录

​ --lib目录:放置依赖的jar包

Servlet

概念:全称server applet,运行在服务端的小程序。Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则

步骤:

  1. 创建JavaEE项目

  2. 定义一个类,实现Servlet接口

  3. 实现接口中的抽象方法

  4. 配置Servlet

    <servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>ServletDemo</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>
    

执行原理:

  1. 当服务器接收到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
  2. 查找web.xml文件是否有对应的标签体内容
  3. 如果有,则会找到对应的全类名
  4. tomcat会将字节码文件加载进内存,并且创建其对象
  5. 调用其方法

Servlet的生命周期

  1. 被创建:执行init方法,只执行一次

    Servlet什么时候被创建?

    • 默认情况下,第一次被访问时Servlet被创建

    • 可以配置执行Servlet的创建时机,在标签下配置

      1. 第一次被访问时创建

        的值为负数

      2. 在服务器启动时创建

        的值为0或正整数

    Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的

    • 多个用户同时访问时可能存在线程安全问题
    • 解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对其修改值
  2. 提供服务:执行service方法,执行多次

  3. 被销毁:执行destroy方法,只执行一次

    只有服务器正常关闭时,才会执行destroy方法(在Servlet被销毁前执行,释放资源)

Servlet3.0:

好处:支持注解配置,不需要web.xml

在类上使用@WebServlet注解,进行配置:@WebServlet(“资源路径”)

Servlet体系结构:

Servlet ---- 接口

​ |

GenericServlet ---- 抽象类

​ |

HttpServlet ---- 抽象类

  • GenericServlet:将Servlet接口中的其他方法做了默认的空实现,只将service( )方法作为抽象。

    将来定义Servlet类时,可以继承GenericServlet,实现service( )方法即可

  • HttpServlet:对Http协议的一种封装,简化操作

    1. 定义类继承HttpServlet
    2. 复写doGet/doPost方法

Servlet相关配置:

  1. urlpartten:Servlet访问路径
    1. 一个Servlet可以定义多个访问路径:@WebServlet({"/a", “/b”, “/c”})
    2. 路径定义规则:
      1. /xxx
      2. /xxx/xxx:多层路径,目录结构
      3. *.do

Request

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

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

    ServletRequest ---- 接口

    ​ | 继承

    HttpServletRequest ---- 接口

    ​ | 实现

    RequestFacade ---- 类(tomcat)

  3. request功能:

    1. 获取请求消息数据

      1. 获取请求行数据

        • GET /day14/demo?name=zhangsan HTTP/1.1

        • 方法:

          1. 获取请求方式:GET

            String getMethod( )

          2. 获取虚拟目录:/day14

            String getContextPath( )

          3. 后获取Servlet路径:/demo

            String getServletPath( )

          4. 获取get方式请求参数:name=zhansan

            String getQueryString( )

          5. 获取请求URI:

            String getRequestURI( ):/day14/demo

            StringBuffer getRequestURL( ): http://localhost/day14/demo

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

            String getProtocol( )

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

            String getRemoteAddr( )

      2. 获取请求头数据

        方法:

        1. String getHeader(String name):通过请求头的名称获取请求头的值
        2. Enumeration getHeaderNames( ):获取所有的请求头名称
      3. 获取请求体数据:

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

        步骤:

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

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

        1. String getParameter(String name):根据参数名称获取参数值
        2. String[ ] getParameterValues(String name):根据参数名称获取参数值的数组
        3. Enumertation getParameterNames( ):获取所有请求的参数名称
        4. Map<String , String[ ]> getParameterMap( ):获取所有参数的Map集合

        中文乱码问题:

        • get方式:tomcat 8已经将get方式乱码问题解决了

        • post方式:会乱码

          解决:在获取参数前,设置request的编码

          request.setCharacterEncoding(“utf-8d”)

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

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

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

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

        方法:

        1. setAttribute(String name, Object obj):存储数据
        2. getAttribute(String name):通过键获取值
        3. removeAttribute(String name):通过键移除键值对
      4. 获取ServletContext:

        1. 概念:代表整个web应用,可以和程序的容器(服务器)来通信

        2. 获取:

          1. 通过request对象获取:request.getServletContext( )
          2. 通过HttpServlet获取:this.getServletContext( )
        3. 功能:

          1. 获取MIME类型:

            MIME类型:在互联网通信过程中定义的一种文件类型数据

            格式:大类型/小类型 text/html image/jpeg

            获取:String getMimeType(String file)

          2. 域对象:共享数据

            1. setAttribute(String name, Object value)
            2. getAttribute(String name)
            3. removeAttribute(String name)

            ServletContext对象范围:所有用户所有请求数据

          3. 获取文件的真实(服务器)路径

            方法:String getRealPath(String path)

BeanUtils工具类,简化数据封装

  • 用于封装JavaBean

    1. JavaBean:标准的Java类

      1. 要求:
        1. 类必须被public修饰
        2. 必须提供空参的构造器
        3. 成员变量必须使用private修饰
        4. 提供公共的setter和getter方法
      2. 功能:封装数据
    2. 概念:

      成员变量

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

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

    3. 方法:

      1. setProperty( )
      2. getProperty( )
      3. populate(Object obj, Map map):将map集合的键值对信息,封装到对应的JavaBean对象中

Response

功能:设置响应消息

  1. 设置响应行

    1. 格式:HTTP/1.1 200 ok
    2. 设置状态码:setStatus(int sc)
  2. 设置响应头:setHeader(String name, String value)

  3. 设置响应体:

    使用步骤:

    1. 获取输出流

      字符输出流:PrintWriter getWriter( )

      字节输出流:ServletOutputStream getOutputStream( )

    2. 使用输出流将数据输出到客户浏览器

案例:

  1. 完成重定向:资源跳转的方式

    //        //访问Demo1,会自动跳转到Demo2
    //        System.out.println("Demo1......");
    //        //1.设置状态码302
    //        resp.setStatus(302);
    //        //设置响应头
    //        resp.setHeader("location", "/ResponseDemo2");
    
            //简化写法
            resp.sendRedirect("/ResponseDemo2");
    

    重定向的特点:

    1. 地址栏发生变化
    2. 重定向可以访问其他站点(服务器)的资源
    3. 重定向是两次请求,不可以使用request对象共享数据

    转发的特点:

    1. 转发地址栏路径不变
    2. 转发只能访问当前服务器下的资源
    3. 转发是一次请求,可以使用request对象共享数据

    路径写法:

    1. 路径的分类
      1. 相对路径
      2. 绝对路径:建议虚拟目录动态获取:request.getContextPath( )
  2. 服务器输出字符数据到浏览器

    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.io.PrintWriter;
    
    /**
     * @author 86156
     */
    @WebServlet("/ResponseDemo3")
    public class ResponseDemo3 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        //设置编码   可以不写
    //        resp.setCharacterEncoding("utf-8");
    
    //        //告诉浏览器编码,并建议浏览器使用该编码
    //        resp.setHeader("content-type", "text/html;charset=utf-8");
    
            //简化写法
            resp.setContentType("text/html;charset=utf-8");
    
            //获取字符输出流
            PrintWriter writer = resp.getWriter();
            //输出数据
            writer.write("你好Ego");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req, resp);
        }
    }
    
    
  3. 服务器输出字节数据到浏览器

    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    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.io.PrintWriter;
    
    /**
     * @author 86156
     */
    @WebServlet("/ResponseDemo4")
    public class ResponseDemo4 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html;charset=utf-8");
            ServletOutputStream os = resp.getOutputStream();
            os.write("你好Ego".getBytes("utf-8"));
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req, resp);
        }
    }
    
    
  4. 验证码

    import javax.imageio.ImageIO;
    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.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    
    @SuppressWarnings("all")
    /**
     * @author 86156
     */
    @WebServlet("/checkcode")
    public class CheckCode 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 {
    
            int height = 50;
            int width = 100;
    
            //1.创建图片对象
            BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    
            //2.美化图片
            //2.1填充背景色
            Graphics g = img.getGraphics(); //画笔对象
            g.setColor(Color.PINK); //设置画笔颜色
            g.fillRect(0, 0, width, height);
    
            //2.2画边框
            g.setColor(Color.BLUE);
            g.drawRect(0, 0, width - 1, height - 1);
    
            //2.3写验证码
            String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            Random random = new Random();
            for(int i = 1; i <= 4; i++){
                int index = random.nextInt(str.length());
                char ch = str.charAt(index);
                g.drawString(ch + "", width / 5 * i, height / 2);
            }
            //2.4画干扰线
            g.setColor(Color.GREEN);
            for(int i = 0; i < 10; i++){
                int x1 = random.nextInt(width);
                int x2 = random.nextInt(width);
                int y1 = random.nextInt(height);
                int y2 = random.nextInt(height);
                g.drawLine(x1, y1, x2, y2);
            }
    
            //3.输出到页面中
            ImageIO.write(img, "jpg", resp.getOutputStream());
        }
    }
    
    

##ServletContext

  1. 概念:代表整个web应用,可以和程序的容器(服务器)来通信

  2. 获取:

    1. 通过request对象获取:request.getServletContext( )
    2. 通过HttpServlet获取:this.getServletContext( )
  3. 功能:

    1. 获取MIME类型:

      MIME类型:在互联网通信过程中定义的一种文件类型数据

      格式:大类型/小类型 text/html image/jpeg

      获取:String getMimeType(String file)

    2. 域对象:共享数据

      1. setAttribute(String name, Object value)
      2. getAttribute(String name)
      3. removeAttribute(String name)

      ServletContext对象范围:所有用户所有请求数据

    3. 获取文件的真实(服务器)路径

      方法:String getRealPath(String path)

会话技术

  1. 会话:一次会话中包含多次请求和响应
    • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
  2. 功能:在一次会话的范围内多次请求间,共享数据
  3. 方式:
    1. 客户端会话技术:Cookie
    2. 服务器端会话技术:Session

Cookie

  1. 概念:客户端会话技术,将数据保存到客户端

  2. 步骤:

    1. 创建Cookie对象,绑定数据

      new Cookie(String name, String value)

    2. 发送Cookie对象

      response.addCookie(Cookie cookie)

    3. 获取Cookie,拿到数据

      Cookie[ ] request.getCookies( )

  3. 实现原理

    基于响应头set-cookie和请求头cookie实现

  4. cookie的细节

    1. 一次可不可以发送多个cookie?

      可以,可以创建多个Cookie对象,使用response多次调用addCookie发送即可

    2. cookie在浏览器中保存多长时间?

      1. 默认情况下,当浏览器关闭后,Cookie数据被销毁

      2. 持久化存储:

        setMaxAge(int seconds)

        seconds:

        1. 正数:将Cookie数据写到硬盘的文件中。持久化存储,数字表示存活时间
        2. 负数:默认值
        3. 零:删除cookie信息
    3. cookie能不能存中文?

      在tomcat 8之前 ,cookie不能直接存储中文数据

      ​ 需要将中文数据转码—一般采用URL编码

      在tomcat 8之后,cookie支持中文数据,但是特殊字符还是不支持,建议使用URL编码存储,URL解码解析

    4. cookie获取范围多大?

      1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?

        默认情况下cookie不能共享

        setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录。如果要共享,则可以将path设置为"/"

      2. 不同的tomcat服务器间cookie共享问题

        setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享

        如:setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享

  5. Cookie的特点和作用

    1. cookie存储数据在客户端浏览器
    2. 浏览器对于单个cookie的大小有限制(4kb),对同一个域名下的总cookie数量也有限制(20个)

    作用:

    1. cookie一般用于存储少量的不太敏感的数据
    2. 在不登录的情况下,完成服务器对客户端的身份识别

JSP入门

  1. 概念:Java Server Pages:Java服务器端页面

    可以理解为:一个特殊的页面,其中既可以指定定义HTML标签,又可以定义Java代码。

    用于简化书写。

  2. 原理:

    JSP本质上就是一个Servlet

  3. JSP的脚本:JSP定义Java代码的方式

    1. <% 代码 %>:定义的Java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么
    2. <%! 代码 %>:定义的Java代码,在jsp转换后的Java类的成员位置
    3. <%= 代码 %>:定义的Java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么
  4. JSP的内置对象

    一共有9个内置对象

    • request

    • response

    • out:字符输出流对象。可以将数据输出到页面上。和response.getWriter( )类似

      response.getWriter( )和out.writer( )区别:tomcat服务器做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。所以response.getWriter( )数据输出永远在out.writer( )之前

Session

  1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。

  2. 步骤:

    1. 获取HttpSession对象:

      HttpSession session = request.getSession( );

    2. 使用HttpSession对象:

      Object getAttribute(String name)
      void setAttribute(String name, Object value)

      void removeAttribute(String name)

  3. 原理:Session的实现是依赖于Cookie的

  4. 细节:

    1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?

      不是(默认情况下)。

      如果需要相同,则可以创建Cookie,键位JSESSIONID,设置最大存活时间,让cookie持久化保存

      Cookie c = new Cookie("JSESSIONID", session.getId());
      c.setMaxAge(60*60);
      response.addCookie(c);
      
    2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?

      不是。

      但是要确保数据不丢失,

      session的钝化:在服务器正常关闭之前,将session对象序列化到硬盘上

      session的活化:在服务器启动后,将session文件转化为内存中的session对象(反序列化)

    3. session的失效时间?

      1. 服务器关闭
      2. session对象调用invalidate( )
      3. session默认失效时间为30分钟
  5. session的特点:

    1. session用于存储一次会话的多次请求数据,存在服务器端
    2. session可以存储任意类型,任意大小的数据
  6. session与cookie的区别:

    1. session存储数据在服务器端,cookie在客户端
    2. session没有数据大小限制,cookie有限制
    3. session数据安全,cookie相对不安全

JSP进阶

  1. 指令

    作用:用于配置JSP页面,导入资源文件

    格式:

    <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 …%>

    分类:

    1. page :配置JSP页面

      • contentType:等同于response.setContentType( )
      1. 设置响应体的mime类型以及字符集
      2. 设置当前JSP页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
      • import:导包
      • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
      • isErrorPage:标识当前页面是否是错误页面
        • true:是,可以使用内置对象exception
        • false:否,默认值。不可以使用内置对象exception
    2. taglib:导入资源

      <%@taglib prefix="c" uri="" %>
      
    3. include:页面包含的。导入页面的资源文件

      <%@include file="demo2.jsp"%>
      
  2. 注释

    1. HTML注释:

      :只能注释HTML代码片段
    2. JSP注释:

      <%-- --%>:可以注释所有

  3. 内置对象

    在JSP页面中不需要创建,直接使用的对象

    一共有9个:

    ​ 变量名 真实类型 作用

    • pageContext PageContext 当前页面共享数据
    • request HttpServletRequest 一次请求访问的多个资源(转发)
    • session HttpSession 一次会话的多个请求间
    • application ServletContext 所有用户间共享数据
    • response HttpServletResponse 响应对象
    • page Object 当前页面(Servlet)的对象 this
    • out JspWriter 输出对象,数据输出到页面上
    • config ServletConfig Servlet的配置对象
    • exception Throwable 异常对象

MVC开发模式

  1. MVC:

    1. M:Model,模型。JavaBean
      • 完成具体的业务操作,如:查询数据库,封装对象
    2. V:View,视图。JSP
      • 展示数据
    3. C:Controller,控制器。Servlet
      • 获取用户的输入
      • 调用模型
      • 将数据交给视图进行展示

    优点:

    1. 耦合性低,方便维护,利于分工协作
    2. 重用性高

    缺点:使得项目架构变得复杂,对开发人员要求高

EL表达式

  1. 概念:Expression Language 表达式语言

  2. 作用:替换和简化jsp页面中Java代码的编写

  3. 语法:${ 表达式 }

  4. 注意:jsp默认支持EL表达式,如果要忽略EL表达式

    1. 设置JSP中page指令:isELIgnored=“true” 忽略当前jsp页面中有所的EL表达式
    2. \${ 表达式 }:忽略当前这个EL表达式
  5. 使用:

    1. 运算

      运算符:

      1. 算数运算符: + - * /(div) %(mod)

      2. 比较运算符: > < >= <= == !=

      3. 逻辑运算符:&&(and) ||(or) !(not)

      4. 空运算符:empty

        功能:用于判断字符串、集合、数组对象是否为null或长度是否为0

    2. 获取值

      1. EL表达式只能从域对象中获取值

      2. 语法:

        1. ${域名称.键名}:从指定域中获取指定键的值

          域名称:

          1. pageScope --> pageContext
          2. requestScope --> request
          3. sessionScope --> session
          4. applicationScope --> application(ServletContext)
        2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止

        3. 获取对象、List集合、Map集合的值

          1. 对象:${域名称.键名.属性名}

            本质上会调用对象的getter方法

          2. List集合:${域名称.键名[索引]}

          3. Map集合:

            ${域名称.键名.key名称}

            ${域名称.键名[“key名称”]}

    3. 隐式对象:

      EL表达式有11个隐式对象

      pageContext:

      ​ 获取jsp其他8个内置对象

      ​ ${pageContext.request.contextPath}:动态获取虚拟目录

      Filter过滤器

###概念

web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能

过滤器的作用:

  • 一般用于完成通用的操作。如:登陆验证,统一编码处理,敏感字符过滤…

快速入门

  1. 定义一个类,实现接口Filter
  2. 复写方法
  3. 配置拦截路径
    • web.xml
    • 注解
package com.ego.filter;


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器执行.....");

        //放行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

过滤器细节

  1. web.xml配置

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        <filter>
            <filter-name>demo1</filter-name>
            <filter-class>com.ego.filter.FilterDemo</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>demo1</filter-name>
            <!--拦截路径-->
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    </web-app>
    
  2. 过滤器执行流程

    执行过滤器上的语句,然后访问资源,回来时执行过滤器下的语句

  3. 过滤器生命周期方法

    1. init:在服务器启动时,会创建Filter对象,然后调用init方法。只执行一次,用于加载资源
    2. doFilter:每一次请求被拦截资源时,会执行。执行多次
    3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器正常关闭,则会执行destroy方法。只执行一次,用于释放资源
  4. 过滤器配置详解

    1. 拦截路径配置:

      1. 具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会执行
      2. 拦截目录:/user/* 访问/user下的所有资源时,过滤器都会被执行
      3. 后缀名拦截:*.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
      4. 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
    2. 拦截方式配置:资源被访问的方式

      • 注解配置:

        设置dispatcherTypes属性:

        1. REQUEST:默认值。浏览器直接请求资源
        2. FORWARD:转发访问资源
        3. INCLUDE:包含访问资源
        4. ERROR:错误跳转资源
        5. ASYNC:异步访问资源
      • web.xml配置

        设置标签即可

  5. 过滤器链(配置多个过滤器)

    执行顺序:如果有两个过滤器

    1. 过滤器1
    2. 过滤器2
    3. 资源执行
    4. 过滤器2
    5. 过滤器1

    过滤器先后顺序问题:

    1. 注解配置:按照类名的字符串比较规则比较,值小的先执行

      如:AFilter和BFilter,AFilter先执行

    2. web.xml配置:谁定义在上边,谁先执行

Listener监听器

事件监听机制

  • 事件:一件事情
  • 事件源:事件发生的地方
  • 监听器:一个对象
  • 注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生某个事件时,执行监听器代码

两个基础方法

ServletContextListener:监听ServletContext对象的创建和销毁

  • void contextDestroyed(SerlvetContextEvent sce):ServletContext对象被销毁之前会调用该方法
  • void contextInitialized(ServletContextEvent sce):ServletContext对象创建后会调用该方法

步骤:

  1. 定义一个类,实现ServletContextListener接口
  2. 复写方法
  3. 配置
    1. web.xml
    2. 注解
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值