目录
本文章根据黑马程序员陈老师Javaweb教程所作学习总结
一、路线
1、数据库Mysql
2、JDBC
3、maven
4、Mybatis
前端
5、HTML+CSS
6、javascript
7、ajax+vue+elementul
web核心
8、tomcat+http+servlet
9、request+response
10、jsp
11、cookie+session
12、filter+listener
二、数据库
1、事务
- 事务是一种机制、一个操作序列,包含了一组数据库操作命令
- 事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失效
- 事务是一个不可分割的工作逻辑单元
(1)事务简单理解:
张三给李四借了500块钱,现在李四要还给张三。本身两人账户都有1000元,李四给张三转账500元,最后张三有1500元,李四500元,这个转账操作要经历以下三个步骤:
①查询李四账号余额
②李四账号金额-500
③张三账号金额+500
但是为了避免出现李四金额减少,张三金额没有增加的情况出现,所以要将这个转账操作作为一个整体,要么同时成功,要么同时失败。这个时候在转账操作前开启事务(START TRANSACTION;或者 BEGIN),中途如果出现异常则回滚事务(POLLBACK;),没有异常就提交事务(ROLLBACK;)
(2)事务的四大特征:原子性、一致性、隔离性、持久性
三、JDBC
1、概念
2、深入理解JDBC
3、JDBC使用步骤
(1)导入jar包
创建一个空项目(项目结构中配置jdk和对应的编译版本、创建Java模块modules)->导入驱动jar包放入新建的目录lib里面(jar包下载网址:MySQL :: Download MySQL Connector/J (Archived Versions) )->让当前工程识别jar包(add as library -> modules library),如果不识别的话,后面无法完成驱动的注册。
(2)编写代码
4、 JDBC的API详解
参考博客
5、数据库连接池
(1)Driud使用步骤(性能优秀的数据库连接池)
①导入jar包(driud jar包)
下载jar包并导入进idea,跟jdbc的jar包一样的操作
②定义配置文件
配置properties文件
③加载配置文件
加载配置时可以有以下两种方法:
如果出现【系统找不到指定文件】错误时,可以直接右键点击properties文件复制路径,解决 问题来源:http://t.csdn.cn/AWv89;
如果出现【url not set】错误时,则是加载配置文件代码没有弄全,可能是缺少load()方法;或者是连接池版本过低;
④获取数据库连接池对象
⑤获取连接
6、JDBC练习
(1)准备环境:
①创建数据库表tb_brand
②编写实体类Brand
- 写出成员变量(数据库表中的属性)
- IDEA中使用快捷键 Alt + Insert 快捷方式生成get/set方法和toString方法
(2)测试用例
①查询所有数据
②第6步封装数据,将结果装载到list集合中,最后输出list集合
③添加、修改、删除数据
举一反三,跟查询的区别就是需要参数,返回boolean类型
(3)测试用例总代码:
四、Maven
1、Maven简介
maven本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型。提供标准的、跨平台的自动化项目构建方式;方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题;提供标准的、统一的项目结构,使得在各个编程软件上正常运行。
2、Maven本身构造及其统一的项目开发目录结构
src文件里面有main和test两个文件,其中main是用来写程序的,test是用来写测试程序的。在main和test文件中各有java和resources两个文件,其中java是写Java源程序的,resources是用于写配置文件的
3、Maven下载与安装
(1)下载地址:
(2)配置环境变量
(3)用MVN命令检验是否配置好
4、配置国内源
博客搜索方法
5、Maven功能
- 提供了一套标准化的项目结构
- 提供了一套标准化的构建流程(编译、测试、打包、发布.....)
- 提供了一套依赖管理机制
依赖管理其实就是管理你项目所依赖的第三方资源(jar包、插件...)
①Maven使用标准的坐标配置来管理各种依赖
②只需要简单的配置就可以完成依赖
6、IDEA配置Maven
(1)IDEA配置Maven环境
①在IDEA中创建一个空项目
②按照以下步骤进行配置
(2)Maven坐标详解
(3)IDEA创建Maven项目
(4)IDEA导入Maven项目
(5) 配置Maven — Helper插件
插件的作用:
①鼠标右键点击项目名称,可以直接点击Run Maven进行编译、测试、打包等操作,就不用去另外点击右边的maven
②最方便的是,鼠标右键点击项目名称,点击Debug Maven进行断点调试
7、依赖管理
(1)使用坐标导入jar包(加注释快捷键:CTRL + /)
(2)依赖范围
五、MyBatis
1、MyBatis简介
2、MyBatis快速入门
查询user表中的所有数据:
(1)创建user表,添加数据
(2)创建模块,导入坐标
1.坐标的导入(在pom.xml文件中导入mybatis依赖、mysql驱动、junit单元测试等坐标)
可以在网上查mybatis的坐标,也可以登录官网直接复制(mybatis – MyBatis 3 | 入门),下面mybatis核心配置文件和sql映射文件的代码也在这个里面可以找到。
问题及解决:在新创建的项目中,里面的maven可能是默认的配置(不是自身配置了国内源的maven,所以会出现下载依赖速度缓慢的问题。这个时候可以根据我们前面在maven在idea中的配置内容中学习到的知识,点击settings...中的maven界面,将其中的maven文件地址改为自身设置过的地址,setting.xml也改为自己的.xml地址,从而解决问题)
2.具体代码
<dependencies>
<!--mybatis的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!--mysql 的驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<!--junit 单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!--添加slf4j日志api-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.5</version>
</dependency>
<!--添加logback—classic依赖-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.6</version>
</dependency>
<!--添加logback-core依赖-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.6</version>
</dependency>
</dependencies>
(3)编写MyBatis核心配置文件(mybatis-config.xml文件)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库的连接信息-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="lmq15*******17"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--
加载SQL的映射文件
UserMapper.xml表示数据库映射文件地址
-->
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
(4)编写SQL映射文件(UserMapper.xml文件)
(5)编码
- 定义POJO类
- 加载核心配置文件,配置SqlSessionFactory对象
- 获取SqlSessionFactory对象,执行SQL语句
- 释放资源
public class MybatisDemo {
public static void main(String[] args) throws IOException {
// 加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行sql,test.selectAll表示这个sql语句的唯一标识,这个根据UserMapper.xml映射文件中的找到
List<User> users = sqlSession.selectList("test.selectAll");
System.out.println(users);
// 释放资源
sqlSession.close();
}
}
3、Mapper代理开发
(1)遵守三大规则
1.定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一个目录下
怎么放到同一目录下?直接将映射文件拖到mapper目录下吗?不行!因为在Maven项目编写过程中,.xml配置文件应该放到resources文件里面。
正确做法:在resources下再创建一个跟UserMapper接口一样的目录,注意!在resources里创建目录是应该用com/itheima/mapper,中间应该用 “/” 而不是 “.”,不然无法创建成功。
细节:此时映射文件地址已经改变,前面提起的mybatis核心配置文件里面的映射文件地址也要相应的改变
2.设置SQL映射文件的namespace属性(空间名称)为Mapper接口全限定名
解释:在前面,映射文件里面的namespace我们是随便写的一个名称,但是现在要将其改为UserMapper接口的全限定名
3.在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
Mapper接口代码:
package com.itheima.mapper;
import com.itheima.pojo.User;
import java.util.List;
// 这里是UserMapper接口,所以要用接口的关键词interface
public interface UserMapper {
/* 根据映射文件里面的SQL语句来判断,如果要返回多个集合就用集合List<>
如果只返回一个,则使用User对象
*/
List<User> selectAll();
}
UserMapper映射文件代码:
(2)编码
1.通过SqlSwssion的getMapper方法获取Mapper接口的代理对象
2.调用对应方法完成sql的执行
代码:
package com.itheima;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/*
Mybatis 的代理开发
*/
public class MybatisDemo2 {
public static void main(String[] args) throws IOException {
// 加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行sql,test.selectAll表示这个sql语句的唯一标识,这个根据UserMapper.xml映射文件中的找到
// List<User> users = sqlSession.selectList("test.selectAll");
// 获取UserMapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();
System.out.println(users);
// 释放资源
sqlSession.close();
}
}
细节:在mybatis核心配置文件中如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载
原本写法:
缺点:如果有多个SQL映射文件,还需要一个一个去复制映射文件的地址并添加到mybatis的核心配置文件中,过于繁琐
改进后:
改进后,会自己直接扫描对应目录下的mapper接口,就不用一个一个的去复制映射文件地址,直接全部加载
4、MyBatis核心配置文件
在官网文档可以查看学习(mybatis – MyBatis 3 | 配置)
5、配置文件完成增删改查
(1)准备环境
- 数据库表tb_brand
- 实体类Brand
- 测试用例
- 安装MyBatisX插件
(2)查询所有
代码:
package com.itheima.test;
import com.itheima.mapper.BrandMapper;
import com.itheima.pojo.Brand;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyBatisTest {
@Test
public void testSelectAll() throws IOException {
// 1.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取Mapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
// 4.执行方法
List<Brand> brands = brandMapper.selectAll();
System.out.println(brands);
// 5.释放资源
sqlSession.close();
}
}
出现的错误:因为数据库表(tb_brand)的字段名称 和 实体类(Brand)的属性名称不一致,则不能自动封装数据
解决办法:在映射文件中可以采用起别名(但是每次查询都要定义一次别名)、sql片段(但是不灵活)解决,
根据最优解决办法,采用resultMap的解决办法解决
resultMap:
改良后的BrandMapper.xml映射文件:
(3)查询详情
大体步骤跟前面【查询所有】基本一样,改动点是以下几点:
映射文件中的SQL语句改变(相应的接口也要修改、测试文件里面重新定义方法并添加了参数)
红框里表示参数占位符
总的代码:
public class MyBatisTest {
/*
查询所有
*/
@Test
public void testSelectAll() throws IOException {
// 1.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取Mapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
// 4.执行方法
List<Brand> brands = brandMapper.selectAll();
System.out.println(brands);
// 5.释放资源
sqlSession.close();
}
/*
查询详情
*/
@Test
public void testSelectById() throws IOException {
// 定义一个参数
int id = 1;
// 1.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取Mapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
// 4.执行方法
Brand brand = brandMapper.selectById(id);
System.out.println(brand);
// 5.释放资源
sqlSession.close();
}
/*
条件查询
*/
@Test
public void testSelectByCondition() throws IOException {
// 定义一个参数
int status = 1;
String companyName = "华为";
String brandName = "华为";
//处理参数,这里要注意,模糊查询要相应的处理一下参数
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
// 1.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取Mapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
// 4.执行方法
List<Brand> brands = brandMapper.selectByConditon(status, companyName, brandName);
System.out.println(brands);
// 5.释放资源
sqlSession.close();
}
}
6、动态SQL(SQL映射文件里面操作)
(1)多条件动态查询
当我不想查询第一条,想查询第一条之后的,但是像上面这样写就会报错,因为and直接接到where命令后面的,SQL语法错误,该怎么办?
解决1:采用恒等式
解决2:使用<where><where>标签替换where关键字
(2)单条件动态查询
7、注解完成增删改查
六、HTML(官方教程w3school 在线教程)
1、HTML简介
2、HTML快速入门
(1)新建文本文件,后缀名改为.html
(2)编写HTML结构标签
(3)在<body>中定义文字
head表示头,加载一些资源信息和展示title标题;body表示体,浏览器正文要显示的内容就写在这个里面
<font color="blue"> 正文 </font>,标签可以修改正文的属性
3、基础标签(可以自己在网页上选中检查来查看网页所用的标签)
(1) 代码:
<!--html5 的版本表示-->
<!DOCTYPE html>
<html lang="en">
<head>
<!--当前页面的字符集-->
<meta charset="UTF-8">
<title>小小修士修炼空间</title>
</head>
<body>
<center>
<h1> 欢迎来到小小修士修炼场地</h1>
</center>
<hr>
<font color="blue">
<h3> 该修士目前修为: 练气期</h3>
</font>
<p>
修炼中~
</p>
<p>
静心修炼三小时,<font color="red"><b>经验+20</b></font>;此时小小修士觉得肚子有一点儿饿了,果然在练气层还是无法做到不食五谷。于是小小修士决定再修炼一会儿后就去吃饭,然后散散心,毕竟一直修炼也怕走火入魔
</p>
</body>
</html>
(2)运行效果:
4、图片、音频、视频标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小小修士的日常空间</title>
</head>
<body>
<!--
src: 表示文件的路径
./退回的上一级
.//退回到上一级的上一级
例如在这个文件中 ./会退回到html文件这一级,../会退回到html2_demo文件这一级
根据此文件目录来看,如果是同一目录则直接 ./a.jpg或者a.jpg
如果是上一级目录则 ./img/a.jpg
如果还在上一目录则 ../img/a.jpg
-->
<img src="../img/a.jpg" width="500" height="550">
<!--
音频标签
controls 表示属性,例如 宽度长度等
-->
<audio src="" controls></audio>
<!--
视频标签
controls 表示属性
-->
<video src="" controls></video>
</body>
</html>
5、超链接标签
6、列表标签
7、表格标签
8、布局标签
9、表单标签
(1)定义:
注意:
在<form>标签定义的表单中 method属性有以下注意点:
method:指定表单提交的方式 1.get:默认值 *请求参数出现在请求行当中 *请求参数(name属性名=输入数据值的键值对)会拼接在url后边 *rul的长度有限制 4kb 2.post: *请求参数会隐藏在http请求协议的请求体中 *请求参数无限制
(2)实现代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小小修士的修炼空间</title>
</head>
<body>
<!--
form:
action:指定表单数据提交的URL,将数据提交到指定的服务端数据库路径中去(目前没有指定服务端,所以用#代替,它表示将数据提交到当前html页面里面)
*表单项数据要想被提交,必须指定其name属性
method:指定表单提交的方式
1.get:默认值
*请求参数(name属性名=输入数据值的键值对)会拼接在url后边
*rul的长度有限制 4kb
2.post:
*请求参数会隐藏在http请求协议的请求体中
*请求参数无限制
-->
<center>
<font color="blue">
<h1>
  
修士信息注册页面
</h1>
</font>
</center>
<hr>
<br>
<br>
<br>
<center>
<form action="#" method="post">
<!--
  表示全角空格
  表示半角空格
-->
<!--input 定义表达项,通过type属性控制输入形式-->
<!--
定义文本输入框
通过label标签将【姓名:】与文本框连接起来,让用户可以通过点击属性名来输入文本框内容
*label中的for属性必须要跟input中的id属性对应起来,这样才能连接
-->
<p>
     <label for="username">姓名:</label>
<input type="text" name="username" id="username">
<br>
</p>
<!--定义密码字段-->
<p>
     <label for="userId">密码:</label>
<input type="password" name="password" id="userId">
<br>
</p>
<!--定义下拉列表-->
<p>
  何地开始修行:
<select name="address">
<option value="重庆">重庆</option>
<option value="成都">成都</option>
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="杭州">杭州</option>
</select>
<br>
</p>
<!--定义文件上传按钮-->
<p>
             
头像上传:
<input type="file">
<br>
</p>
<!--
定义单选按钮
*如果要将两个单选内容绑定在一起(互斥),则将他们的name属性要命名一致
*如果没有使用value属性,则单选内容传送到服务端的数据不会变化,value属性定义的什么内容,则选这个单选时传送的就是什么内容
-->
<p>
性别:
<input type="radio" name="gender" value="男" id="male">
<label for="male">男</label>
<input type="radio" name="gender" value="女" id="female">
<label for="female">女</label>
<br>
</p>
<!--
定义复选框内容
*如果要将选项内容绑定在一起,则将他们的name属性要命名一致
-->
<p>
                       
修仙杂艺:
<input type="checkbox" name="hobby" value="炼丹">炼丹
<input type="checkbox" name="hobby" value="炼器">练气
<input type="checkbox" name="hobby" value="阵法">阵法
<input type="checkbox" name="hobby" value="制符">制符
<input type="checkbox" name="hobby" value="灵植">灵植
<input type="checkbox" name="hobby" value="御兽">御兽
<input type="checkbox" name="hobby" value="其他">其他
<br>
</p>
<!--定义提交按钮,value 属性定义按钮名-->
<p>
 
<input type="submit" value="注册">
<!--定义重置按钮-->
<input type="reset">
<!--定义点击按钮-->
<input type="button" value="按钮">
</p>
</form>
</center>
</body>
</html>
(3)运行效果:
七、CSS
什么是CSS?
1、CSS的导入方式
2、CSS选择器
3、CSS属性
详细请看官方教程:CSS 教程
八、JavaScript
什么是JavaScript?
1、JavaScript的引入方式
(1)内部脚本:将js代码定义在HTML页面中
1.alert()是一个弹出警告框,括号里面可以书写弹出内容
(2)外部脚本:将js代码定义在外部js文件中,然后引入到HTML页面中
2、JavaScript的基础语法
(1)书写语法
(2)输出语句
(3)变量
var关键字 :
- 作用域:全局变量(定义在局部的变量在局部外面也可以正常执行)
- 变量可以重复定义
- 下图可以正常运行,20覆盖了30而不会报错
let关键字:
- 作用域:局部变量不能当成全局变量使用,只在当前代码块有效
- 变量不可以重复定义
(4)数据类型
具体代码演示:
(5)运算符
==与===的区别:
类型转换:
代码:
总结:
(6)流程控制语句
具体演示代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小小修士</title>
</head>
<body>
<!-- 在HTML中的JavaScript代码必须位于 <script></script>
之间,且一般情况下,将JavaScript脚本放在</body>前面
-->
<script >
// 1.if
var count = 3;
if(count == 3){
alert(count);
}
//2.switch
var num = 3;
switch (num){
case 1:{
alert("星期一");
break;
}
case 2:{
alert("星期二");
break;
}
case 3:{
alert("星期三");
break;
}
case 4:{
alert("星期四");
break;
}
case 5:{
alert("星期五");
break;
}
case 6:{
alert("星期六");
break;
}
case 7:{
alert("星期天");
break;
}
default:{
alert("输入的星期有误");
break;
}
}
//3.for
var sum = 0;
for(let i = 1; i <= 100; i++){
sum += i;
}
alert(sum);
//4.while
var sum = 0;
var i = 1;
while(i <= 100){
sum += i;
i++;
}
alert(sum);
</script>
</body>
</html>
(7)函数
3、JavaScript常用对象
(1)Array
实现代码:
(2)String
实现代码:
trim()方法:去除字符串前后两端的空白字符,在以后表单验证的时候可能需要去除两端空白字符
(3)自定义对象
实现代码:
4、BOM(JavaScript 和 HTML DOM 参考手册)
(1)Window浏览器窗口对象
实现代码:
定时器实现代码:
案例:
具体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小小修士修炼空间</title>
</head>
<body>
<center>
<font color="#ff4500">
<h1>
小小修士进阶场
</h1>
</font>
</center>
<hr>
<br>
<br>
<br>
<center>
<input type="button" onclick="on()" value="开灯">
<img id="myImage" border="0" src="../img/off.gif" style="text-align:center";>
<input type="button" onclick="off()" value="关灯">
</center>
<!--JavaScript代码-->
<script>
function on(){
document.getElementById('myImage').src='../img/on.gif';
}
function off(){
document.getElementById('myImage').src='../img/off.gif';
}
// 定时器
// 更近所需变化值的个数采用求余产生固定的值,例如需要两个变化的数:x%2,需要三个变化的数:x%3
var x = 0;
setInterval(function (){
if(x%2 == 0){
on();
}else{
off();
}
x++;
if(x==100){
x=0;
}
},1000);
</script>
</body>
</html>
效果图:
(2)Navigator浏览器对象
(3)Screen屏幕对象
(4)History历史记录对象
(5)Location地址栏对象
代码:
案例:
5、DOM(获取对象,后面通过对象来调用相应的方法)
(1)获取Element对象
代码仿写:
(2)常见的HTML Element对象的使用
自行查阅官方文档:JavaScript 和 HTML DOM 参考手册
6、事件监听
(1)事件绑定
(2)常见事件(官网:HTML DOM 事件)
7、正则表达式
九、Web核心
1、HTTP
浏览器向服务端传输请求数据,服务端接收请求数据后响应数据传输给浏览器,浏览器接收响应数据。但是怎么识别呢?请求数据和响应数据要按照一定的规则来书写,这样浏览器和服务端就能按照这种规则来解析数据。
(1)请求数据格式
(2)响应数据格式
2、Web服务器—Tomcat
(1)Tomcat的基本使用(Apache Tomcat® - Welcome!)
安装、卸载、启动、关闭、配置、部署项目(自行博客搜寻)
(2)在idea上创建maven web 项目
(3)在idea上使用Tomcat
(1)集成方法
(2)pom.xml 添加插件方法
3、Servlet
Servlet 提供了动态 Web 资源开发技术,一种可以将网页数据提交到 Java 代码,并且将 Java 程序的数据返回给网页的技术,使用 Servlet 技术实现了不同用户登录之后在页面上动态的显示不同内容等的功能。
(1)快速入门
依照前面所学创建maven web项目:
注意:
在步骤1修改pom.xml文件时,记得导入tomcat插件。
遇到的问题:
在配置Tomcat插件时右侧没有出现tomcat7标志
解决办法:
- 检查pom文件中的jdk配置(与自己的jdk版本是否一样)
- 在pom文件中,不要将tomcat插件plugin放到<pluginManagement>中(大部分是这个问题)
(2)Servlet执行流程
(3)Servlet生命周期
代码:
package com.itheima.web;
import javax.jws.WebService;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
// Servlet要想被访问,必须要配置一个访问路径@WebServlet("/demo1")
@WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
public class ServletDome1 implements Servlet {
/*
初始化方法:
1.调用时机:默认情况下,Servlet被第一次访问时,调用
*loadOnStartup:为-1时,创建对象的时候才会调用;为0或正整数时,服务器启动时就会被调用
2.调用次数:1次
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init被调用");
}
/*
提供服务:
1.调用时间:每一次Servlet被访问时,调用
2.调用次数:多次
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet你好,小小修士来报道了");
}
/*
销毁方法:
1.调用时间:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
2.调用次数:1次
*/
@Override
public void destroy() {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public ServletConfig getServletConfig() {
return null;
}
}
(4)Servlet体系结构
1.如何实现doGet方法?
通过浏览器直接输入URL路径来访问资源的方法就是get的请求方式(实现了doGet方法)
2.如何实现doPost方法?
第一步:写一个HTML页面表单来请求当前servlet资源(HTML在webapp文件里面)
第二步:HTML浏览器页面提交数据,通过post请求方式访问资源并提交(实现了doPost方法)
3.思考:
①HttpServlet中为什么要根据请求方式的不同,调用不同的方法?(各个请求方式的请求消息不一样,要根据不同的请求方式进行不同的处理)
②如何调用?(通过不同的逻辑方式进行调用)
下面通过探究官方文档原理来加深理解:
编写一个实现servlet接口的类,编写service方法中的逻辑代码,如下:
package com.itheima.web;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class ServletDome3 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 根据请求方式的不同,进行分别的处理
// 将servletRequest强转为HTTPServletRequest对象,因为请求方式只有在HTTP的协议下才能获取出来
HttpServletRequest request = (HttpServletRequest)servletRequest;
// 1.获取请求方式
String method = request.getMethod();
// 2.判断
if("GET".equals(method)){
// get方式处理逻辑
}else if("POST".equals(method)){
// post方式的处理逻辑
}
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
为了避免重复在实现servlet接口的类中重复写代码,可以单独写一个实现servlet接口的类(下图第一张截图),将请求方式的逻辑判断写成方法,后面需要的类(下图第二个截图)继承单独写的这个类就行(继承的时候需要重写请求方式的逻辑判断方法),改写如下:
(5)Servlet urlPattern配置
(6)XML配置方式编写Servlet
4、Request(请求)&Response(响应)
(1)Request:
浏览器向服务端发送请求(HTTP协议请求数据),请求数据被tomcat解析后被放到一个对象里面来保存,这个对象就是Request对象。当我们使用Request对象时就是获取这些请求数据
①Request继承体系
②Request获取请求数据
请求体步骤:
1.创建一个HTML页面编写表单代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/web-dem/demo4" method="post">
<input name="username">
<input type="submit">
</form>
</body>
</html>
2. 在servlet文件dopost方法中获取post 请求体参数
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取post 请求体:请求参数
// 1.获取字符输入流
BufferedReader bufferedReader = req.getReader();
// 2.读取数据
String line = bufferedReader.readLine();
System.out.println(line);
}
最后HTML表单数据提交后,Request就会获取到数据
思考:
GET请求方式和POST请求方式区别主要在于获取请求参数的方式不一样,是否可以提供一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码?
Request通用方式获取请求参数:
package com.itheima.web;
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.util.Map;
@WebServlet("/req1")
public class RequestDome1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// GET请求逻辑
// System.out.println("get请求获取参数~");
// 1.获取所有参数的map集合
Map<String,String[]> map = req.getParameterMap();
for(String key : map.keySet()){
// 获取键
System.out.print(key + ":");
// 获取值
String[] values = map.get(key);
for(String value : values){
System.out.print(value+" ");
}
System.out.println();
}
System.out.println("-----------------------------------");
// 2.根据key获取参数值,数组
String[] hobbies = req.getParameterValues("hobby");
for(String hobby : hobbies){
System.out.println(hobby);
}
System.out.println("-----------------------------------");
// 3.根据key获取单个参数值
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
/*
// POST请求逻辑
System.out.println("post请求获取参数~");
// 1.获取所有参数的map集合
Map<String,String[]> map = req.getParameterMap();
for(String key : map.keySet()){
// 获取键
System.out.print(key + ":");
// 获取值
String[] values = map.get(key);
for(String value : values){
System.out.print(value+" ");
}
System.out.println();
}
System.out.println("-----------------------------------");
// 2.根据key获取参数值,数组
String[] hobbies = req.getParameterValues("hobby");
for(String hobby : hobbies){
System.out.println(hobby);
}
System.out.println("-----------------------------------");
// 3.根据key获取单个参数值
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
*/
}
}
在tomcat8之前出现的中文乱码问题:
为什么会乱码?
post提交乱码:通过字符输入流来获取数据,输入流默认编码为ISO-8859-1,
解决办法:在获取输入流之前将编码设置为utf-8
get提交乱码:字符串通过HTTP协议由浏览器传输到服务器(URL编码形式传输),然后到了tomcat后(URL解码),但是因为编解码字符集不一样,所以产生乱码情况。
解决办法:将ISO-8859-1编码转换为字节,然后将字节转换为utf-8编码就行。
代码:
package com.itheima.web.request;
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.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@WebServlet("/demo4")
public class ServletDome4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 使用request对象 获取请求数据
String name = req.getParameter("name"); // url?name=小小修士
// 将URL解码后的【ISO-8859-1】转换为字节数据
byte[] bytes = name.getBytes("ISO-8859-1");
// 再将字节数组转换为字符串
String s = new String(bytes, "utf-8");
// 使用response对象 设置响应数据
resp.setHeader("content-type","text/html;charset=utf-8");
// 输出流默认的编码是ISO-8859-1,不支持中文;此时将流的编码设置为utf-8 "text/html;charset=utf-8"
resp.getWriter().write("<h1>"+s+",欢迎您!<h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
③Request请求转发
(2)Response:
将请求数据处理后,服务端中的tomcat会发送一些响应的字符串给浏览器,浏览器解析响应数据。我们通过Response对象来设置响应数据,tomcat会在响应前会将对象里面设置好的字符串发送给浏览器。
①Response 设置响应数据功能介绍
②Response 完成重定向(重定向需要虚拟目录,可以采取动态的方式获取,降低耦合性)
package com.itheima.web.response;
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("/resp1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("resp1~~");
/*
// 重定向
// 1.设置响应状态码 302
resp.setStatus(302);
// 2.设置响应头 Location
resp.setHeader("Location","/web-dem/resp2");
*/
// 简化方式定义重定向
//resp.sendRedirect("/web-dem/resp2");
// 使用动态获取虚拟路径-->请求数据
String contextPath = req.getContextPath();
resp.sendRedirect(contextPath+"/resp2");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
关于路径问题:
③Response 响应字符数据
④Response 响应字节数据
取代第三步:
配置pom.xml文件
修改文件代码:
(3)案例
用户登录:
详情可以看:案例(用户登录与注册文章)
用户注册:
代码优化:
创建一个工具类,每次要获取SqlSessionFactory对象时,就调用这个工具类里面的方法,但是工厂只能创建一次(如果创建多次增加了负担),所以不能重复创建,采用静态代码块的方法
工具类代码:
package com.xiulian.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
static{
/*
*静态代码块会随着类的加载而自动执行,且只执行一次
*/
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory(){
return sqlSessionFactory;
}
}
5、JSP
(1)JSP快速入门
(2)JSP原理
(3)JSP脚本
(4)EL表达式
(5)JSTL标签
(6)MVC模式和三层架构
MVC:
servlet充当控制器,从模型里面获取数据存储到域中(例如request域),然后转发到jsp里面做页面展示。
三层架构:
两者的关系:
(7)案例
准备环境:
查询所有:
①编写Dao层(在mapper包下)
接口:
映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.BrandMapper">
<!-- 数据库别名修改,当数据库属性名跟实体类变量不同时,做此修改 -->
<resultMap id="brandResultMap" type="brand">
<result column="brand_name" property="brandName"></result>
<result column="company_name" property="companyName"></result>
</resultMap>
</mapper>
②编写service层(在service包下)
package com.itheima.service;
import com.itheima.mapper.BrandMapper;
import com.itheima.pojo.Brand;
import com.itheima.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
/*
Service 层,调用接口方法,返回结果
*/
public class BrandService {
// 获取连接工厂对象,因为工厂要被多次调用,所有设置成成员变量
SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
/*
*查询所有
* @return
*/
public List<Brand> selectAll(){
/*
* 这个里面是调用BrandMapper.selectAll();(运用mybatis)
*借用封装的工具类SqlSessionFactoryUtils,调用里面的方法获取
* SqlSession
*/
// 1.获取SqlSession对象
SqlSession sqlSession = factory.openSession();
// 2.获取BrandMapper,[BrandMapper.class]是接口
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
// 3.调用接口里面的方法
List<Brand> brands = mapper.selectAll();
// 4.释放资源
sqlSession.close();
return brands;
}
}
③编写web层代码(在web包下)
*编写HTML页面代码(超链接)(访问web下编写的SelectAllServlet文件)
*编写jsp页面代码(页面展示)(web下SelectAllServlet文件从Dao层得到的数据转发到jsp页面里然后在网页展示)
HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--超链接(访问到href所对应的虚拟目录)-->
<a href="/brand-demo/selectAllServlet">查询所有</a>
</body>
</html>
jsp代码:
<%@ page isELIgnored="false" %>
<%@ page contentType="text/html; charset=utf-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>筑基层</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
<tr>
<th>序号</th>
<th>品牌名称</th>
<th>企业名称</th>
<th>排序</th>
<th>品牌介绍</th>
<th>状态</th>
<th>操作</th>
</tr>
<c:forEach items="${brands}" var="brand" varStatus="status">
<tr align="center">
<td>${status.count}</td>
<td>${brand.brandName}</td>
<td>${brand.companyName}</td>
<td>${brand.ordered}</td>
<td>${brand.description}</td>
<c:if test="${brand.status == 1}">
<td>启用</td>
</c:if>
<c:if test="${brand.status != 1}">
<td>禁用</td>
</c:if>
<td>
<a href="#">修改</a><a href="#">删除</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
web层文件代码:
package com.itheima.web;
import com.itheima.pojo.Brand;
import com.itheima.service.BrandService;
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.util.List;
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.调用BrandService
List<Brand> brands = service.selectAll();
// 2.存入request域中
req.setAttribute("brands",brands);
// 3.转发到brand.jsp
req.getRequestDispatcher("/brand.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
问题及解决:
分别出现了404问题和500问题,在执行项目后,点击超链接出现的两个问题
404问题:web浏览器tomcat没有配置好,按照要求重写配置
500问题:数据库连接出了错,分别检查实体类Brand中的参数名是否和数据库依据jsp文件代码一致(我就是这个问题),检查mybatis核心配置文件里面数据库连接信息是否正确,检查映射文件sql语句是否有误等等~~
回顾主要流程:
1.首先准备好项目环境(导入对应的依赖、搭建文件结构、创建相应的数据库表、编写表的实体类、然后用mybatis完成与数据库的连接【mybatis核心配置文件(还有扫描执行映射文件的功能)】以及实现对数据库的操作【映射文件和对应的接口】)
2.编写Dao层,对数据库数据的操作就是Dao层(有的写成mapper层,里面就是mapper接口,拥有执行操作的方法)
3.编写service层,里面就是获取连接工厂而进一步获取sqlsession对象从而获取Dao层的mapper接口,进一步调用其中的方法,从而书写完毕一个操作的方法selectAll()方便web层调用这个方法得到数据(为了避免多次且浪费进程的情况,所以并不直接写获取连接的代码,而是单独创建一个util包里面写工具类代码SqlSessionFactoryUtils类)
4. 编写web层,首先在webapp下编写页面代码(HTML,jsp等),然后web层里面书写的类就是接收HTML的访问(超链接的跳转),这个类调用service层的操作方法获取数据存到request域中,并将数据转发到jsp页面里,然页面展现数据。
添加:
①编写Dao层(在mapper包下)
接口:
映射文件:不变
②编写service层(在service包下)
③编写web层代码(在web包下)
*编辑jsp文件(按钮事件绑定)(在原有展现页面的jsp里面声明按钮,然后新建一个让 按钮跳转的jsp页面【一个可以添加数据的表单页面,这个页面提交路径是web层的【AddServlet】)
*编写web层AddServlet代码(注意修改POST乱码问题)
修改:
回显数据:
①编写Dao层(在mapper包下)
接口:
映射文件:不变
②编写service层(在service包下)
③编写web层代码(在web包下)
*在brand.jsp页面中书写【修改】的跳转路径
*书写uptade.jsp页面,起到回显的作用,通过id显示对应的信息页面
*书写web层的selectByIdServlet代码,接收id,通过id调用对应的service方法获取对应数据,存到域中,将数据转发到uptade.jsp页面,让页面回显数据
修改数据:
①编写Dao层(在mapper包下)
接口:
②编写service层(在service包下)
③编写web层代码(在web包下)
将update.jsp页面数据提交到web层下的UpdateServlet,此层代码将数据接收封装后转发到查询所有的web层代码里,然后显示出修改后的所有数据页面
删除:
①编写Dao层(在mapper包下)
接口:
映射文件:
②编写service层(在service包下)
注意:一定不要忘记提交事务,否则会报错
③编写web层代码(在web包下)
④删除时显示是否确认删除的提示框
在brand.jsp页面的删除跳转路径中加入confirm()方法
brand-demo案例完全结构:
6、会话跟踪技术
(1)Cookie基本使用
(2)Cookie原理
在servlet创建cookie对象和保存的键值对,然后将其响应到客户端,客户端就会保存该cookie。在另外一个servlet里面接收cookie的请求,获取到对应的cookie的值。在浏览器未被关闭的情况下,访问第一个servlet后再访问第二个servlet就能验证cookie共享(如果关闭浏览器还想共享cookie就要设置cookie的保存时间)
(3)Cookie使用细节(cookie的持久化保存)
(4)Session基本使用
demo1网页
demo2网页
(5)Session原理
一个servlet获取session对象并存储值。另一个servlet也获取该session对象,并去获取对应的值。如何保证它们获取的session对象是同一个?这就涉及到了cookie,在第一个servlet中,客户端会将服务端传来的session的id用cookie保存下来,当该客户端再次请求服务端时会将session的id值传到服务端,服务端会根据对应id去获取session对象,以此保证一次会话不同请求中获取到的session的对象是同一个(其他客户端请求服务端时获取到的session对象时不同的)
(6)Session使用细节
(7)案例
项目名为RewriteBrand-demo
用户登录
流程:
前期准备:mybatis核心配置文件、映射文件、实体类等代码书写
按照三层架构模式进行编写
1.书写dao层(mapper层)
书写mapper接口方法,跟映射文件对应
2.书写service层
书写与接口中对应的方法,通过工具类获取连接工厂,通过mybatis利用映射文件数据库操作语句操作数据库,创建方法(一定要注意,每次都要清除对象(close),除了查询操作,其他操作要记得提交事务)
3.书写web层(准备相应的跳转前端页面或者前端展示页面)
获取网页提交过来的请求数据(username,password),调用service层对应方法返回user对象,通过判断user是否为空做出对应的操作。不为空,则登录成功,因为是一次会话多次请求,所以要用到会话跟踪技术(将登录成功的user对象存储到session),这样在跳转的页面里面也可以调用user对象的值,利用重定向跳转到selectAllServlet查询所有的功能,为什么要用重定向?因为登录请求和跳转的查询请求没有数据要共享,所以用重定向。为空,则登录失败,提示“用户名或密码错误”并转发到login.jsp页面,在request域中存入键值对(名,“用户名或密码错误”),后面通过jsp页面调用request的键来获取值。
记住用户
判断是否勾选记住用户:给复选框定义一个值value,如果不等于这个值则没有勾选(通过request域获取值,然后在登录成功的代码块中通过这个值去判断是否勾选记住用户)。如果判断为勾选,则为用户名和密码创建cookie对象,设置其存活时间,并发送给网页,这样每次用户勾选复选框后,服务端会自动将其保存在服务端,方便其调用。
获取cookie:服务器再次访问浏览器会自动携带cookie,所以我们要在页面获取到cookie数据后,设置到用户名和密码框中,分别在jsp页面中的username、password中设置value值(就是cookie.username.value)
问题及解决:
1.请求数据与响应数据不支持中文传输,所以要根据请求方式的不同进行转换
2.cookie不支持中文,所以要使用URL编码转换后再创建cookie
代码:
用户注册:
流程:
前期准备:mybatis核心配置文件、映射文件、实体类等代码书写
按照三层架构模式进行编写
1.书写dao层(mapper层)
书写mapper接口方法,跟映射文件对应
2.书写service层
判断是否注册成功,首先判断从浏览器传输回来的封装对象的数据是否存在,如果不存在则添加创建并返回true,如果存在则返回false。
3.书写web层(准备相应的跳转前端页面或者前端展示页面)
接收请求数据并封装为user对象,然后调用service层的判断注册方法返回一个Boolean类型的值,通过这个值判断是否创建成功,如果成功则转发到登录页面并显示“注册成功,请登录”的字样,如果没有成功则转发到注册页面并显示“用户名已存在”。
展示验证码:
大体流程:
在工具类包中加入生成验证码工具类,然后web层编写CheckCodeServlet能够对验证码进行前后端数据的转换;再去注册页面的jsp中去展现验证码输入框、验证码图片和单击换一张的按钮,其中验证码图片的路径(src)就是web层书写的对应文件代码,对验证码图片和按钮设置onclick绑定事件(根据绑定所写函数方法来进行验证码图片的更换),所设id的目的之一也是为了根据验证码的id获取验证码对象,把此对象的地址进行变更就会使得验证码图片改变(在函数方法的src里面将原有地址后面加一个参数,参数为随时在变化的时间,这样就达到了点击按钮或图片验证码更新的效果)
校验验证码:
大体流程:
首先在web层中的CheckCodeServlet代码文件中将生成的验证码存入到session中(因为时一次会话两次请求,所以要进行会话请求,不然验证码将会不一样),然后在web层的RegisterServlet代码文件中去获取用户输入的验证码(通过文本框name去获取)、获取程序随机生成的验证码(通过session原先保存的键值对获取),然后比较他们是否相等,如果不等,要显示验证码错误,然后跳转到注册页面。
7、Filter(过滤器)
可以将web资源里面重复书写的功能代码写在Filter里面,例如用户没有登录就不能访问登录后的页面,所以web资源里面要一个一个判断用户是否登录,如果没有登录就拒绝访问,这个时候就可以将这个判断写在Filter里面。
(1)Filter快速入门
(2)Filter执行流程
(3)Filter使用细节
8、Listener
9、AJAX
在没有接触ajax的时候,我们响应数据是通过将数据存在域里面,然后前端页面通过jsp进行数据调用实现动态的展示,使用ajax可以替换掉jsp,如下图:
Ajax的作用:
同步和异步:
同步:客户端发送请求到服务端,服务端处理请求(在这个期间客户端只有等待),服务端处理完毕后响应给客户端
异步:同样是客户端发送请求到服务端,服务端处理请求(在这个过程中,客户端不用等待服务器端,不会刷新页面,客户端可以去进行其他操作), 服务端处理完毕后响应给客户端
10.JSON
(1)基本语法
(2)数据转换