JavaWeb-Maven
分模块设计与开发
如果都是一个整体,不便维护,难以复用
分模块设计
直接在tlias-web-management里引入tlias-pojo和tlias-utils的依赖
1 | 创建maven模块 tlias-pojo,存放实体类。 |
step1:创建maven模块tlias-pojo,存放实体类
step2:在主程序中引用模块
继承与聚合
继承
概念:继承描述的是两个工程之间的关系,和java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承。
作用:简化依赖配置,统一管理依赖
1 | 实现:<parent>...</parent> |
继承关系实现
① 创建maven模块 tlias-parent ,该工程为父工程,设置打包方式pom(默认jar)。
打包方式:
jar:普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)
war:普通web程序打包,需要部署在外部的tomcat服务器中运行
pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理
1 | <parent> |
② 在子工程的pom.xml文件中,配置继承关系
1 | 在子工程中,配置了继承关系之后,坐标中的groupId是可以省略的,因为会自动继承父工程的 。 |
③ 在父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)。
1 | <dependencies> |
ps:若父子工程都配置了同一个依赖的不同版本,以子工程的为准。
版本锁定
1 | 在maven中,可以在父工程的pom文件中通过 <dependencyManagement> 来统一管理依赖版本 |
1 | <dependencyManagement> 与 <dependencies>的区别是什么? |
聚合
要把几个模块全部安装到本地之后才能打包
1 | 聚合 |
1 | maven中可以通过 <modules> 设置当前聚合工程所包含的子模块名称 |
1 | <!--聚合-->父工程(聚合工程) |
l聚合工程中所包含的模块,在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关。
总结
作用
- 聚合用于快速构建项目
- 继承用于简化依赖配置、统一管理依赖
相同点:
- 聚合与继承的pom.xml文件打包方式均为pom,可以将两种关系制作到同一个pom文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
不同点:
- 聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的中央仓库,用于解决团队内部的资源共享与资源同步问题。
JavaWeb-Springboot-2
配置优先级
从上至下优先级
命令行参数>java系统属性
Bean管理
Spring项目启动时,会把bean都创建好放到IOC容器当中,如果想要主动获取这些bean:
bean的获取
在spring容器中,bean默认是单例的
作用域 | 说明 |
---|---|
singleton | 容器内同 名称 的 bean 只有一个实例(单例)(默认) |
prototype | 每次使用该 bean 时会创建新的实例(非单例) |
request | 每个请求范围内会创建新的实例(web环境中,了解) |
session | 每个会话范围内会创建新的实例(web环境中,了解) |
application | 每个应用范围内会创建新的实例(web环境中,了解) |
1 | @Scope("prototype") |
注意事项
默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时)。
prototype的bean,每一次使用该bean的时候都会创建一个新的实例。
实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性。
第三方bean
1 | @Component |
如果要管理的bean对象来自于第三方(不是自定义的,是无法用@Component以及衍生注解声明bean的,就是需要用到@Bean注解)
一、用启动类,不建议
二、用第三方bean对象
用配置类声明第三方bean对象
通过 @Bean注解的name/value属性指定bean名称,如果没有指定,默认是方法名
SpringBoot原理
起步依赖
Maven存在一个依赖传递,只要提供一个起步依赖
自动配置
SpringBoot的自动配置就是当spring容器启动之后,一些配置类,bean对象就自动的存入了IOC容器中,不需要我们手动去声明
当想要实现从另外一个项目引入
springboot只能扫描到启动类及其子包,扫描不到其他的包
方案一:ComponentScan(使用繁琐,效率低)
1 | @ComponentScan({"com.example","com.itheima"}) |
方案二:@Import 导入。
使用@Import导入的类会被Spring加载到IOC容器中,导入形式主要有以下几种:
- 导入 普通类
- 导入 配置类
- 导入 ImportSelector 接口实现类
@EnableXxxx注解,封装@Import注解
源码跟踪
@SpringBootApplication
——->
1 | @SpringBootConfigration |
@Conditional
以conditional开头的注解都是条件装配的注解
作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring IOC容器中。
位置:方法、类
@Conditional 本身是一个父注解,派生出大量的子注解:
- @ConditionalOnClass:判断环境中是否有对应字节码文件,才注册bean到IOC容器。
- @ConditionalOnMissingBean:判断环境中没有对应的bean(类型 或 名称) ,才注册bean到IOC容器。
- @ConditionalOnProperty:判断配置文件中有对应属性和值,才注册bean到IOC容器。
1 | @Bean |
自定义starter
需求:自定义aliyun-oss-spring-boot-starter,完成阿里云OSS操作工具类 AliyunOSSUtils 的自动配置。
目标:引入起步依赖引入之后,要想使用阿里云OSS,注入 AliyunOSSUtils直接使用即可。
不想听了
总结
三层架构
JavaWeb-Springboot
表单校验、拦截
会话技术
会话:
用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
会话跟踪:
一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
会话跟踪方案:
客户端会话跟踪技术:Cookie
优点:HTTP协议中支持的技术
缺点:
移动端APP无法使用Cookie
不安全,用户可以自己禁用Cookie
Cookie不能跨域
服务端会话跟踪技术:Session
优点:存储在服务端,安全
缺点:
服务器集群环境下无法直接使用Session
Cookie的缺点
令牌技术
JWT令牌
过滤器Filter
概念:filter 过滤器,是javaweb三大组件(Servlet,filter,listener)之一;
过滤器可以把一些对于资源的请求拦截下来,从而实现一些特殊的功能。
过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理,敏感字符处理等
1.定义Filter:定义一个类,实现 Filter 接口,并重写其所有方法。
2.配置Filter:Filter类上加 @WebFilter 注解,配置拦截资源的路径。引导类上加 @ServletComponentScan 开启Servlet组件支持。
1 | @WebFilter(urlPatterns = "/*") |
doFilter
Filter快速入门
定义:实现Filter接口
配置:@WebFilter(urlPatterns=”/*”)
@ServletComponentScan
详解(执行流程、拦截路径,过滤器链)
执行流程
1 | chain.doFilter(request,response); |
l放行后访问对应资源,资源访问完成后,还会回到Filter中吗?==会==
l如果回到Filter中,是重新执行还是执行放行后的逻辑呢?==执行放行后逻辑==
拦截路径
Filter 可以根据需求,配置不同的拦截资源路径:
拦截路径 | urlPatterns值 | 含义 |
---|---|---|
拦截具体路径 | /login | 只有访问 /login 路径时,才会被拦截 |
目录拦截 | /emps/* | 访问/emps下的所有资源,都会被拦截 |
拦截所有 | /* | 访问所有资源,都会被拦截 |
过滤器链
介绍:一个web应用中,可以配置多个过滤器,这多个过滤器酒形成了一个过滤器链。
登录校验filter
请求头中携带令牌(token)
1. 获取请求url
1 | String url = req.getRequestURL().toString(); |
拦截器Interceptor
简介和快速入门
概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。
作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。
详解
拦截器-拦截路径
拦截路径 | 含义 | 举例 |
---|---|---|
/* | 一级路径 | 能匹配/depts,/emps,/login,不能匹配 /depts/1 |
/** | 任意级路径 | 能匹配/depts,/depts/1,/depts/1/2 |
/depts/* | /depts下的一级路径 | 能匹配/depts/1,不能匹配/depts/1/2,/depts |
/depts/** | /depts下的任意级路径 | 能匹配/depts,/depts/1,/depts/1/2,不能匹配/emps/1 |
执行流程
登录校验- Interceptor
出现异常,该如何处理?
方案一:在Controller的方法中进行try…catch处理
方案二:全局异常处理器
事务管理和AOP
事务管理
概念
事务时一组操作的集合,它是一个不可分割的工作单位,这些操作==要么同时成功,要么同时失败==
操作
开启事务(一组操作开始前,开启事务):start transaction / begin;
提交事务 (这组操作全部成功后,提交事务):commit;
回滚事务(中间任何一个操作出现异常,回滚事务):rollback;
Spring事务管理
@Transactional
事务进阶
rollbackFor–回滚
默认情况下,只有出现 RuntimeException 才回滚异常。rollbackFor属性用于控制出现何种异常类型,回滚事务。
propagation–传播
事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。
属性值 | 含义 |
---|---|
REQUIRED | 【默认值】需要事务,有则加入,无则创建新事务 |
REQUIRES_NEW | 需要新事务,无论有无,总是创建新事务 |
SUPPORTS | 支持事务,有则加入,无则在无事务状态中运行 |
NOT_SUPPORTED | 不支持事务,在无事务状态下运行,如果当前存在已有事务,则挂起当前事务 |
MANDATORY | 必须有事务,否则抛异常 |
NEVER | 必须没事务,否则抛异常 |
… |
AOP
AOP概述(Aspect Oriented Programming)
面向切面编程,面向方向编程,面向特定方法编程
动态代理技术是实现面向切面编程最主流的方法
场景:案例部分功能运行较慢,定位执行耗时较长的业务方法,此时需要统计每一个业务方法的执行耗时。
实现:动态代理是面向切面编程最主流的实现,而springAOP是Spring框架的高级技术, 旨在管理bean对象的过程中,主要通过底层的动态代理机制,对特定的方法进行编程。
优点:
- 在没有对于原始方法进行修改的同时,代码无侵入
- 减少重复代码
- 提高开发效率
- 维护比较方便
1 | <dependency> |
理解来说,就是把原始的方法进行包装,在这个AOP类中就可以定义在运行原始方法前运行什么操作。
AOP快速入门
AOP核心概念
- 连接点:JoinPoint,可以被AOP控制的方法(暗含方法执行时的相关信息)
- 通知:Advice,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)
- 切入点:PointCut,匹配连接点的条件,通知仅会在切入点方法执行时被应用
- 切面:Aspect,描述通知与切入点的对应关系(通知+切入点)
- 目标对象:Target,通知所应用的对象
一旦执行了AOP流程,执行对象的目标不是原来的对象,而是代理对象
通知类型
以上也是切入点表达式,存在重复问题,需要将其抽取。
public :表示在其他外部的切面类中也可以应用该表达式
private:在其他外部的切面类红也可以引用该表达式
通知顺序
当有多个切面的切入点都匹配到了目标方法,目标方法运行时,多个通知方法都会被执行。
1.不同切面类中,默认按照切面类的类名字母排序:
目标方法前的通知方法:字母排名靠前的先执行
目标方法后的通知方法:字母排名靠前的后执行
2.在切面类上添加order注解
切入点表达式
基础
切入点表达式:描述切入点方法的一种表达式
作用:主要用来决定项目中的哪些方法需要加入通知
常见形式:
1.execution(……):根据方法的签名来匹配
2.@annotation(……) :根据注解匹配
1 | execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?) |
其中带 ? 的表示可以省略的部分
访问修饰符:可省略(比如: public、protected)
包名.类名: 可省略
可以省略但是不建议,不然会使得匹配的范围过大
throws 异常:可省略(注意是方法上声明抛出的异常,不是实际抛出的异常)
@annotation(……)
定义注解,这个注解起到一个标识的作用
@annotation 切入点表达式,用于匹配标识有特定注解的方法。
连接点
可以被AOP控制的方法
在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,比如目标类名,方法名。
就是把之前的那些给抽象了
对于 @Around 通知,获取连接点信息只能使用 ProceedingJoinPoint
1 | @Around("execution(* com.itheima.service.DeptService.*(..))") |
1 | @Before("execution(* com.itheima.service.DeptService.*(..))") |
AOP案例
步骤
step1:自定义注解
step2:编写切面类
1 | //LogAspect.java |
JavaWeb-Mybatis
什么是Mybatis?
数据层又叫做持久层
MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。
Mybatis入门
mybatis快速入门
使用Mybatis查询所有用户数据
Mapper层:mybatis的接口层。加mapper注释,数据访问层dao层的接口,
要执行语句那句select语句时,只需要使用list方法,就会默认的调用这个语句,sql语句的访问结果就会默认的封装到这个方法里
step1:准备数据库
运行sql语句创建数据库
step2:创建springboot项目,点上mybatis之类的tool
step3:连接数据库
step4:创建实体类pojo
可以直接用mybatis-generator生成
step5:创建mapper接口层
@Mapper//在运行时,会自动生成该接口的实现类对象(代理对象),并且将该对象交给IOC容器管理
1 | package com.ljy.demo5.mapper; |
step6:测试
在test项目里测试
1 | @SpringBootTest//springboot整合单元测试的注解 |
输出结果
JDBC介绍
java database connectivity,就是使用java语言操作关系型数据库的一套API,这是一套规范,sun公司提供的
各个厂商提供jdbc的实现,这个叫做jdbc的驱动、数据库的驱动
数据库连接池
数据库连接池是一个容器,负责分配、管理数据库连接(connection)
它允许应用程序重复使用一个现有的数据库连接,而不是再重新创建一个新的
释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏。
切换Druid数据库连接池
1 | <dependency> |
1 | spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver |
小结
1.数据库连接池
l是一个容器,负责分配、管理数据库连接(Connection)
l优势:资源复用、提升系统响应速度
l接口:DataSource
l产品:C3P0、DBCP、Druid、Hikari
Lombok
Lombok是一个实用的Java类库,能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率。
注解 | 作用 |
---|---|
@Getter/@Setter | 为所有的属性提供get/set方法 |
@ToString | 会给类自动生成易阅读的 toString 方法 |
@EqualsAndHashCode | 根据类所拥有的非静态字段自动重写 equals 方法和 hashCode 方法 |
@Data | 提供了更综合的生成代码功能(@Getter + @Setter + @ToString + @EqualsAndHashCode) |
@NoArgsConstructor | 为实体类生成无参的构造器方法 |
@AllArgsConstructor | 为实体类生成除了static修饰的字段之外带有各参数的构造器方法。 |
Lombok会在编译时,自动生成对应的java代码。我们使用lombok时,还需要安装一个lombok的插件(idea自带)。
Mybatis基础增删改查
准备
按照之前的准备
删除
按照ID删除数据
@Delete注释
占位符 #{id}
1 | @Delete("delete from emp where id = #{id}") |
1 | @Mapper |
日志
预编译sql语句
- 性能更高
- 更安全(防止SQL注入)
SQL注入
通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。
插入
1 | //新增员工 |
1 | @Test |
主键返回@Options(keyProperty=”id”)
描述:在数据添加成功后,需要获取插入数据库数据的主键。如:添加套餐数据时,还需要维护套餐菜品关系表数据。
更新(修改)
1 | //更新员工 |
1 | @Test |
查询
1 | @Select("select * from emp where id = #{id}") |
1 | @Test |
数据封装
解决一
1 | //方案三: 开启mybatis的驼峰命名自动映射开关 --- a_cloumn ------> aColumn |
MybatisXML映射文件
xml映射文件
Mybatis动态SQL
随着用户的输入或者外部的变化而变化SQL语句,我们称为动态SQL
if
1 | <if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。 |
foreach
Springboot案例
分页参数
文件上传
表单项
文件上传
JavaWeb-mysql
数据库设计
Mysql概述
分类 | 全称 | 说明 |
---|---|---|
DDL | Data Definition Language | 数据定义语言,用来定义数据库对象(数据库,表,字段) |
DML | Data Manipulation Language | 数据操作语言,用来对数据库表中的数据进行增删改 |
DQL | Data Query Language | 数据查询语言,用来查询数据库中表的记录 |
DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
数据库设计-DDL
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段值不能为null | not null |
唯一约束 | 保证字段的所有数据都是唯一、不重复的 | unique |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | primary key |
默认约束 | 保存数据时,如果未指定该字段值,则采用默认值 | default |
外键约束 | 让两张表的数据建立连接,保证数据的一致性和完整性 | foreign key |
MySQL中的数据类型有很多,主要分为三类:数值类型、字符串类型、日期时间类型。
数据表
create_time:记录的是当前这条数据插入的时间。 update_time:记录当前这条数据最后更新的时间
表(创建、查询、修改、删除)
多表设计
数据库操作
数据库操作-DML
DML的英文全称是data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增删改查操作
1 | 添加数据(INSERT) |
INSERT
指定字段添加数据:insert into 表名 (字段名1, 字段名2) values (值1, 值2);
全部字段添加数据:insert into 表名 values (值1, 值2, …);
批量添加数据(指定字段):insert into 表名 (字段名1, 字段名2) values (值1, 值2), (值1, 值2);
批量添加数据(全部字段):insert into 表名 values (值1, 值2, …), (值1, 值2, …);
update
修改数据:update 表名 set 字段名1 = 值1 , 字段名2 = 值2 , …. [ where 条件 ] ;
修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据。
DELETE
删除数据:delete from 表名 [ where 条件 ];
1.DELETE 语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据。
2.DELETE 语句不能删除某一个字段的值(如果要操作,可以使用UPDATE,将该字段的值置为NULL)。
数据库操作-DQL SELECT
DQL英文全称是Data Query Language(数据查询语言),用来查询数据库表中的记录。
查询多个字段:select 字段1, 字段2, 字段3 from 表名;
查询所有字段(通配符):select * from 表名;
设置别名:select 字段1 [ as 别名1 ] , 字段2 [ as 别名2 ] from 表名;
去除重复记录:select distinct 字段列表 from 表名;
事务
介绍
事务 是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作 要么同时成功,要么同时失败。
1 | 开启事务:start transaction; / begin ; |
四大特性(ACID)
多表查询
一对一
一对多
多对对
数据库优化
索引
SQL优化
JavaWeb
JS
1.JS引入方式
2.变量
JavaScript 中用 var 关键字(variable 的缩写)来声明变量 。
JavaScript 是一门弱类型语言,变量可以存放不同类型的值 。
变量名需要遵循如下规则:
Ø组成字符可以是任何字母、数字、下划线(_)或美元符号($)
Ø数字不能开头
Ø建议使用驼峰命名
ECMAScript 6 新增了 let 关键字来定义变量。它的用法类似于 var,但是所声明的变量,只在 let 关键字所在的代码块内有效,且不允许重复声明。
ECMAScript 6 新增了 const 关键字,用来声明一个只读的常量。一旦声明,常量的值就不能改变。
•var:声明变量,全局作用域/函数作用域,允许重复声明
• let:声明变量,块级作用域,不允许重复声明
• const:声明常量,一旦声明,常量的值不能改变
3.数据类型
JavaScript中分为:原始类型 和 引用类型。
var 变量名 = new Array(元素列表);
4.BOW
Browser Object Model 浏览器对象模型,允许JavaScript与浏览器对话, JavaScript 将浏览器的各个组成部分封装为对象。
location地址对象:就是那个框
属性
history:对 History 对象的只读引用。请参阅 History 对象。
location:用于窗口或框架的 Location 对象。请参阅 Location 对象。
navigator:对 Navigator 对象的只读引用。请参阅 Navigator 对象。
方法
alert():显示带有一段消息和一个确认按钮的警告框。
confirm():显示带有一段消息以及确认按钮和取消按钮的对话框。
setInterval():按照指定的周期(以毫秒计)来调用函数或计算表达式。
setTimeout():在指定的毫秒数后调用函数或计算表达式。
5.DOM(概念:Document Object Model ,文档对象模型)
6.事件监听
事件:HTML事件是发生在HTML元素上的 “事情”。比如:
1 | 按钮被点击 |
事件监听:JavaScript可以在事件被侦测到时 执行代码。
事件绑定
方式一:通过 HTML标签中的事件属性进行绑定
1 | <input type="button" onclick="on()" value="按钮1"> |
方式二:通过 DOM 元素属性绑定
1 | <input type="button" id="btn" value="按钮2"> |
常见事件
7.Vue
Vue 是一套前端框架,免除原生JavaScript中的DOM操作,简化书写。
基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定,将编程的关注点放在数据上。
Vue快速入门
常用指令
指令:HTML 标签上带有 v- 前缀 的特殊属性,不同指令具有不同含义。例如:v-if,v-for…
常用指令
指令 | 作用 |
---|---|
v-bind | 为HTML标签绑定属性值,如设置 href , css样式等 |
v-model | 在表单元素上创建双向数据绑定 |
v-on | 为HTML标签绑定事件 |
v-if | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-else-if | |
v-else | |
v-show | 根据条件展示某元素,区别在于切换的是display属性的值 |
v-for | 列表渲染,遍历容器的元素或者对象的属性 |
指令 | 作用 |
---|---|
v-bind | 为HTML标签绑定属性值,如设置 href , css样式等 |
v-model | 在表单元素上创建双向数据绑定 |
通过v-bind或者v-model绑定的变量,必须在数据模型中声明。
生命周期
生命周期:指一个对象从创建到销毁的整个过程。
生命周期的八个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法(钩子)。
状态 | 阶段周期 |
---|---|
beforeCreate | 创建前 |
created | 创建后 |
beforeMount | 挂载前 |
mounted | 挂载完成 |
beforeUpdate | 更新前 |
updated | 更新后 |
beforeDestroy | 销毁前 |
destroyed | 销毁后 |
生命周期的八个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法(钩子)
1 | <script> |
mounted:挂载完成,Vue初始化成功,HTML页面渲染成功。(发送请求到服务端,加载数据)
Maven
Maven是apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。
基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建。
作用
依赖管理:方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题
统一项目结构:提供标准、统一的项目结构
项目构建:标准跨平台(Linux、Windows、MacOS)的自动化项目构建方式
清理、编译、测试、打包、发布
Maven概述
Maven坐标
Maven 中的坐标是资源的唯一标识,通过该坐标可以唯一定位资源位置。
使用坐标来定义项目或引入项目中需要的依赖。
Maven 坐标主要组成
groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.itheima)
artifactId:定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
version:定义当前项目版本号
依赖配置
依赖:指当前项目运行所需要的jar包,一个项目中可以引入多个依赖。
1 | 1.在 pom.xml 中编写 <dependencies> 标签 |
1 | <dependencies> |
依赖具有传递性
直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
排除依赖
排除依赖指主动断开依赖的资源,被排除的资源无需指定版本。
依赖范围
依赖的jar包,默认情况下,可以在任何地方使用。可以通过
1 | <scope>…</ scope > |
设置其作用范围。
作用范围:
scope****值 | 主程序 | 测试程序 | 打包(运行) | 范例 |
---|---|---|---|---|
compile(默认) | Y | Y | Y | log4j |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc驱动 |
生命周期
Maven的生命周期就是为了对所有的maven项目构建过程进行抽象和统一。
Maven中有3套相互独立的生命周期:
在同一套生命周期中,当运行后面的阶段时,前面的阶段都会运行。
- clean:清理工作。
- default:核心工作,如:编译、测试、打包、安装、部署等。
- site:生成报告、发布站点等。
1 | clean:移除上一次构建生成的文件 |
Spring
Spring Framework配置比较繁琐,入门的难度比较大
Sprint Boot简化配置,快速入门
SpringBootWeb入门
Controller类
HTTP协议
HTTP-概述
基于请求-响应模型:一次请求对应一次响应
基于TCP协议:面向连接、安全
HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。
缺点:多次请求间不能共享数据
优点:速度快
Hyper Text Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。
HTTP-请求协议
get
post
HTTP-响应协议
200 | 客户端请求成功。 |
---|---|
404 | 请求资源不存在,般是URL输入有误,或者网站资源被删除了。 |
500 | 服务器发生不可预期的错误。 |
HTTP-协议解析
Web服务器-Tomcat
Web服务器 对HTTP协议操作进行封装,简化web程序开发
部署web项目,对外提供网上信息浏览服务。
Tomcat简介
一个轻量级的web服务器,支持servlet、jsp等少量javaEE规范。
也被称为web容器、servlet容器。
- 概念: Tomcat是Apache 软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。
- JavaEE:Java Enterprise Edition,Java企业版。指Java企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、EJB、RMI、JSP、Servlet、XML、JMS、Java IDL、JTS、JTA、JavaMail、JAF
- Tomcat 也被称为 Web容器、Servlet容器。Servlet程序需要依赖于 Tomcat才能运行
- 官网:https://tomcat.apache.org/
小结
- 起步依赖
- 内嵌Tomcat服务器
Web后端开发-请求响应
请求
Postman
前后端分离开发
当前最为流行的开发模式:前后端分离
Postman
postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。
作用:常用于进行接口测试
简单参数
原始方式
获取请求参数,需要HttpServletRequest 对象手动获取
SpringBoot方式
简单参数:参数名与形参变量名相同,定义形参即可接收参数。
1 | @RequestMapping("/simpleParam") |
简单参数:如果方法形参名称与请求参数名称不匹配,可以使用 @RequestParam 完成映射。
1 | @RequestMapping("/simpleParam") |
@RequestParam中的required属性默认为true,代表该请求参数必须传递,如果不传递将报错。 如果该参数是可选的,可以将required属性设置为false。
实体参数
简单实体对象:请求参数名与形参对象属性名相同,定义POJO接收即可
1 | @RequestMapping("/simplePojo") |
复杂实体对象:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数。
1 | @RequestMapping("/complexPojo") |
数组集合参数
数组参数
数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数
1 | @RequestMapping("/arrayParam") |
集合参数@RequestParam
集合参数:请求参数名与形参集合名称相同且请求参数为多个,@RequestParam 绑定参数关系
1 | @RequestMapping("/listParam") |
总结
==数组:请求参数名与形参中数组变量名相同,可以直接使用数组封装==
==集合:请求参数名与形参中集合变量名相同,通过@RequestParam绑定参数关系==
日期参数@DateTimeFormat
日期参数:使用 @DateTimeFormat 注解完成日期参数格式转换
1 | @RequestMapping("/dateParam") |
Json参数
JSON参数:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用 @RequestBody 标识
1 | @RequestMapping("/jsonParam") |
路径参数
路径参数:通过请求URL直接传递参数,使用{…}来标识该路径参数,需要使用 @PathVariable 获取路径参数
1 | @RequestMapping("/path/{id}/{name}") |
响应
@ResponseBody
位置:Controller类上/方法上
作用:将方法返回值直接响应,若返回值类型是 实体对象/集合 ,转JSON格式响应
说明:@RestController = @Controller + @ResponseBody ;
统一响应结果
如果一个个的响应,不方便管理和维护
分层解耦
三层架构
controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据。
service:业务逻辑层,处理具体的业务逻辑。
dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增、删、改、查。
可能有很多类型的数据,比如是xml的、数据库的、或者是别人给的
定义Dao层的接口,增强扩展性
控制反转:
Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
依赖注入:
Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象,称之为bean。
1 | 1: Service层和Dao层的实现类,交给IOC容器管理 |
如果要切换service,只需要把component修改了就行
IOC详解
IOC对象 又称为bean对象
注解 | 说明 | 位置 |
---|---|---|
@Component | 声明bean的基础注解 | 不属于以下三类时,用此注解 |
@Controller | @Component的衍生注解 | 标注在控制器类上 |
@Service | @Component的衍生注解 | 标注在业务类上 |
@Repository | @Component的衍生注解 | 标注在数据访问类上(由于与mybatis整合,用的少) |
声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。
Bean组件扫描
前面声明bean的四大注解,要想生效,还需要被组件扫描注解@ComponentScan扫描。
@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解 @SpringBootApplication 中,默认扫描的范围是启动类所在包及其子包。
Bean注入
@Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报出如下错误:
Java基础知识9-lambda表达式概述
Java基础知识8-网络编程概述
网络编程概述
什么是网络编程?
网络编程是指利用计算机网络实现程序之间通信的一种编程方式。在网络编程中,程序需要通过网络协议(如 TCP/IP)来进行通信,以实现不同计算机之间的数据传输和共享。
在网络编程中,通常有三个基本要素
①IP 地址:定位网络中某台计算机
②端口号port:定位计算机上的某个进程(某个应用)
③通信协议:通过IP地址和端口号定位后,如何保证数据可靠高效的传输,这就需要依靠通信协议了。
网络编程三要素
IP地址
①IP 地址用于唯一标识网络中的每一台计算机。在 Internet 上,使用 IPv4 或 IPv6 地址来表示 IP 地址。通常 IPv4 地址格式为 xxx.xxx.xxx.xxx,其中每个 xxx 都表示一个 8 位的二进制数(每一个xxx的取值范围是0-255),组合起来可以表示 2^32 个不同的 IP 地址。
②IPv4 地址的总数量是4294967296 个,但并不是所有的 IPv4 地址都可以使用。IPv4 地址被分为网络地址和主机地址两部分,前3个字节用于表示网络(省市区),最后1个字节用于表示主机(家门牌)。而一些 IP 地址被保留或者被私有机构使用,不能用于公网的地址分配。另外,一些 IP 地址被用作多播地址,仅用于特定的应用场景。因此实际上可供使用的 IPv4 地址数量要少于总数量,而且随着 IPv4 地址的逐渐枯竭,IPv6 地址已经开始逐渐普及,IPv6 地址数量更是相当巨大。
③IPv6使用16个字节表示IP地址(128位),这样就解决了网络地址资源数量不够的问题。IPv6 地址由 8 组 16 位十六进制数表示,每组之间用冒号分隔,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984
④本机地址:127.0.0.1,主机名:localhost。
⑤192.168.0.0-192.168.255.255为私有地址,属于非注册地址,专门为组织机构内部使用。
IP地址相关的:域名与DNS
①域名
IP地址毕竟是数字标识,使用时不好记忆和书写,因此在IP地址的基础上又发展出一种符号化的地址方案,来代替数字型的IP地址。每一个符号化的地址都与特定的IP地址对应。这个与网络上的数字型IP地址相对应的字符型地址,就被称为域名。
目前域名已经成为互联网品牌、网上商标保护必备的要素之一,除了识别功能外,还有引导、宣传等作用。如:www.baidu.com
②DNS
在Internet上域名与IP地址之间是一对一(或者多对一)的,域名虽然便于人们记忆,但机器之间只能互相认识IP地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成,DNS(Domain Name System域名系统)就是进行域名解析的服务器,域名的最终指向是IP。
端口号(port)
①在计算机中,不同的应用程序是通过端口号区分的。
②端口号是用两个字节(无符号)表示的,它的取值范围是0~65535,而这些计算机端口可分为3大类:
①公认端口:0~1023。被预先定义的服务通信占用(如:HTTP占用端口80,FTP占用端口21,Telnet占用端口23等)
②注册端口:1024~49151。分配给用户进程或应用程序。(如:Tomcat占用端口8080,MySQL占用端口3306,Oracle占用端口1521等)。
③动态/私有端口:49152~65535。
③通常情况下,服务器程序使用固定的端口号来监听客户端的请求,而客户端则使用随机端口连接服务器。
④IP地址好比每个人的地址(门牌号),端口好比是房间号。必须同时指定IP地址和端口号才能够正确的发送数据。接下来通过一个图例来描述IP地址和端口号的作用,如图所示:
通信协议
①通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则。就像两个人想要顺利沟通就必须使用同一种语言一样,如果一个人只懂英语而另外一个人只懂中文,这样就会造成没有共同语言而无法沟通。
②在计算机网络中,这些连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换。
③在计算机网络中,常用的协议有 TCP、UDP、HTTP、FTP 等。这些协议规定了数据传输的格式、传输方式和传输顺序等细节。其中,TCP(传输控制协议)是一种可靠的面向连接的协议,它提供数据传输的完整性保证;而 UDP(用户数据报协议)则是一种无连接的协议,传输效率高。在网络编程中,需要选取合适的协议类型来实现数据传输。
通信协议相关的:OSI参考模型(可以)
①世界上第一个网络体系结构由IBM公司提出(1974年,SNA),以后其他公司也相继提出自己的网络体系结构如:Digital公司的DNA,美国国防部的TCP/IP等,多种网络体系结构并存,其结果是若采用IBM的结构,只能选用IBM的产品,只能与同种结构的网络互联。
②为了促进计算机网络的发展,国际标准化组织ISO(International Organization for Standardization)于1977年成立了一个委员会,在现有网络的基础上,提出了不基于具体机型、操作系统或公司的网络体系结构,称为开放系统互连参考模型,即OSI/RM (Open System Interconnection Reference Model)。
==OSI模型把网络通信的工作分为7层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。OSI七层协议模型如图所示:==
通信协议相关的:TCP/IP参考模型
①OSI参考模型的初衷是提供全世界范围的计算机网络都要遵循的统一标准,但是由于存在模型和协议自身的缺陷,迟迟没有成熟的产品推出。TCP/IP协议在实践中不断完善和发展取得成功,作为网络的基础,Internet的语言,可以说没有TCP/IP参考模型就没有互联网的今天。
②TCP/IP,即Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,是Internet最基本的协议、Internet国际互联网络的基础。
③TCP/IP协议是一个开放的网络协议簇,它的名字主要取自最重要的网络层IP协议和传输层TCP协议。TCP/IP协议定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。TCP/IP参考模型采用4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求,这4个层次分别是:网络接口层、互联网层(IP层)、传输层(TCP层)、应用层。
④OSI模型与TCP/IP模型的对应关系如图所示:
OSI参考模型 与 TCP/IP参考模型 区别
① OSI 参考模型是理论上的,而 TCP/IP 参考模型是实践上的。TCP/IP 参考模型被许多实际的协议(如 IP、TCP、HTTP 等)所支持和实现,而 OSI 参考模型则主要是作为理论框架和标准进行研究和讨论。
②OSI 参考模型是由国际标准化组织提出的网络通信协议框架,其中分为 7 层,各层之间明确了功能的划分,从物理层到应用层,逐层向上升,每层只对自己下一层提供服务,并依次封装和解封数据。OSI 参考模型是一种理论上的协议框架,用于描述计算机系统间的通信原理和规范。
③TCP/IP 参考模型(也称互联网参考模型)是实际应用中最广泛的协议框架。它将网络协议划分为 4 层:网络接口层、网络层、传输层和应用层。TCP/IP 参考模型与 OSI 参考模型之间有着相对应的层次结构,但是其中的每一层都是实际存在的协议,而不是纯粹的框架。TCP/IP 参考模型被广泛应用于互联网上,是计算机系统间进行通信的重要基础。
网络编程基础类
InetAddress类
① java.net.IntAddress类用来封装计算机的IP地址和DNS(没有端口信息),它包括一个主机名和一个IP地址,是java对IP地址的高层表示。大多数其它网络类都要用到这个类,包括Socket、ServerSocket、URL、DatagramSocket、DatagramPacket等
②常用静态方法
lstatic InetAddress getLocalHost() 得到本机的InetAddress对象,其中封装了IP地址和主机名
lstatic InetAddress getByName(String host) 传入目标主机的名字或IP地址得到对应的InetAddress对象,其中封装了IP地址和主机名(底层会自动连接DNS服务器进行域名解析)
③常用实例方法
1 | public String getHostAddress() 获取IP地址 |
获取InetAddress对象
1 | InetAddress ia = InetAddress.getLocalHost(); |
获取本机的IP地址
1 | String hostAddress = ia.getHostAddress(); |
获取本机的主机名称
1 | String hostName = ia.getHostName(); |
通过域名来获取InetAddress对象
1 | InetAddress ia2 = InetAddress.getByName("www.baidu.com"); |
URL类
①URL是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
②URL由4部分组成:协议、存放资源的主机域名、端口号、资源文件名。如果未指定该端口号,则使用协议默认的端口。例如HTTP协议的默认端口为80。在浏览器中访问网页时,地址栏显示的地址就是URL。
③URL标准格式为:<协议>://<域名或IP>:<端口>/<路径>。其中,<协议>://<域名或IP>是必需的,<端口>/<路径>有时可省略。如:https://www.baidu.com。
④为了方便程序员编程,JDK中提供了URL类,该类的全名是java.net.URL,该类封装了大量复杂的涉及从远程站点获取信息的细节,可以使用它的各种方法来对URL对象进行分割、合并等处理。
⑤URL类的构造方法:
1 | URL url = new URL(“http://127.0.0.1:8080/oa/index.html?name=zhangsan#tip”); |
⑥URL类的常用方法:
1 | 获取协议:url.getProtocol() |
1 | // 创建URL类型的对象 |
⑦使用URL类的openStream()方法可以打开到此URL的连接并返回一个用于从该连接读入的InputStream,实现最简单的网络爬虫
TCP与UDP协议
Socket套接字概述
①我们开发的网络应用程序位于应用层,TCP和UDP属于传输层协议,在应用层如何使用传输层的服务呢?在应用层和传输层之间,则是使用套接Socket来进行分离。
②套接字就像是传输层为应用层开的一个小口,应用程序通过这个小口向远程发送数据,或者接收远程发来的数据。而这个小口以内,也就是数据进入这个口之后,或者数据从这个口出来之前,是不知道也不需要知道的,也不会关心它如何传输,这属于网络其它层次工作。
③Socket实际是传输层供给应用层的编程接口。Socket就是应用层与传输层之间的桥梁。使用Socket编程可以开发客户机和服务器应用程序,可以在本地网络上进行通信,也可通过Internet在全球范围内通信。
④TCP协议和UDP协议是传输层的两种协议。Socket是传输层供给应用层的编程接口,所以Socket编程就分为TCP编程和UDP编程两类。
TCP协议
①使用TCP协议,须先建立TCP连接,形成传输数据通道,似于拨打电话
②传输前,采用“三次握手”方式,属于点对点通信,是面向连接的,效率低。
③仅支持单播传输,每条TCP传输连接只能有两个端点(客户端、服务端)。
④两个端点的数据传输,采用的是“字节流”来传输,属于可靠的数据传输。
⑤传输完毕,需释放已建立的连接,开销大,速度慢,适用于文件传输、邮件等。
TCP协议的三次握手(通道建立)
TCP(传输控制协议)是一种面向连接的、可靠的传输层协议。它使用三次握手来建立连接,以确保数据在两个设备之间可靠地传输。
三次握手的过程如下:
==客户端发送 SYN(同步)数据包。这个数据包包含客户端的初始序列号(ISN)。==
==服务器收到 SYN 数据包后,发送 SYN-ACK(同步确认)数据包。这个数据包包含服务器的初始序列号(ISN)和对客户端 ISN 的确认号(ACK)。==
==客户端收到 SYN-ACK 数据包后,发送 ACK(确认)数据包。这个数据包包含对服务器 ISN 的确认号(ACK)。==
三次握手完成后,客户端和服务器就可以开始交换数据了。
三次握手的意义:
三次握手可以确保数据在两个设备之间可靠地传输。它可以防止以下情况的发生:
不会丢失:如果没有三次握手,客户端和服务器可能会同时发送数据,导致数据丢失。
不会重复:如果没有三次握手,客户端和服务器可能会重复发送数据,导致数据重复。
不会乱序:如果没有三次握手,客户端和服务器可能会乱序发送数据,导致数据乱序。
TCP协议的四次挥手(通道关闭)
使用四次挥手来关闭连接,以确保数据在两个设备之间可靠地传输。
四次挥手的过程如下:
客户端发送 FIN(结束)数据包。这个数据包表示客户端已经完成数据传输,并希望关闭连接。
服务器收到 FIN 数据包后,发送 ACK(确认)数据包。这个数据包表示服务器已经收到客户端的 FIN 数据包,并同意关闭连接。
服务器发送 FIN 数据包。这个数据包表示服务器已经完成数据传输,并希望关闭连接。
客户端收到 FIN 数据包后,发送 ACK(确认)数据包。这个数据包表示客户端已经收到服务器的 FIN 数据包,并同意关闭连接。四次挥手完成后,客户端和服务器之间的连接就关闭了。
四次挥手的意义
四次挥手可以确保数据在两个设备之间可靠地传输。它可以防止以下情况的发生:
如果没有四次挥手,客户端和服务器可能会同时关闭连接,导致数据丢失。
如果没有四次挥手,客户端和服务器可能会重复发送数据,导致数据重复。
如果没有四次挥手,客户端和服务器可能会乱序发送数据,导致数据乱序。
UDP协议
①采用数据报(数据、源、目的)的方式来传输,无需建立连接,类似于发短信。
②每个数据报的大小限制在64K内,超出64k可以分为多个数据报来发送。
③发送不管对方是否准备好,接收方即使收到也不确认,因此属于不可靠的。
④可以广播发送,也就是属于一对一、一对多和多对一连接的通信协议。
⑤发送数据结束时无需释放资源,开销小,速度快,适用于视频会议、直播等。
基于TCP协议的编程
TCP协议编程概述
①socket是一种进程间的数据交换机制,利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为事实上的标准。
②在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client),而在第一次通讯中等待连接的程序被称作服务端(Server)。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别。
接受和发出其实是可以理解为IO流
③socket与主机地址和端口号相关联,主机地址就是客户端或服务器程序所在的主机的IP地址,端口地址是指客户端或服务器程序使用的主机的通信端口。在客户端和服务器中,分别创建独立的Socket,并通过Socket的属性,将两个Socket进行连接,这样客户端和服务器通过套接字所建立连接并使用IO流进行通信。
Socket类概述
①Socket类实现客户端套接字(Client),套接字是两台机器间通信的端点
②Socket类构造方法:
1 | public Socket(InetAddress a, int p) 创建套接字Socket并连接到指定IP地址的指定端口号 |
③Socket类实例方法:
1 | public InetAddress getInetAddress() 返回此套接字连接到的远程 IP 地址。 |
ServerSocket类概述
①ServerSocket类用于实现服务器套接字(Server服务端)。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果
②ServerSocket构造方法:
1 | public ServerSocket(int port) |
③ServerSocket实例方法:
1 | public Socket accept() 侦听要连接到此套接字并接受它。 |
1 | ServerSocket serverSocket = null; |
TCP循环发消息
1 | byte[] bytes = new byte[1024]; |
TCP双向通信
①在双向通讯的案例中,客户端需要向服务端发送一张图片,服务端收到客户端发送的图片后,则需要向客户端回复收到图片的反馈。在客户端给服务端发送图片的时候,图片发送完毕必须调用shutdownOutput()方法来关闭socket输出流,否则服务端读取数据就会一直阻塞。
②服务器端实现步骤:
创建ServerSocket对象,绑定监听端口;
通过accept()方法监听客户端请求;
使用输入流接收客户端发送的图片,然后通过输出流保存图片
通过输出流返回客户端图片收到。
调用close()方法关闭资源
③客户端实现步骤:
创建socket对象,指明需要连接的服务器地址和端口号;
建立连接后,通过输出流向服务器端发送图片;
通过输入流获取服务器的响应信息;
调用close()方法关闭资源
1 | Socket clientSocket = null; |
1 | clientSocket = new Socket(InetAddress.getLocalHost(), 8888); |
基于UDP协议的编程
xxxxxxxxxx Class userClass = User.class;Constructor con = userClass.getDeclaredConstructor(Map.class);Type[] genericParameterTypes = con.getGenericParameterTypes();for(Type g :genericParameterTypes){ if(g instanceof ParameterizedType){ ParameterizedType parameterizedType = (ParameterizedType) g; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for(Type a : actualTypeArguments){ System.out.println(a.getTypeName()); } }}java
①DatagramPacket类负责把发送的数据打包(打包的数据为byte类型的数组),并且创建发送端时需指定接收端的IP地址和端口
②DatagramPacket的构造方法:
1 | public DatagramPacket(byte buf[], int offset, int length) 创建接收端的数据报。 |
③DatagramPacket的实例方法:
1 | public synchronized byte[] getData() 返回数据报中存储的数据 |
基于UDP编程的实现
①接收端实现步骤
创建DatagramSocket对象(接收端),并指定端口号;
创建DatagramPacket对象(数据报);
调用receive()方法,用于接收数据报;
调用close()方法关闭资源
1 | DatagramSocket ds = new DatagramSocket(8888); |
②发送端实现步骤
创建DatagramSocket对象(发送端);
创建DatagramPacket对象(数据报),并指定接收端IP地址和端口;
调用send()方法,用于发送数据报;
调用close()方法关闭资源。
1 | DatagramSocket ds = new DatagramSocket(); |
Java基础知识7-注解
注解概述
什么是注解?
①注解是JDK1.5才引入的。
②注解可以标注在 类上,属性上,方法上 等。
==③注解可以做到在不改变代码逻辑的前提下在代码中嵌入补充信息。==
注解与注释
①注释:给程序员看的,编译器编译时会忽略注释。
②注解:给编译器看的,或给其它程序看的,程序根据有没有这个注解来决定不同的处理方式。
注解的重要性
①框架是如何实现的:框架 = 反射 + 注解 + 设计模式。
Java预置注解
①@Deprecated
用来标记过时的元素,在编译阶段遇到这个注解时会发出提醒警告,告诉开发者正在调用一个过时的元素比如过时的类、过时的方法、过时的属性等。
forRemoval属性值表示如果是true就是已移除
②@Override
修饰实例方法,则该方法必须是个重写方法,否则就会编译失败。
③@SuppressWarnings(抑制警告的注解):在实际开发中,建议尽量不要忽略警告,而是真正的去解决警告。
1 | @SuppressWarnings("rawtypes"):抑制未使用泛型的警告 |
④@FunctionalInterface “函数式接口”的注解
**==“函数式接口”的注解,这个是 JDK1.8 版本引入的新特性。==**:函数式接口 有且只能存在一个抽象方法
==这个注解是专门用来标注接口的==
使用@FunctionalInterface标注的接口,则该接口就有且只能存在一个抽象方法,否则就会发生编译错误。
(注意:接口中的默认方法或静态方法可以有多个。)
自定义注解Annotation
注解的属性是以方法这种签名实现的
自定义注解(注解属于引用数据类型)
①使用 @interface 来定义注解。
②默认情况下注解可以出现在类上、方法上、属性上、构造方法上、方法参数上等……
③所有自定义的注解,它的父类是:java.lang.annotation.Annotation
1 | //@Retention(value= RetentionPolicy.SOURCE) // @MyAnnotation 注解保留在源码中。 |
1 | @MyAnnotation |
注解也可以定义属性
①注解也可以定义属性,不过属性定义时,属性名后面必须加一个小括号。
②属性的类型只能是:
byte,short,int,long,float,double,boolean,char
String、Class、枚举类型、注解类型
以上所有类型的一维数组形式
1 | /** |
1 | // 语法规则:如果这个注解中有属性,那么使用的时候,必须给属性赋值。没有赋值则报错。 |
注解的使用
①注解在使用时必须给属性赋值,除非你使用了default关键字为属性指定了默认值。
②如果属性只有一个,并且属性名是value时,使用注解时value可以省略不写。
③如果属性是一个数组,使用注解时,数组值只有一个,数组的大括号是可以省略的。
元注解
①用来标注注解的注解叫做元注解。(也是JDK内置的注解。)
②常用的元注解:
1 | @Retention:设置注解的保持性 |
@Retention
①Retention英文意思有保留、保持的意思,它表示注解存在阶段是保留在源代码(编译期),字节码(类加载)或者运行时(JVM中运行)。
②在@Retention注解中使用枚举RetentionPolicy来表示注解保留时期。
1 | @Retention(RetentionPolicy.SOURCE):注解仅存在于源代码中,在字节码文件中不包含。 |