后端Web的开发
1. Maven
-
Maven是apache旗下的一个开源项目,是一款用于管理和构建java项目的工具
-
Maven的作用:
-
依赖管理:当我们导入多个jar包时,多个jar包之间可以相互依赖,当我们升级其中一个,需要把其他的也升级,这样很麻烦,所以,我们就可以不用导入jar包了,就可以通过Maven在配置文件中简单描述一下依赖的信息
-
统一项目结构:提供标准,统一的项目结构,基于Maven创建的项目,有一个统一的结构,这样就可以方便在不同的编辑器之间导入了
-
- 标准化的项目构建流程:提供了一套标准跨平台(Linus,windows,MacOS)的自动化项目构建方式(编译-检测-打包-发送)
1.1 maven的安装
-
Apache Maven是一个项目管理和构建的工具,他是基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建
-
仓库:用于存放资源,管理各种jar包
- 本地仓库:自己计算机上的一个目录,当从中央仓库下载时,会下载到当前仓库中
- 中央仓库:由Maven团队维护的全球唯一的。
- 远程仓库(私服):一般由公司搭建的私有仓库
-
依赖管理模型的访问顺序:先到本地仓库查询,如果没有再去远程仓库,再去中央仓库
-
安装步骤:
- 解压apache-maven-3.6.1-bin.zip
- 配置本地仓库:修改 conf/settings.xml 中的 为一个指定目录。(在53行)
<localRepository>F:\moven\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn_repo</localRepository> //我的本地仓库
- 配置阿里云私服:修改 conf/settings.xml 中的 标签,为其添加如下子标签:
<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
- 配置环境变量: MAVEN_HOME 为maven的解压目录,并将其bin目录加入PATH环境变量。
-
相关目录的介绍:
1.2 maven的配置
-
方法一:每个工程都要配置一次
-
选中IDEA的File–>Settings–>Build,Execution,Deployment–>Bulid Tools–>Maven
-
设置IDEA使用本地安装的Maven,并修改配置文件和本地仓库路径
-
方法二:
-
在方法一的基础上,在项目外面进行配置
1.3 创建maven项目
- 创建模块,选择Maven,点击Next
- 填写模块名称,坐标信息,点击finish,创建完成
- 编写 HelloWorld,并运行
-
当创建好时,会将所下载好的依赖和插件放入到自己创建好的仓库中
-
由于采用的是webapp1.0是没有java文件夹和test文件夹的
-
解决方案:
-
webapp1.0版本修改为1.4版本,这样可以在xml文件中更改项目结构
-
使用解压工具打开:F:\moven\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn_repo\org\apache\maven\archetypes\maven-archetype-webapp\1.4中的maven-archetype-webapp-1.4.jar
-
再打开META-INF中的Maven中的archetype-metadata.xml
-
按如下编写
-
-
这里面显示的jdk的版本和编码方式
-
当创建好之后的工程结构:
-
在main目录下存放的是:项目的资源,在java目录下面是java的源代码,resources是配置资源
-
text目录是:测试的相关资源
-
编写代码时在java目录中
-
当我们运行代码完成后,会在target目录下面生成对应的class文件
1.3.1Maven坐标
- 什么是坐标:
- Maven中的坐标是资源的唯一标识,通过坐标可以唯一定位资源的位置
- 使用坐标来定义项目或引入项目所需要的依赖
- Maven坐标的主要组成:
- groupId:定义当前Maven项目隶属组织名称(通常是域名反写:com.itheima)(也就是文件夹,为后续的打包进行提供文件名,存放在本地仓库中)
- artifactId:定义当前Maven项目名称(通常是模块名,例如:maven-project01)(也就是依赖的名称)
- version:定义当前项目版本号
1.4 导入Maven项目
-
方式一:选中左侧的Maven面板,点击+号,选中对应项目的pom.xml文件即可
-
方式二:文件–>项目结构–>模块中的加号,导入对应项目的pom.xml
-
pom.xml的介绍:
在Maven项目中,pom.xml文件是Project Object Model(项目对象模型)的缩写,它是Maven项目的核心配置文件,负责定义项目的基本信息、依赖关系、构建插件等。pom.xml文件的主要作用包括:
- 定义项目的基本信息,如项目的名称、版本、描述等。
- 声明项目的依赖关系,包括所需的外部库、框架等。
- 配置项目的构建插件,定义项目的构建过程和打包方式。
- 指定项目的资源目录、输出目录等。
- 配置项目的插件,如编译插件、测试插件等。
- 定义项目的源代码目录结构。
- 配置项目的部署信息,如部署到远程仓库的方式等。
总的来说,pom.xml文件是Maven项目的核心配置文件,通过配置pom.xml可以管理项目的依赖关系、构建过程、打包方式等,是Maven项目的重要组成部分。
1.5 依赖管理
1.5.1 依赖配置
-
依赖:值当前项目运行所需要的jar包,一个项目可以引入多个依赖,简而言之就是:引入第三方资源
-
配置:
- 在pom.xml中编写标签,一个pom.xml文件中只能有一个标签
- 在标签中,使用引入坐标
- 定义坐标的groupId,artifactId,version
- 点击刷新按钮,引入最新的坐标
-
例子:引入记录日志的资源(logback-classic)
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
-
在左侧打开Maven面板,查看是否添加到了所需要的依赖
-
当我们需要修改依赖的版本,只需要修改version标签里面的内容,刷新之后,Maven会自动联网下载到本地仓库
-
如果本地仓库没有该依赖,可以去Maven仓库去搜索所需要的依赖的书写方式,刷新之后,会自动下载到本地仓库中
1.5.2 依赖传递
- 导入依赖时,依赖所依赖的依赖会也会自动进行配置
- 直接依赖:在当前项目中用过依赖配置建立起的依赖关系
- 间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
- 排除依赖:主动断开所依赖的资源,被排除的依赖无需版本号,通过标签来完成
- 在所导入的依赖下面,排除依赖
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven-projectB</artifactId>
<!-- 排除依赖-->
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
<version>1.0-SNAPSHOT</version>
</dependency>
1.5.3 依赖范围
- 依赖的jar包,默认情况下,可以在任何地方使用。可以通过设置其作用范围
- 作用范围:
- 主程序范围有效(main文件夹范围内)
- 测试程序范围有效(test文件夹范围内)
- 是否参与打包运行(package指令范围内)
- 大部分情况下都是默认值
- 判断是否有效,就是能否能创建所导入依赖的对象
1.5.3 生命周期
- Maven的生命周期就是为了索引的maven项目构建过程进行抽象和统一
- maven有3套相互独立的生命周期:
- clean:清理工作
- default:核心工作,如:编译,测试,打包,安装,部署
- site:生成报告,发布站点
- 每套生命周期包含一些阶段,阶段是有顺序的,后面的阶段依赖于前面的阶段
- 下面是5个主要的生命周期阶段:
-
在同一套生命周期中,当运行后面的阶段时,前面的阶段都会运行
-
执行指定生命周期的两种方式:
- 在idea中,右侧maven工具栏,选中对应的生命周期,双击执行
- 在命令行中,通过命令执行
-
注意:
- 当Failed to execute goal on project xxxxx,说明本地仓库和中央仓库是没有所需要的依赖
- 该依赖可是是私服的,所以就必须先通过install将其依赖下载到本地仓库中,这样才不会报错
-
当执行这些生命周期时,都会讲文件存放到target目录下面的
-
如果想跳过测试阶段,可以选中工具栏中的禁止图标
## 2.Web入门
- Spring Boot可以帮我们非常快速的构建应用程序,简化开发,提高效率
2.1 SpringBootWeb入门
-
创建步骤:
- 创建springboot工程,并勾选web开发相关依赖
- 当创建完成之后,删除不必要的文件,留下以下文件
- 定义HelloController类,添加方法hello,并添加注解
- 运行启动类SpringbootWebQuickstartApplication,端口号为8080
3.HTTP协议
3.1 概述
- 概念Hyper Text Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则
- 特点:
- 基于TCP协议:面向连接,安全
- 基于请求0响应模型的:一次请求对应一次响应
- HTTP协议是无状态的协议:对于事物处理是没有记忆能力的,每次请求-响应都是独立的
- 缺点:多次请求之间不能共享数据
- 优点:速度快
3.2 请求协议
-
请求头的相关键值对的概念
请求头的相关键的名称 值的含义 Host 请求的主机名 User-Agent 浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 … Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT …) like Gecko Accept 表示浏览器能接收的资源类型,如text/,image/ * 或者 /*表示所有; Accept-Language 表示浏览器偏好的语言,服务器可以据此返回不同语言的网页; Accept-Encoding 表示浏览器可以支持的压缩类型,例如gzip, deflate等 Content-Type 请求主体的数据类型 Content-Length 请求主体的大小(单位:字节) -
请求体是:post请求类型特有的
-
请求方式-get:请求参数在请求行中,没有请求体,如/hello。GET请求大小是有限制的,因为URL是有限制的
-
请求方式-post:请求参数在请求体中,POST请求大小是没有限制的
3.3 响应协议
- 响应协议:就是响应数据的格式
-
响应的状态码的分类:
1xx 响应中-临时状态码,表示请求已经接收,告诉客户端应该继续请求或者如果它已经完成则忽略它 2xx 成功-表示请求已经被成功接收,处理已完成 3xx 重定向-重定向到其他地方;让客户端再发起一次请求以完成整个处理 4xx 客户端错误-处理发生错误,责任在客户端。如: 请求了不存在的资源、客户端未被授权、禁止访问等。 5xx 服务器错误-处理发生错误,责任在服务端。如:程序抛出异常等。 -
常见的响应状态码:
状态码 英文描述 解释 200 OK
客户端请求成功,即处理成功,这是我们最想看到的状态码 302 Found
指示所请求的资源已移动到由 Location
响应头给定的 URL,浏览器会自动重新访问到这个页面304 Not Modified
告诉客户端,你请求的资源至上次取得后,服务端并未更改,你直接用你本地缓存吧。隐式重定向 400 Bad Request
客户端请求有语法错误,不能被服务器所理解 403 Forbidden
服务器收到请求,但是拒绝提供服务,比如:没有权限访问相关资源 404 Not Found
请求资源不存在,一般是URL输入有误,或者网站资源被删除了 405 Method Not Allowed
请求方式有误,比如应该用GET请求方式的资源,用了POST 428 Precondition Required
服务器要求有条件的请求,告诉客户端要想访问该资源,必须携带特定的请求头 429 Too Many Requests
指示用户在给定时间内发送了太多请求(“限速”),配合 Retry-After(多长时间后可以请求)响应头一起使用 431 Request Header Fields Too Large
请求头太大,服务器不愿意处理请求,因为它的头部字段太大。请求可以在减少请求头域的大小后重新提交。 500 Internal Server Error
服务器发生不可预期的错误。服务器出异常了,赶紧看日志去吧 503 Service Unavailable
服务器尚未准备好处理请求,服务器刚刚启动,还未初始化好 状态码大全:https://cloud.tencent.com/developer/chapter/13553
-
常见的响应头:
Content-Type | 表示该响应内容的类型,例如text/html,application/json。 |
---|---|
Content-Length | 表示该响应内容的长度(字节数)。 |
Content-Encoding | 表示该响应压缩算法,例如gzip。 |
Cache-Control | 指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒。 |
Set-Cookie | 告诉浏览器为当前页面所在的域设置cookie。 |
3.4 协议解析
- 由于服务端解析HTTP协议太麻烦了,可以通过Tomcat服务器来完成
4.Tomcat
4.1 基本使用
-
Tomcat不用下载,SpringBoot已经内置Tomcat
-
卸载:只需要将下载的文件夹删除即可
-
相关文件的含义:
-
启动:双击bin\startup.bat
-
控制台修改中文乱码:修改conf/logging.properties
-
-
关闭:
- 直接关闭:强制关闭
- bin\shutdown.bat:正常关闭
- Ctrl+c:正常关闭
-
配置Tomcat端口号(conf/server.xml)
-
HTTP协议的默认端口号为80,如果将Tomcat端口号改为80,将来访问Tomact时,无需输入端口号
-
Tomcat项目部署
- 将项目文件夹放置到webapps目录下,部署完成
4.2 程序解析(内嵌Tomcat)
-
SpringBoot的基本骨架:
-
SpringBoot的依赖:
-
起步依赖:
- spring-boot-starter-web:包含了web应用开发所需要的常见依赖。
- spring-boot-starter-test:包含了单元测试所需要的常见依赖。
- 官方提供的starter:https://docs.spring.io/spring-boot/docs/2.7.4/reference/htmlsingle/#using.build-systems.starters
-
创建SpringBoot项目会自动将内置的Tomcat启动起来,并且会自动占用8080端口号
5. 请求
- 对于请求来说:就是让服务器发送的代码,让java程序接受到,便于后面的操作(例如传递用户的账号,密码到数据库中)
5.1 概念:
-
对于之前编写的Controller类,这是一个普通的类,并没有实现任何的接口和类,并且这个程序Tomcat是无法识别的和运行的
-
虽然Tomcat无法识别JavaEE里面的类,但是能够识别JavaEE规范的一项技术的Servlet,Tomcat也称为(Servlet容器)
-
对于SpringBoot底层给我们提供了一个非常核心的Serlvet程序(DispatchServlet)
-
DispatchServlet实现了Servlet规范中的servlet接口
-
所以,浏览器发来的请求会先通过DispatchServlet,再将这个请求转给Controller程序
-
再由Controller程序对请求进行处理,再将处理完的数据返回给DispatchServlet
-
再通过DispatchServlet给浏览器响应数据
-
Tomcat服务器会将前端发来请求信息封装到HttpSerlvetRequest对象中(请求对象)再发给Controller程序
-
Tomcat服务器会将服务器返回的数据(响应数据)封装到HttpSerlvetResponse对象中再发给前端浏览器
-
请求(HttpSerlvetRequest):获取请求数据
-
响应(HttpSerlvetResponse):设置返回数据
-
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。(护方便 体验一般),例如:京东,唯品会,淘宝,天猫
-
CS架构:Client/Server,客户端/服务器架构模式(开发、维护麻烦 体验不错),例如:QQ,微信,企业微信
5.2 请求-postman工具
- 由于浏览器地址获取的请求全市GET请求,当后端是POST请求时,就需要重新编写前端代码
- Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件
- 也可以是使用Apifox
- 作用:常用于进行接口测试
5.3 请求-简单参数
-
原始方法:(了解,比较繁琐,还要进行手动转换)
在原始的web程序中,获取请求参数(在地址后面的),通过HttpSerletRequest对象手动获取!
-
SpringBoot方式
简单参数:参数名与形参变量名相同,定义形参即可接受参数,也会自动进行类型转换
请求参数与java方法中的形参变量名要相同
- POST请求和GET请求其他都是一样,只是POST的请求参数是在请求体中声明的
- 如果方法参数名称和请求参数名称不匹配,可以使用@RequestParam完成映射
- 注意:@RequestParam中的required属性值默认是true,代表请求参数必须被传递,如果不传递将报错,如果该参数是可选的,可以将required属性设置为false
5.4 请求-实体参数
-
所谓的实体参数:就是将参数封装到对象中
-
简单实体对象:请求参数名与参数对象属性名相同,定义POJO(简单的java对象)接受即可
-
如果不相同时,则返回java程序就为null
-
复杂实体对象:请求参数与形参对象属性名相同,按照对象层次结构关系即可接受嵌套POJO属性参数
- 注意:无论是简单参数和实体参数,都必须定义相关属性的GET和SET方法,否则无法成功封装到对象中
5.5 请求-数组集合参数
-
在前端的表单的复选框中,可以选择多个选项,当提交表单时,这些数据会通过数组请求到java服务端上
-
数组参数:请求参数名与形参数组名称相同,且请求参数为多个,定义数组类型参数即可接受参数
-
服务端的接受方式一:
- 通过数组来接受,只需要形参名称与请求参数名相同就可以了
-
服务端接收方式二:
-
通过集合来接受:请求参数名与形参集合名称相同且请求参数为多个,@RequestParm绑定参数
-
5.5 请求-日期参数
- 日期参数:使用@DateTimeFormat注解来完成日期的格式转换
- 由于日期格式多种多样,所以在服务端就得确定好,前端传入日期的格式是怎么样的
- 得通过@DateTimeFormat注解中的pattern属性来完成
- 方法的参数要和请求参数的名称一致
- 如果请求参数的格式与定义好的格式不匹配则在java中显示null
- 注意:服务端中的pattern中格式的大小写一定要一模一样,否则返回的是null
5.6 请求-json格式的参数(重点)
- JSON参数:JSON数据键名与形参对象属性名相同,定义POJO类型参数即可接受参数,需要使用@RequestBody标识
- 当要请求JSon格式的参数时,需要把请求方式设置为POST
- 并且把JSON格式的数据放在请求体中,并且选中raw,并选中JSON
- JSON中的所以key都得使用“”(双引号),并且是复杂参数的情况下,要使用数组的形式
- 在服务端接受JSON格式,一般都是使用实体参数(对象)来接受
5.6 请求-路径参数
- 路径参数:通过请求URL直接传递参数,使用{…}来标识该路径,需要使用@PathVariable获取路径参数
- 当我们想动态的设置请求路径时,就是使用这个方法,就是将动态的参数用{}框起来
- 并且这个动态参数要和形参一样
6. 响应
6.1 响应结果
- @ResponseBody
- 类型:方法注解,类注解
- 位置:Controller方法上/类上
- 作用:将方法返回值直接响应,如果返回值类型是 实体对象/集合,将会转换为Json格式响应
- 说明:@RestController=@Controller+@ResponseBody
- 并且数据响应是返回到响应体中
- 由于返回值的不同,返回的类型就是不同的,对于前端难以处理,对于项目难以管理,不变维护
6.2 统一的响应结果
- 我们可以通过定义一个实体对象来返回响应结果
- 只需要把返回值设置为这同一个实体对象
6.3 案例
-
注意:SpringBoot项目的静态资源(html,css,js等前端资源)默认存放目录为:classpath:/static,classpath:/public,classpath:/rescources
-
classpath:指的是类路径,rescources目录就相当于一个类路径
-
也可以在classpath下面建立一个classpath和resources目录下存放静态资源
-
推荐使用static目录,springboot官方骨架已经有了
7. 分层-解耦
7.1 分层-三层架构
- 基于java程序开发,为了后期方便管理和维护,不应该把程序的代码全写在一个类中,应该按照三层架构进行处理,并且应该按照单一职责原则
-
controller:控制层,接受前端发来的请求,对请求进行出来,并响应数据
-
service:业务逻辑层,处理具体的业务逻辑
-
dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增,删,改,查
-
因此:我们在项目下面,可以创建三个包:controller,service,dao这三个包
-
由于dao层(mapper),可能会有多种方式来访问数据,例如:数据库,xml等等,因此,我们可以通过接口编程来处理
-
定义一个一个接口,接口中只有获取的方法,再创建多个实现类,来处理访问数据的多种方式
-
同理Service层也可以创建多个接口来处理
- 详细步骤解析:
- 当浏览器发送请求时,会先调用controller层,进行接受请求和响应数据
- 再通过service层获取逻辑处理后的结果
- service层的数据又要通过dao层来获取,所以在service层中又接受dao层传递进来的数据
- dao层数据进行访问操作
- 总结:逻辑:倒着写,程序:正着执行
7.2 解耦-IOC-DI引入
-
内聚:软件中各个功能模块内部的功能联系
-
耦合:衡量软件中各个层/模块之间的依赖,关联程度
-
高内聚,低耦合
-
控制反转:Inversion Of Control,简称IOC.对象的创建控制器由程序自身转移到外部(容器),这种思维称为控制反转
- 之前对象都是通过new创建的,当类名发送改变时,就会发生错误,
- 现在把所以对象都交给了容器管理
-
依赖注入:Dependency Injection,简称DI。容器为应用程序运行时,所依赖的资源,称为依赖注入
-
Bean对象:在IOC容器中创建,管理的对象,称为bean
7.3IOC-DI入门
- 将Service层及Dao层的实现类,交给IOC容器管理
- 在实现类上面添加@Component注解,这样实现类就交给IOC容器管理了
- 为Controller及Service注入运行时,依赖的对象
- 对所需要实现类的成员变量上,添加@Autowired注解
- 运行测试
7.4IOC的详解
- 当要把某个对象交个IOC容器管理,需要在对应的类上加上如下注解之一:
注解 | 说明 | 位置 |
---|---|---|
@Component | 声明bean的基础注解 | 不属于以下三类时,用此注解 |
@Controller | @Component的衍生注解 | 标注在控制器类上(@RestController=@Controller+@ResponseBody) |
@Service | @Component的衍生注解 | 标注在业务类上 |
@Repository | @Component的衍生注解 | 标注在数据访问类上(由于与mybatis整合,用的少) |
-
在每个IOC容器中,每个bean都是可以有名字,可以进行设置,如果没有设置,默认:类名首字母小写,如果要指定在注解后面加上(value=“xxx”);
-
一般bean的名字不用设置
-
注意:在springboot集成web开发中,声明控制器bean只能用@Controller
7.4.1 Bean组件扫描
-
要写bean的四大注解生效,需要被组件扫描注解@ComponentScan扫描
-
@ComponentScan注解虽然没有显示配置,但是实际上已经包含在启动类声明注解@SpringBootApplication中,默认扫描范围是启动类所在包及其子包
-
也可以在启动类手动添加@ComponentScan,并制定扫描的范围,一旦手动声明了,默认扫描范围就失效了
-
但是一般都不会这样,一般情况下都是将包放在springboot启动类所在包以及子包
7.5DI详解
- @Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报出如下错误:
-
解决方案:
-
通过@Primary:设置bean的优先级,在@Service注解上面再添加@Primary
-
通过@Qualifier:配合@Autowired注解来完成
-
通过@Resource:无需使用@Autowried注解,@Autowired注解是通过类型来注入的,@Rescource是通过名称来注入的
- @Resource注解是JDK提供的注解,@Autowired是spring提供的注解
- @Resource注解是JDK提供的注解,@Autowired是spring提供的注解
-