1. JDBC
- 概念:Java数据库连接,用Java语言操作数据库,本质是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包,我们可以使用这套接口(JDBC)变成,真正执行的代码是驱动jar包中的实现类
-
快速入门
/** * JDBC快速入门 */ public class JdbcDemo1 { public static void main(String[] args) throws Exception { //1. 导入驱动jar包 //2.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //3.获取数据库连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root"); //4.定义sql语句 String sql = "update account set balance = 2000 where id = 1"; //5.获取执行sql的对象 Statement Statement stmt = conn.createStatement(); //6.执行sql int count = stmt.executeUpdate(sql); //7.处理结果 System.out.println(count); //8.释放资源 stmt.close(); conn.close(); } }
2. Cookie和Session
2.1 会话技术
- 会话:一次会话中包含多次请求和相应
- 功能:在一次会话的范围内的多次请求间,共享数据
- 方式:
- 客户端会话技术:Cookie
- 服务端会话技术:Session
2.2 Cookie
-
概念:将数据保存到客户端
-
使用步骤:
-
创建Cookie对象,绑定数据
new Cookie(String name,String value)
-
发送Cookie对象
response.addCookie(Cookie cookie)
-
获取Cookie,拿到数据
Cookie[] request.getCookies()
-
-
实现原理:
- 基于响应头set-cookie和请求头cookie实现
-
cookie的细节
-
一次可不可以发送多个cookie?
- 可以
- 可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可
-
cookie在浏览器中保存多久?
- 默认情况下,当浏览器关闭后,Cookie数据被销毁
- 持久化存储:
- setMaxAge(int seconds)
- 正数:将Cookie数据写到硬盘的文件中。seconds是cookie存活时间
- 负数:默认值
- 零:删除cookie信息
- setMaxAge(int seconds)
-
cookie能不能存中文?
- tomcat 8之后才支持中文存储,但还是不支持特殊字符,建议使用URL编码存储,URL解析
-
cookie共享问题?
-
假设在一个tomcat服务器中,部署了多个web项目,能不能共享?
-
默认情况下不能共享
-
setPath(String path):设置cookie的获取范围。默认情况下设置当前的虚拟目录
-
如果要共享,则可以将path设置为“/”
-
-
不用的tomcat服务器间cookie共享问题
-
setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享
-
-
-
cookie的特点和作用
-
特点:浏览器对于单个cookie的大小有限制(4kb)以及对同一个域名下的总cookie数量也有限制(20个)
-
作用:
- cookie一般用于存少量不太敏感的数据
- 在不登陆的情况下,完成服务器对客户端的身份识别
-
-
案例:记住上一次访问时间
- 需求:访问一个Servlet,如果是第一次访问,则提示你为第一次访问,否则显示上次访问的时间
- 分析:采用Cookie来完成,在服务器中的Servlet判断是否有一个名为lastTime的cookie
-
2.3 JSP
-
概念:全程为Java Server Pages(java服务端页面),既可以指定html标签,又可以定义java代码,用于简化书写
-
原理:本质上就是一个Servlet,里面把html内容都自动添加了标签,不用再手动去写
2.4 Session
-
概念:服务器段会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
-
获取HttpSession对象:HttpSession session = request.getSession();
使用HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
-
原理
- Session的实现是依赖于Cookie的。
-
细节
-
当客户端关闭后,服务器不关闭,两次获取Session是否为同一个?
-
默认情况下不是
-
如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); response.addCookie(c);
-
-
客户端不关闭,服务器关闭后,两次获取的Session是同一个吗?
- 不是同一个,但是要确保数据不丢失
- session的钝化:在服务器正常关闭之前,将session对象序列化到硬盘上
- session的活化:在服务器启动后,将session文件转化为内存中的session对象即可
- 不是同一个,但是要确保数据不丢失
-
session的失效时间?
- 服务器关闭
- session对象调用invalidate()
- session默认失效时间 30分钟,可以选择性配置修改
-
-
session的特点
- session用于存储一次会话的多次请求的数据,存在服务器端
- session可以存储任意类型,任意大小的数据
-
session和cookie的区别
- sessio存储数据在服务器端,cookie在客户端
- session没有数据大小限制,cookie有
- session数据安全,cookie相对不安全
2. MVC和三层架构
2.1 MVC:开发模式
- jsp演变历史
- 早期只有servlet,只能使用response输出标签数据,非常麻烦
- 后来有了jsp,简化了Servlet的开发,如果过度使用jsp,在里面即写了大量的java代码,又写html表,造成难以维护和分工合作
- 再后来,java的web开发借鉴mvc开发模式,是的程序的设计更加合理
- MVC
- M:Model,模型。JavaBean
- 完成具体的业务操作,如:查询数据库,封装对象
- V:View,视图。JSP
- 展示数据
- C:Controller,控制器。Servlet
- 获取用户的输入
- 调用模型
- 将数据交给视图进行展示(用到域对象共享数据)
- M:Model,模型。JavaBean
- MVC优缺点
- 优点:耦合性低,方便维护,利于分工写作;重用性高
- 缺点:使得项目架构变得复杂,对开发人员要求高
2.2 三层架构:软件设计架构
-
界面层(表示层/web层):用户看到的界面。用户可以通过页面上的组件和服务器进行交互
-
业务逻辑层(service层):处理业务逻辑的。
-
数据访问层(dao层):操作数据存储文件。
可以这么说,表现层对应V和C,业务层和持久层对应M
参考博客https://blog.csdn.net/weixin_39722922/article/details/89185976
为什么不直接用Servlet调用数据,而是要添加一个业务逻辑层呢?
- dao层只定义对数据库最基本的CRUD操作,service层的业务逻辑对dao层的方法进行组合
-
案例:用户信息的增删改查操作
-
需求:用户信息的增删改查操作
-
设计:
-
技术选型:Servlet+JSP+MySQL+JDBCTempleat+Duird+BeanUtils+tomcat
-
数据库设计:
create database day17;
use day17;
create table user(
id int primary key auto_increament,
name varchar(20) not null,
gender varchar(5),
…
);
-
-
开发:
- 环境搭建
- 创建数据库环境
- 创建项目,导入需要的jar包
- 编码
- 环境搭建
-
测试
-
部署运维
-
3. Filter和Listener
3.1 Filter:过滤器
-
概念:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能,一般用于完成通用的操作,如:登录验证、统一编码处理、敏感字符过滤
-
快速入门:
- 定义一个类,实现接口Filter
- 复写方法
- 配置拦截路径
- web.xml
- 注解,如:@WebFilter("/*")
-
过滤器细节:
-
web.xml配置
<filter> <filter-name>demo1</filter-name> <filter-class>cn.itcast.web.filter.FilterDemo1</filter-class> </filter> <filter-mapping> <filter-name>demo1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
过滤器执行流程
- 执行过滤器
- 执行放行后的资源
- 回来执行过滤器放行代码下边的代码
-
过滤器生命周期方法
- init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次,用于加载资源
- doFilter:每一次请求被拦截资源时会执行,执行多次
- destroy:在服务器关闭后,Filter对象被销毁。如果服务器正常关闭,则会执行destroy方法,只执行一次,用于释放资源
-
过滤器配置详解
- 拦截路径配置
- index.jsp
- /user/*
- *.jsp //前面不用加/
- /*
- 拦截方式配置
- 注解配置:设置dispatcherTypes属性{可以用大括号组合使用}
- REQUEST:默认值,直接请求的时候过滤
- FORWARD:转发请求到该资源才过滤
- INCLUDE:包含访问资源
- ERROR:错误跳转资源
- ASYNC:异步访问资源
- web.xml配置
- 设置标签即可
- 注解配置:设置dispatcherTypes属性{可以用大括号组合使用}
- 拦截路径配置
-
过滤器链(配置多个过滤器)
-
执行顺序:如果有两个过滤器
- 过滤器1->过滤器2->资源执行->过滤器2->过滤器1
-
控制先后顺序
- 注解配置:按照类名的字符串比较规则比较,值小的先执行
- 如:AFilter和BFilter,AFilter先执行
- web.xml配置:谁定义在上边,谁先执行
- 注解配置:按照类名的字符串比较规则比较,值小的先执行
-
-
案例
- 案例1_登录验证
- 案例2_敏感词汇过滤:如果是敏感词汇,替换为***
- 分析:对request对象进行增强,request本身没有改变的方法
- 增强对象的功能:设计模式
- 装饰模式
- 代理模式
- 概念
- 真实对象:被代理的对象
- 代理对象
- 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
- 实现方式
- 静态代理:又一个类文件描述代理模式
- 动态代理:在内存中形成代理类
- 实现步骤:
- 代理对象和真实对象实现相同的接口
- 代理对象 = Proxy.newProxyInstance();
- 使用代理对象调用方法
- 增强方法
- 增强方式
- 增强参数列表
- 增强返回值类型
- 增强方法体执行逻辑
- 实现步骤:
- 概念
public class ProxyTest { public static void main(String[] args) { Lenove lenove = new Lenove(); /* 代码逻辑编写的方法:代理对象调用的所有方法都会触发该方法执行 参数: 1.proxy:代理对象(一般不会用) 2.metod:代理对象调用的方法,被封装为的对象 3.args:代理对象调用的方法时,传递的实际参数 */ SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenove.getClass().getClassLoader(), lenove.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("sale")){ //1.增强参数 double money = (double) args[0]; money = money * 0.85; System.out.println("专车接"); //使用真实对象调用该方法 String obj = (String) method.invoke(lenove, money); System.out.println("包邮送"); //2.增强返回值 return obj+"_鼠标垫"; }else { String obj = (String) method.invoke(lenove, args); return obj; } } }); //3.调用方法 String computer = proxy_lenovo.sale(8000); System.out.println(computer); // proxy_lenovo.show(); } }
public class Lenove implements SaleComputer { @Override public String sale(double money) { System.out.println(money +"块买了一台联想电脑"); return "联想电脑"; } @Override public void show() { System.out.println("展示电脑..."); } }
-
3.2 Listener:监听器
-
概念:web的三大组件之一
- 事件监听机制:事件,事件源,监听器,注册监听
-
ServletContextListener:监听ServletContext对象的创建和销毁
-
方法:
//ServletContext对象被销毁之前会调用该方法 void contextDestroyed(ServletContextEvent servletContextEvent)
void contextInitialized(ServletContextEvent servletContextEvent)
-
步骤:
-
定义各个类实现ServletContextListener接口
-
复写方法
-
配置
-
web.xml
<listener> <listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class> </listener>
-
注解 @WebListener
-
-
-
4. Maven
4.1 初级
-
基本概念
Maven是一个项目管理工具,可以解决如下问题
- 自动引入jar包并解决jar包冲突,且jar包可重用,坐标在pom.xml中配置
- 可以同时进行多个单元测试
- 有丰富的命令方便项目的打包和发布
-
项目的构建
- Tomcat部署过程全部都是手动,将项目自己打包放在webapp目录下,找到startup命令才能把项目运行起来
- Maven运行一个项目,只需要在命令行进入项目地址后,输入mvn tomcat:run就行
-
标准目录结构
- src/main/java 核心代码部分
- src/main/resources 配置文件部分
- src/test/java 测试代码部分
- src/test/resources 测试配置文件
- src/main/webapp 页面资源,js,css,图片等等
-
常用命令
- mvn clean 删除编译文件target目录及内容(别人的项目在自己电脑上运行首先执行这个命令,环境不一样)
- mvn compile 作用是将src/main/java下的文件编译为class文件输出到target目录下。
- mvn test 会执行src/test/java下的单元测试类
- mvn package 对于java工程执行package打成jar包,对于web工程打成war包
- mvn install 将maven打成jar包或war包发布到本地仓库
- 当后面的命令执行时,前面的操作过程也都会自动执行; 加上deploy发布命令,去掉clean就是一套默认生命周期
-
maven概念模型图
-
创建maven的java工程
- 使用或不使用骨架创建没有太大区别,只要自己把目录结构创建后就行
4.2 分模块构建
4.2.1 传统的web工程做一个数据查询
-
准备数据库,web.xml约束,将pom无关的依赖删除
-
maven导入jar包时冲突
原因:不同的jar包有相同的依赖包,而且jar包的版本不同,那依赖包版本听谁的呢
解决办法
-
第一声明优先原则:哪个jar包的坐标靠上的位置,这个jar包就是先声明的,先声明的jar包坐标下的依赖包可以优先进入项目中
-
路径近者优先原则:直接依赖路径比传递依赖路径近,那么最终项目进入的jar包会是路径的直接依赖
直接依赖:项目中直接导入的jar包,就是该项目的直接依赖包
传递依赖:项目中没有直接导入的jar包,可以通过项目直接依赖jar包传递到项目中
-
直接排除法(推荐使用):当我们要排除某个jar包下依赖包,在配置exclusions标签的时候,内部可以不写版本号,因为此时依赖包使用的版本默认和本jar包一样
-
-
将提前准备好的三大框架的pom文件全部导入进来,如果后期还有其他jar包要导入,先在show dependecies看一下这个包依赖的包与项目中的包版本是否符合
-
对pom文件内标签的讲解
-
dependencyManagement:可以用来锁定jar包版本
maven工程是可以分父子依赖关系的。
凡是依赖别的项目后,拿到的别的项目的依赖包,都属于传递依赖。
比如:当前A项目,被B项目依赖。那么我们A项目中所有jar包都会传递到B项目中。
B项目开发者,如果再在B项目中导入一套ssm框架的jar包,对于B项目是直接依赖。
那么直接依赖的jar包就会把我们A项目传递过去的jar包覆盖掉。
为了防止以上情况的出现。我们可以把A项目中主要jar包的坐标锁住,那么其他依赖该项目的项目中,
即便是有同名jar包直接依赖,也无法覆盖。 -
build
<!-- 添加tomcat7插件 --> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> </plugin> </plugins> </build>
-
properties:键值对的形式,pom文件可以这么些是因为头上有这样的约束
<!-- 统一管理jar包版本 --> <properties> <spring.version>5.0.2.RELEASE</spring.version> <slf4j.version>1.6.6</slf4j.version> <log4j.version>1.2.12</log4j.version> <shiro.version>1.2.3</shiro.version> <mysql.version>5.1.6</mysql.version> <mybatis.version>3.4.5</mybatis.version> <spring.security.version>5.0.1.RELEASE</spring.security.version> </properties>
-
-
向SSM的整合一样,写一个根据id查询名字的项目,有些配置有些细微的差别,项目部署直接使用的maven:run
4.2.2 改进项目结构
-
maven工程拆分与聚合的思想
-
建立项目结构
-
创建一个maven工程的项目,并且只留下pom.xml和iml文件
-
在项目里面创建模块,web使用web-app骨架
-
工程和模块的区别
工程不等于完整的项目,模块也不等于完整的项目,一个完整的项目看的是代码,代码完整,就可以说这是一个完整的项目 和此项目是工程和模块没有关系。 工程天生只能使用自己内部资源,工程天生是独立的。后天可以和其他工程或模块建立关联关系。 模块天生不是独立的,模块天生是属于父工程的,模块一旦创建,所有父工程的资源都可以使用。 父子工程直接,子模块天生集成父工程,可以使用父工程所有资源。 子模块之间天生是没有任何关系的。 父子工程直接不用建立关系,继承关系是先天的,不需要手动建立。 平级直接的引用叫依赖,依赖不是先天的,依赖是需要后天建立的。
-
直接在这个模块的pom文件中引入需要的模块,以后dao模块里面的所有东西都属于service
<dependency> <groupId>com.itheima</groupId> <artifactId>maven_day02_dao</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
-
传递依赖下来的包是否能用
-
将传统工程的代码分层引入到新项目的模块下,然后在表现层中引入sping配置文件分成的两块
<import resource="classpath:spring/applicationContext-dao.xml"/> <import resource="classpath:spring/applicationContext-service.xml"/>
-
三种启动方式
- maven内置的tomcat插件,直接在parent工程下面双击run
- maven内置的tomcat插件,在web工程(表现层)run
- 本地仓库没有被引入的service和dao的jar包,不能直接启动,需要在parent的maven项目中先install一下
- 使用本地安装的tomcat
-