JavaWeb
JavaWeb入门
参考课程:Java web从入门到企业实战完整版
Web前置知识
Mysql
详见本博客中的:MySql数据库入门
补充:
DDL:对表结构的操作。
DML:对表内数据的增删改查操作。
DQL:对表内数据的查询操作。
JDBC
JDBC简介
jdbc就是用java语言操作关系型数据库的一套API。
同一套Java代码,操作不同的关系型数据库。
jdbc是一套Sun公司定义的标准接口 。
在jdbc的标准下,Mysql,Oracle,DB2等数据库公司各自实现了这些接口,这些完成了的接口叫做实现类。这些实现类又叫做各自数据库的“驱动”。其本质是Jar包。
所以我们使用JDBC接口进行编程,但真正执行的是各实现类的Jar包。
JDBC的好处:
- 各数据库厂商使用相同的接口,JAVA代码不需要根据不同的数据库进行开发。
- 可随时更换底层数据库,但访问JAVA的代码可以基本不变。
JDBC快速入门
- 创建工程,导入驱动Jar包
- 注册驱动 class.forname(“com.mysql.cj.jdbc.Driver”)
- 获取连接 Connection conn = DriverManager.getConnection(url, username, password)
- 定义SQL语句 String sql = “…”
- 获取执行SQL对象 Statement stmt = conn.createStatement();
- 执行SQL stmt.executeUpdate(sql);
- 处理返回结果 System.out.println(“…”)
- 释放资源 stmt.close(); conn.close();
JDBC API 详解
DriverManager
注册驱动
Driver类源码中静态代码块调用了registerDriver()进行驱动的注册
Mysql 5 之后的驱动包,可以省略注册驱动的步骤
自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类获取连接
getConnection()方法
参数:
Url:连接路径语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2…
示例:jdbc:mysql://127.0.0.1:3306/db1
细节:本机mysql服务器可以写为jdbc:mysql:///数据库名称?参数键值对1&参数键值对2…User:Mysql用户名
Password:Mysql密码
Connection
- 获取执行SQL的对象
- 普通执行SQl对象
Statement createStatement()
- 预编译SQL的执行SQL对象:防止SQL注入
PreparedStatement prepareStatement(sql)
- 执行存储过程的对象
CallableStatement prepareCall(sql)
- 普通执行SQl对象
- 事务管理
- Mysql事务管理
- JDBC事务管理:Connection
Connection接口中定义了3个对应的方法 - 开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务,即为开启事务。
- 提交事务:commit()
- 回滚事务:rollback()
Statement
- Statement作用:
- 执行SQl语句
- 执行SQL语句
- int executeUpdate(sql):执行DML,DDL语句 返回值:(1)DML语句影响的行数,(2)DDL语句执行后,执行成功也可能返回0。
- ResultSet executeQuery(sql):执行DQL语句 返回值:ResultSet结果集对象。
ResultSet
- ResultSet(结果集对象)作用:
- 封装了DQL查询语句的结果:
ResultSet stmt.ResultSet(sql):执行DQL语句,返回ResultSet对象
- 封装了DQL查询语句的结果:
- 获取查询结果
- boolean next(): (1)将光标从当前位置向前移动一行(2)判断当前行是否为有效行
返回值:- true:有效行,当前行有数据
- false:无效行,当前行没有数据
- xxx getXxx(参数):获取数据
xxx:参数类型;如int getInt(参数);String getString(参数)
参数(重载形式):- int:列的编号,从1开始
- String:列的名称
- boolean next(): (1)将光标从当前位置向前移动一行(2)判断当前行是否为有效行
- ResultSet案例
- 需求:查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
PreparedStatement
PreparedStatement作用:
- 预编译SQL语句并执行:防止SQL注入问题。
- 获取PreparedStatement对象
SQL语句中的参数值,使用?占位符代替String sql = "select * from user where username = ? and password = ?";
通过Connection对象获取,并传入对应的sql语句PreparedStatement pstmt = conn.prepareStatement(sql);
- 设置参数值
PreparedStatement对象:setXxx(参数1,参数2):给?赋值。
Xxx:数据类型;如setInt(参数1,参数2)
参数:- 参数1:?的位置编号,从1开始
- 参数2:?的值
- 执行SQL
executeUpdate(); 不需要再传递sql
其实区别是如果传入的是一个String的参数,pstmt会对String内的符号进行转义,防止 = 或者 ‘’ 等符号和查询语句中的符号混淆产生歧义。
SQL注入
- SQL注入是通过操作输入来修改事先定义号的SQL语句,用以达到执行代码对服务器进行攻击的方法。
PreparedStatement原理
PreparedStatement好处:
- 预编译SQL,性能更高
- 防止SQL注入:将敏感字符进行转义
PreparedStatement预编译功能开启:
useServerPrepStmts=true
配置MySQL执行日志(重启mysql服务后生效)
1
2
3
4
5
6log-output=FILE
general-log=1
general_log_file="D:\mysql.log"
slow-query-log=1
slow_query_log_file="D:\mysql_slow.log"
long_query_time=2PreparedStatement原理:
- 在获取PreparedStatement对象时,将sql语句发送给mysql服务器进行检查,编译(这些步骤很耗时)
- 执行时就不用再进行这些步骤了,速度更快
- 如果sql模板一样,则只需要继续你那个一次检查、编译
数据库连接池
数据库连接池简介
- 数据库连接池是个容器,负责分配、管理数据库连接(Connection)
- 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;
- 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
- 好处
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
数据库连接池实现
- 标准接口DataSource
- 官方(SUN)提供的数据库连接池标准接口,由第三方组织实现此接口。
- 功能:获取连接
Connection getConnection()
- 常见的数据库连接池:
- DBCP
- C3P0
- Druid
- Druid(德鲁伊)
- Druid连接池是阿里巴巴开源的数据库连接池项目
- 功能强大,性能优秀,是Java语言最好的数据库连接池之一
- Druid使用步骤
- 带入jar包
- 定义配置文件
- 加载配置文件
- 获取数据连接池对象
- 获取连接
理解:导入Druid的配置文件,然后使用该配置文件来创建一个Druid工厂。通过创建好的这个Druid工厂实例即可直接生成Connection对象。后面的使用方法和前面相同。
Maven
Maven是专门用于管理和构建Java项目的工具,它的主要功能有:
提供了一套标准化的项目结构
Maven创建的项目所有IDE都可以通用(之前不同的IDE创建的项目目录结构不同,不能通用)提供了一套标准化的构建流程(编译,测试,打包,发布……)
标准化的构建流程:
- 编译
- 测试
- 打包
- 发布
Maven提供了一套简单的命令来完成项目构建。
提供了一套依赖管理机制
依赖管理其实就是管理你项目所依赖的第三方资源(jar包,插件…)- Maven使用标准的坐标配置来管理各种依赖
- 只需要简单的配置就可以完成依赖管理
Maven简介
Apache Maven 是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建、报告和文档。
Maven模型:
- 项目对象模型
- 依赖管理模型
- 插件
仓库分类:
- 本地仓库:自己计算机上的一个目录
- 中央仓库:有Maven团队维护的全球唯一的仓库
- 远程仓库(私服):一般由公司团队搭建的私有仓库
当项目中使用坐标引入对应依赖jar包后,首先会查找本地仓库中是否有对应的jar包:
- 如果有,则再项目直接引用。
- 如果没有,则去中央仓库中下载对应的jar包到本地仓库。
Maven安装配置
配置MAVEN_HOME环境变量
配置本地仓库:修改conf/settings.xml中的<localRepository>为一个指定目录
配置阿里私服:修改conf/settings.xml中的<mirrors>标签,为其添加如下子标签
1
2
3
4
5
6<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
Maven基本使用
Maven常用命令
compile:编译
运行完成后会在项目目录下生成target文件存放项目编译后的字节码文件clean:清理
clean命令是删除相应的编译文件的,在首次执行的时候也会下 载相应的clean插件。
test:测试
该命令会自动执行Test中的类并且进行输出package:打包
打包完成后会在target文件中生成一个jar文件。install:安装
install命令会将本项目的jar文件添加到本地仓库中。
Maven生命周期
Maven构建项目生命周期表述的是一次构建过程经历了多少个事件
Maven对项目构建的生命周期划分为三套
- clean:清理工作
- default:核心工作,例如编译,测试,打包,安装等
- site:产生报告,发布站点等(不常用)
注意:执行test并不会执行clean
IDEA配置Maven
IDEA配置Maven环境
1. 选择IDEA中File-->Settings
2. 搜索maven
3. 设置IDEA使用本地安装的Maven,并修改配置文件路径
Maven坐标详解
什么是坐标?
- Maven中的坐标是资源的唯一标识
- 使用坐标来定义项目或引入项目中需要的依赖
Maven坐标主要组成
- groupid:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.dicemy)
- artifactid:定义当前Maven项目名称(通常是模块名称,例如order-service、goods-service)
- version:定义当前项目版本号
依赖管理
使用坐标导入jar包
1. 再pom.xml中编写\<dependencies>标签
2. 在\<dependencies>标签中使用\<dependency>引入坐标
3. 定义坐标的groupid,artifactid,version
4. 点击刷新按钮,使坐标生效
依赖范围
- 通过设置坐标的依赖范围,可以设置对应jar包的作用范围:编译环境,测试环境,运行环境。
- <scope>默认值:compile
MyBatis
MyBatis
什么是MyBatis?
- MyBatis是一款优秀的持久层框架,用于简化JDBC开发。
- MyBatis本是Apache的一个开源项目iBatis,2010年迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github 。
持久层
- 负责将数据保存到数据库的那一层代码。
- JavaEE三层架构:表现层、业务层、持久层。
框架
- 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
- 在框架的基础之上构建软件编写更加高效、规范、通用、可拓展
JDBC缺点
1. 硬编码
- 注册驱动,获取连接
- SQL语句
2. 操作繁琐
- 手动设置参数
- 手动封装结果集
MyBatis简化
硬编码 =》配置文件
操作繁琐 =》自动完成
MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。
MyBatis快速入门
1. 创建user表,添加数据
2. 创建模块,导入坐标
3. 编写MyBaits核心配置文件-->替换连接信息,解决硬编码问题
4. 编写SQL映射文件-->统一管理sql语句,解决硬编码问题
5. 编码
1. 定义POJO类
2. 加载核心配置文件,获取SQLSessionFactory对象
3. 获取SqlSession对象,执行SQL语句
4. 释放资源
Mapper代理开发
目的
- 解决原生方式中的硬编码
- 简化后期执行SQL
使用Mapper代理方式完成入门案例
- 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下
- 设置SQL映射文件中的namespace属性为Mapper接口全限定名
- 在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
- 编码
- 通过SqlSession的getMapper方法获取Mapper接口的代理对象
- 调用对应方法完成sql的执行
细节:如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载。
理解:每一张表进行查询都需要一个pojo 实体类,作为查询后返回的对象。还需要一个mapper接口类,里面定义用到的所有需要查询或修改的方法的名字,供主方法中调用。最后还需要一个与该mapper配套的xml配置文件,在xml配置文件中写mapper接口类中每一个方法的具体select语句。
在主方法中,通过MyBatis的配置文件创建一个SqlSession工厂,然后创建一个新的SqlSession,通过SqlSession的getMapper方法来获取一个Mapper类,并返回一个mapper对象,最后通过mapper对象调用mapper中的查询或操作函数即可。
MyBatis核心配置文件详解
类型别名(tpyeAliases)
1
2
3<tpyeAliases>
<package name="com.dicemy.pojo"/>
</tpyeAliases>细节:配置各个标签时,需要遵守前后顺序。(放到environments前就行)
配置文件完成增删改查
完成品牌数据的增删改查操作
- 要完成的功能列表清单
- 查询
- 查询所有数据
- 查看详情
- 条件查询
- 添加
- 修改
- 修改全部字段
- 修改动态字段
- 删除
- 删除一个
- 批量删除
- 查询
准备环境
- 数据库表
- 实体类
- 测试用例
- 安装MyBaitsX插件
Web核心
- 什么是JavaWeb
- Web:全球广域网,也成为万维网,能够通过浏览器访问的网站。
- JavaWeb:是用Java技术来解决相关web互联网领域的技术栈
- JavaWeb技术栈
- B/S架构:浏览器/服务器架构模式。
- 好处:易于维护升级
- 静态资源:HTML,CSS,JS,图片等。负责页面展示
- 动态资源:Servlet,JSP等。负责逻辑处理
- 数据库:负责存储数据
- HTTP协议:定义通信规则
- Web服务器:负责解析HTTP协议,解析请求数据,并发送响应数据。
- B/S架构:浏览器/服务器架构模式。
HTTP
概念:超文本传输协议,规定了浏览器和服务器之间数据传输的规则。
HTTP协议特点:
1. 基于TCP协议:面向连接,安全
2. 基于请求-响应模型的:一次请求对应一次响应
3. HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。
- 缺点:多次请求间不能共享数据。
- 优点:速度快
HTTP-请求数据格式
- 请求数据分为3部分:
- 请求行:请求数据的第一行。其中GET表示请求方法,/表示请求资源路径,HTTP/1.1表示协议版本。
- 请求头:第二行开始,格式为key:value形式。
- 请求体:POST请求的最后一部分,存放请求参数。
- 常见的HTTP请求头:
- GET请求和POST请求区别:
- GET请求请求参数在请求行中,没有请求体。POST请求请求参数在请求体中。
- GET请求请求参数大小有限制,POST没有
HTTP-响应数据格式
- 响应数据分为3部分:
- 响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述。
- 响应头:第二行开始,格式为key:value形式。
- 响应体:最后一部分。存放响应数据。
- 响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述。
- 常见的HTTP响应头:
Tomcat
Web服务器是一个应用程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让web开发更加便捷。主要功能是“提供网上信息浏览服务”。
简介
- 概念:Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。
- JavaEE:Java企业版。指Java企业级开发的技术规范总和。包含13项技术规范:JDBC,JNDI,EJB,RMI,JSP,Servlet,XML,JMS,Java IDL,JTS,JTA,JavaMail,JAF。
- Tomcat也被称为Web容器、Servlet容器。Servlet需要一类于Tomcat才能运行。
总结
- Web服务器作用?
- 封装HTTP协议操作,简化开发
- 可以将web项目部署到服务器中,对外提供网上浏览服务
- Tomcat是一个轻量级的Web服务器,支持Servlet/JSP少量JavaEE规范,也称为Web容器,Servlet容器
- Web服务器作用?
Tomcat-基本使用
在bin目录下有一个start.sh文件,点击即可运行
配置:
修改启动端口号:conf/server.xml
HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号。
启动时可能出现的问题:
- 端口号冲突:找到对应程序,并将其关掉
- 启动窗口一闪而过:检查JAVA_HOME是否配置正确
Tomcat-部署项目
- Tomcat部署项目:
- 将项目放置到webapps目录下,即部署完成
- 一般JavaWeb项目会被打成war包,然后将war包放到webapps目录下,T地方阿斯蒂芬阿斯蒂芬cat会自动解压缩war文件。
- Tomcat部署项目:
IDEA中创建Maven Web项目
Web项目结构:
- Maven Web项目结构:开发中的项目
- 部署的JavaWeb项目结构:开发完成,可以部署的项目
- 编译后的Java字节码文件和resources的资源文件,放到WEB-INF下的classes目录下
- pom.xml中依赖坐标对应的jar包,放入WEB-INF下的lib目录下
- Maven Web项目结构:开发中的项目
使用骨架
骨架:项目模板
- 选择web项目骨架,创建项目
- 删除pom.xml中多余的坐标
- 补齐缺失的目录结构
不使用骨架
IDEA中使用Tomcat - 集成本地Tomcat
- 将本地Tomcat集成到idea中,然后进行项目部署即可
IDEA中使用Tomcat - Tomcat Maven插件
- pom.xml添加Tomcat插件
- 使用Maven Helper 插件快速启动项目,选中项目,右键 Run Maven –> tomcat7:run
Servlet
- Servlet是Java提供的一门动态web资源开发技术
- Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet。
Servlet快速入门
1. 创建web项目,导入Servlet依赖坐标
2. 创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输出一句话
3. 配置:在类上使用@WebServlet注解,配置该Servlet的访问路径
4. 访问:启动Tomcat,浏览器输入URL访问该Servlet
Servlet执行流程
1. Servlet由谁创建?Servlet方法由谁调用?
- Servlet由web服务器创建,Servlet方法由web服务器调用。
2. 服务器怎么知道Servlet怎么知道Servlet中一定有service方法?
- 因为我们自定义的Servlet,必须实现Servlet接口并复写其方法,而Servlet接口中有servrice方法。
Servlet生命周期
- 对象的生命周期指一个对象从被创建到销毁的整个过程
- Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:
- 加载和实例化:默认情况下,当Servlet第一次被访问时,有容器创建Servlet对象
@WebServlet(urlPatterns=”/demo”,loadOnStartUp=1)- 负整数:第一次被访问时创建Servlet对象
- 0或正整数:服务器启动时创建Servlet对象。数字越小优先级越高。
- 初始化:在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件,创建连接等初始化的工作。该方法只调用一次
- 请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理。
- 服务终止:当需要释放内存或容器关闭时,容器就回调用Servlet示例的destory()方法完成资源的释放。在destory()方法调用之后,容器会释放这个Servlet示例,该示例随后会被Java的垃圾收集器回收
- 加载和实例化:默认情况下,当Servlet第一次被访问时,有容器创建Servlet对象
Servlet方法介绍
初始化方法,在Servlet被创建时执行,只执行一次
1
void init(ServletConfig config)
提供服务方法,每次Servlet被访问,都会调用该方法
1
void service(ServletRequest req, ServletResponse res)
销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
1
void destroy()
获取ServletConfig对象
1
ServletConfig getServletConfig()
获取Servlet信息
1
String getServletInfo()
Servlet体系结构
我们将来开发B/S架构的web项目,都是针对HTTP协议,随意我们自定义Servlet,会继承HttpServlet
总结
HttpServlet使用步骤
- 集成HttpServlet
- 重写doGet和doPost方法
HttpServlet原理
获取请求方式,并根据不同的请求方式,调用不同的doXxx方法。
Servlet urlPattern配置
Servlet想要被访问,必须配置其访问路径(urlPattern)
一个Servlet,可以配置多个urlPattern
@WebServlet(urlPatterns = {“/demo1”, “demo2”})urlPattern配置规则
- 精确匹配
- 目录匹配
- 拓展名匹配
- 任意匹配
XML配置方式编写Servlet
Servlet从3.0版本后开始支持使用注解配置,3.0版本前只支持XML配置文件的配置方式
步骤:
- 编写Servlet类
- 在web.xml中配置该Servlet
Request&Response
Request(请求)& Response(响应)
- Request:获取请求数据
- Response:设置响应数据
Request
Request继承体系
1. Tomcat需要解析请求数据,封装为Request对象,并且创建Request对象传递到service方法中
2. 使用Request对象,查阅JavaEE API文档的HttpServletRequest接口
Request获取请求数据
获取请求数据
- 请求数据分为3部分:
- 请求行:
GET /request-demo/req1?username=zhangsan HTTP/1.1
- String getMethod():获取请求方式:GET
- String getContextPath():获取虚拟目录(项目访问路径):/request-demo
- StringBuffer getRequestURL():获取URL(统一资源定位符):http://locallhost:8080/request-demo/req1
- String getRequestURI():获取URI(统一资源标识符):/request-demo/req1
- String getQueryString():获取请求参数(GET方式):username=zhangsan&password=123
- 请求头:
User-Agent:Mozilla/5.0 Chrome/91.0.4472.106
- String getHeader(String name):根据请求头名称,获取值
- 请求体:
username=superbaby&password=123
- ServletInputStream getInputStream():获取字节输入流
- BufferedReader getReader():获取字符输入流
- 请求行:
通用方法获取请求参数
请求参数获取方法:
GET方式:
1
String getQueryString()
POST方式:
1
BufferedReader getReader()
通用方法获取参数:
- Map<String, String[]> getParameterMap():
获取所有参数Map集合 - String[] getParameterValues(String name):
根据名称获取参数值(数组) - String getParameter(String name):
根据名称获取参数值(单个值)
- Map<String, String[]> getParameterMap():
通过通用方式获取请求参数后,屏蔽了GET和POST的请求方式代码的不同,则代码可以定义为如下格式:
可以使用Servlet模板创建Servlet更高效
请求参数中文乱码处理
请求参数如果存在中文数据,则会乱码
解决方案:
POST:设置输入流的编码
1
req.setCharacterEncoding("UTF-8");
通用方式(GET/POST):先编码,再解码
1
new String(username.getBytes("ISO-8859- 1"),"UTF-8");
URL编码
- 将字符串按照编码方式转为二级制
- 每个字节转为2个16进制数并在前面加上%
Request请求转发
请求转发
请求转发:一种在服务器内部的资源跳转方式
实现方式:
1
req.getRequsetDispatcher("资源B路径").forward(req,resp);
请求转发资源间共享数据:使用Request对象
- void setAttribute(String name, Object o):存储数据到request域中
- Object getAttribute(String name):根据key,获取值
- void removAttribute(String name):根据key,删除该键值对
请求转发特点:
- 浏览器地址栏领不发生变化。
- 只能转发到当前服务器的内部资源。
- 一次请求,可以在转发的资源间使用requset共享数据。
Response
Response设置响应数据功能介绍
- 响应数据分为3部分:
- 响应行:
HTTP/1.1 200 Ok
- void setStatus(int sc):设置响应状态码
- 响应头:
Content-Type:text/html
- void setHeader(String name, String value):设置响应头键值对
- 响应体:
<html><head></head><body></body></html>
- PrintWriter getWriter():获取字符输出流
- ServletOutputStream getOutputStream():获取字节输出流
- 响应行:
Response完成重定向
重定向(Redirect):一种资源跳转方式
实现方式:
1
2resp.setStatus(302);
resp.setHeader("location","资源B的路径");1
resp.sendRedirect("资源B的路径");
重定向特点:
- 浏览器地址栏路径发生变化
- 可以重定向到任意位置的资源(服务器内部、外部均可)
- 两次请求,不能在多个资源使用request共享数据
路径问题
- 明确路径谁使用?
- 浏览器使用:需要加虚拟目录(项目访问路径)
- 服务端使用:不需要加虚拟目录
Response响应字符数据
使用:
通过Response对象获取字符输出流
1
PrintWriter resp.getWrite();
写数据
1
writer.write("aaa");
注意:
该流不需要关闭,随着响应结束,Response对象销毁,由服务器关闭
中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1
1
resp.setContentType("text/html;charset=utf-8");
Response响应字节数据
使用:
通过Response对象获取字符输出流
1
ServletOutputStream outputStream = resp.getOutputStream();
写数据
1
outputStream.write(字节数据);
IOUtils工具类使用
导入坐标
1
2
3
4
5<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>使用
1
IOUtils.copy(输入流,输出流);
代码优化
创建SqlSessionFactory代码优化
1
2
3String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);问题:
- 代码重复:工具类
- SqlSessionFactory工厂只创建一次,不要重复创建:静态代码块
JSP
- 概念:Java Server Pages, Java服务端页面
- 一种动态的网页技术,其中既可以定义HTML,JS,CSS等静态内容,还可以定义Java代码的动态内容。
- JSP=HTML+Java
- JSP的作用:简化开发,避免了在Servlet中直接输出HTML标签
- JSP本质上就是一个Servlet
JSP已逐渐退出历史舞台
EL表达式
- 表达式语言,用于简化JSP页面内的Java代码
- 主要功能:获取数据
- 语法:${exp ression}
${brands}
:获取域中存储的key为brands的数据 - JavaWeb中的四大域对象:
- Page:当前页面有效
- Requeset:当前请求有效
- Session:当前会话有效
- Application:当前应用有效
JSTL标签
JSP标准标签库,使用标签取代JSP页面上的Java代码
1
2
3
4
5
6<c:if test="${flag == 1}">
男
</c:if>
<c:if test="${flag == 2}">
女
</c:if>
MVC模式和三层架构
MVC模式
MVC是一种分层开发的模式,其中:
- M:Model,业务模型,处理业务
- V:View,试图,界面展示
- C:Controller,控制器,处理请求,调用模型和视图
MVC好处
- 职责单一,互不影响
- 有利于分工协作
- 有利于组建重组
三层架构
- 数据访问层:对数据库的CRUD基本操作。
- 业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能。
- 表现层:接受请求,封装数据,调用业务逻辑层,响应数据。
MVC模式和三层架构的对比
案例
查询所有
添加
修改-回显数据
修改-修改数据
会话跟踪技术
- 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
- 会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
- HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享。
- 实现方式:
- 客户端会话跟踪技术:Cookie
- 服务端会话跟踪技术:Session
Cookie基本使用
Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问
Cookie基本使用
Cookie原理Cookie的实现是基于HTTP协议的
- 响应头:set-cookie
- 请求头:cookie
Cookie使用细节
Cookie存活时间
- 默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
- setMaxAge(int seconds):设置Cookie存活时间
- 正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
- 负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁
- 零:删除对应Cookie
Cookie存储中文
- Cookie不能直接存储中文
- 如需要存储,则需要进行转码:URL编码
Session基本使用
- Session:服务端会话跟踪技术,将数据保存到服务端
- JavaEE提供HttpSession接口,来实现一次会话的多次请求间数据共享功能
- 使用:
- 获取Session对象
HttpSession session = request.getSession();
- Session对象功能:
- Void setAttribute(String name, Object o):存储数据到session域中
- Object getAttribute(String name):根据key,获取值
- Void removeAttribute(String name):根据key,删除该键值对
- 获取Session对象
Session原理
Session是基于Cookie实现的
Session使用细节
Session钝化、活化:
- 服务器重启后,Session中的数据是否还在?
- 钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中
- 活化:再次启动服务器后,从文件中加载数据到Session中
Session销毁:
默认情况下,无操作,30分钟自动销毁
1
2
3<session-config>
<session-timeout>30</session-timeout>
</session-config>调用Session对象的invalidate()方法
Cookie和Session小结
- Cookie和Session都是来完成一次会话内多次请求间数据共享的
- 区别:
- 存储位置:Cookie是将数据存储在客户端,Session将数据存储在服务端。
- 安全性:Cookie不安全,Session安全。
- 数据大小:Cookie最大3KB,Session默认30分钟
- 服务器性能:Cookie不占服务器资源,Session占用服务器资源。
Filter
- 概念:Filter表示过滤器,是JavaWeb三大组件(Servlet,Filter,Listener)之一。
- 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
- 过滤器一般完成一些通用的操作,比如:权限控制,同一编码处理,敏感字符处理等等…
Filter快速入门
- 定义类,实现Filter接口,并重写其所有方法
- 配置Filter拦截资源的路径:在类上定义@WebFilter注解
- 在doFilter方法中输出一句话,并放行
Filter执行流程
Filter拦截路径配置
- Filter可以根据需求,配置不同的拦截资源路径
- 拦截具体的资源:/index.jsp:只有访问index.jsp时才会被拦截。
- 目录拦截:/user/*:访问/user下的所有资源,都会被拦截。
- 后缀名拦截:*.jsp:访问后缀名为jsp的资源,都会被拦截。
- 拦截所有:/*:访问所有资源,都会被拦截。
过滤器链
- 一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链
- 注解配置的Filter,优先级按照过滤器类名(字符串)的自然排序
Listener(用的不多)
- Listener表示监听器,是JavaWeb三大组件(Servlet,Filter,Listener)之一。
- 监听器可以监听就是在application,session,request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件
- Listener分类:JavaWeb中提供了8个监听器
AJAX
- 概念:异步的JavaScript和XML
- AJAX作用:
- 与服务器进行数据交换:通过AJAX可以给服务器发送请求,并获取服务器响应的数据。
- 使用了AJAX和服务器进行通信,就可以使用HTML+AJAX来替换JSP界面了
- 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想,用户名是否可用校验,等等…
- 与服务器进行数据交换:通过AJAX可以给服务器发送请求,并获取服务器响应的数据。
同步和异步
AJAX快速入门
- 编写AjaxServlet,并使用Response输出字符串
- 创建XMLHttpRequest对象:用于和服务器交换数据
- 向服务器发送请求
- 获取服务器响应数据
Axios异步框架
- Axios对原生的AJAX进行封装,简化书写
- 官网:https://www.axios-http.cn/
Axios快速入门
引入axios的js文件
1
<script src="js/axios.min.js"></script>
使用axios发送请求,并获取响应结果
1
2
3axios.post("http://localhost:8080/filter-demo/axiosServlet","username=zhangsan").then(function (resp) {
alert(resp.data)
})
JSON
- 概念:JavaScript对象表示法。
- 由于其语法简单,层次结构鲜明,现多用于作为数据载体,在网络中进行数据传输。
JSON基础语法
JSON数据和Java对象转换
请求数据:JSON字符串转为Java对象
响应数据:Java对象转换为JSON字符串
Fastjson是阿里巴巴提供的一个Java语言编写的高性能功能完善的JSON库,是目前Java语言中最快的JSON库,可以实现Java对象和JSON字符串的相互转换。
使用:
导入坐标
1
2
3
4
5<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>Java对象转JSON
1
String jsonStr = JSON.toJSONString(obj);
JSON字符串转Java对象
1
User user = JSON.parseObject(jsonStr, User.class);
Vue
- Vue是一套前端框架,免除原生JavaScript中的DOM操作,简化书写。
- 基于MVVM思想,实现数据的双向绑定,将编程的关注点放在数据上。
- 官网:https://cn.vuejs.org/
Vue快速入门
新建HTML界面,引入Vue.js文件
1
<script src="js/vue.js"></script>
在JS代码区域,创建Vue核心对象,进行数据绑定
1
2
3
4
5
6
7
8new Vue({
el:"#app"
data(){
return{
username:""
}
}
});编写视图
1
2
3
4<div id="app">
<input name="username" v-model="username">
{{username}}
</div>
Vue常用指令
V-bind:
1
<a v-bind:href="url">百度一下</a>
1
2
3
4<!--
v-bind可以省略
-->
<a :href="url">百度一下</a>v-model:
1
<input name="username" v-model="username">
v-on:
html:
1
2
3<input type="button" value="一个按钮" v-on:click="show()">
<input type="button" value="一个按钮" @click="show()">Vue:
1
2
3
4
5
6
7
8new Vue({
el:"#app",
methods:{
show(){
alert("我被点了");
}
}
})
Vue生命周期
生命周期的八个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法(钩子)
mounted:挂载完成,Vue初始化成功,HTML页面渲染成功。
- 发送异步请求,加载数据
Element
- Element是饿了么公司前端开发团队提供的一套基于Vue的网站组件库,用于快速构建网页。
- 组件:组成网页的部件,例如 超链接、按钮等等
Element快速入门
引入Element的css,js文件和Vue.js
1
2
3<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="WEB-INF/js/vue.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>创建Vue核心对象
1
2
3
4
5<script>
new Vue({
el:"#app"
})
</script>官网复制Element组件代码
Element布局
- Element中有两种布局方式:
- Layout布局:通过基础的24分栏,迅速简单地创建布局
- Container布局容器:用于布局的容器组件,方便快速搭建页面的基本结构
Element组件
在官网上找,然后复制粘贴修改即可。
完结 end.
JavaWeb