黑马JavaWeb-day04
@
maven
maven 简介
maven
:\(Maven\)是\(apache\)旗下的一个开源项目,是一款用于管理和构建\(java\)项目的工具,它是基于项目对象模型(POM|project object model)的概念,通过一小段描述信息来管理项目的构建。
maven的作用
-
管理jar包:在引入maven之前,都是先下载\(jar\)包,然后在项目下面新建一个\(lib\)文件,然后将\(jar\)包放到\(lib\)文件中,有了maven后只需要在maven的配置文件中写代码即可
-
提供了一套标准化的项目构建流程
-
统一的项目结构:不同的开发工具创建出来的java项目具有不同的结构,但基于maven创建出来的项目具有相同的项目结构
- maven中的仓库是用来存储和管理jar包的
- maven中一共有3类仓库,查找jar包的顺序是本地仓库、远程仓库、中央仓库
maven 安装
\(step1\)
同时将下载好的zip文件解压到无空格、中文的路径下
\(step2\)
配置本地仓库:修改\(conf/settings.xml\)中的\(<localRepository>\)为一个指定目录
\(step3\)
配置阿里云私服:修改\(conf/settings.xml\)中的\(<mirrors>\)标签,为其添加如下子标签
\(step4\)
配置环境变量:\(MAVEN\_HOME\)为\(maven\)的解压目录,并将其\(bin\)目录加入到\(PATH\)环境变量
在命令行输入下面命令检验环境变量是否配置成功
mvn -v
成功如下图:
IDEA集成maven
创建maven项目
idea中配置maven全局环境
然后正常创建即可
Maven 坐标
- maven中的坐标是资源(jar)的唯一标识,通过该坐标可以唯一定位资源的位置
- 使用坐标来定义项目或引人项目中需要的依赖
maven坐标的主要组成
groupId
:定义当前的Maven项目隶属组织名称(通常是域名反写)artifactId
:定义当前Maven项目名称(通常是模块名)version
:定义当前项目版本号SNAPSHOT
:功能不稳定、尚处于开发中的版本,即快照版本RELEASE
:功能趋于稳定、当前更新停止,可用于发行的版本
依赖管理
依赖:指当前项目运行所需要的jar包,一个项目中可以引入多个依赖
配置依赖:
- 在
pom.xml
中编写<dependencies>
- 在
<dependencies>
标签中使用<dependency>
引入坐标 - 定义坐标的
groupId
、artifactId
、version
- 点击刷新按钮、引入最新加入的坐标
只下载了\(spring-context\)却多出来这么多依赖,原因就是maven的依赖传递,a依赖b,b依赖c,所有用a就需要b和c
maven的生命周期:对maven项目的构建过程进行了抽象和统一。
maven中有3套相互独立的声明周期:
clean
:清理工作default
:核心工作,如:编译、测试、打包、安装、部署site
:生成报告、发布站点
我们只关注下面这5个阶段
单元测试
测试
:是一种用来促进鉴定软件的正确性、完整性、安全性、质量可靠性的过程
测试阶段划分
:单元测试、集成测试、系统测试、验收测试。
测试方法
:白盒测试、黑盒测试及灰盒测试
单元测试
:针对最小的功能单元(方法),编写测试代码对其正确性进行测试。
JUnit
:最流行的Java测试框架之一,提供了一些功能,方便程序进行单元测试(第三方公司提供)
使用main方法测试的缺点:
- 测试代码和源代码未分开,难维护
- 一个方法测试失败,影响后面方法
- 无法自动化测试,得到测试报告
使用JUnit
单元测试优点:
- 测试代码和源代码分开,便于维护
- 可根据需要进行自动化测试
- 可自动分析测试结果,产出测试报告
使用\(JUnit\),对业务方法进行测试
- 在
pom.xml
中引入\(JUnit\)的依赖 - 在\(test/java\)目录下,创建测试类,并编写对应的测试方法,并在方法上声明
@Test
注解 - 运行单元测试(测试通过:绿色,测试失败:红色)
JUnit
单元测试类命名规范为:xxxxTest.Junit
单元测试方法,必须声明为\(public \;void\)
断言、常见注解
单元测试运行不报错(绿色),并不是代表代码没问题.
断言
:junit
提供了一些辅助方法,用来帮我们确定被测试的方法是否按照预期的效果正常工作,这种方法就被称为断言。
注解
单元测试-企业开发规范
原则:编写测试方法时,要尽可能的覆盖业务方法中所有可能的情况(尤其是边界值)
在maven项目中,test目录存放单元测试的代码,也可以在main目录中编写单元测试但是并不规范
我们可以通过maven的依赖范围来进行一个强制的规范化,让测试类不能写在main中
依赖范围:
- 依赖的jar包,默认情况下,可以在任何地方使用。可以通过\(<scope>...</scope>\)设置它的作用范围
- 作用范围
- 主程序范围有效。(main文件夹范围内)
- 测试程序范围有效。(test文件夹范围内)
- 是否参与打包运行。(package指令范围内)
Web入门
Springboot 入门
Spring发展到今天已经形成了一种开发生态全,Spring提供了若干子项目,每个项目用于完成特定的功能
HTTP协议
概念:\(Hyper \; Text \; Transfer \; Protocol\):超文本传输协议,规定了浏览器和服务器之间的数据传输的规则。
特点
- 基于TCP协议:面向连接,安全
- 基于请求-响应模型的:一次请求对应一次响应
- HTTP协议是无状态的协议:对于事物处理没有记忆能力。每次请求-响应都是独立的
- 缺点:多次请求间不能共享数据
- 优点:速度快
HTTP协议-请求数据格式
常见请求头和请求头的含义
http协议中请求数据一共包括三个部分:
- 请求行:请求数据的第一行
- 请求头:(key:value)
- 请求体:(与请求头之间隔了一个空行)
http请求数据获取
web服务器(tomcat)对http请求的数据进行解析,并进行了封装\((HttpServletRequest)\),在调用\(Controller\)方法的时候传递给了该方法。这样,就使得程序员不必直接对http协议进行操作,让web开发更加便捷。
http响应协议
响应数据的格式
响应行中的状态码
:
-
200
:请求成功被响应 -
404
:请求资源不存在,客户端错误 -
500
:服务器端抛异常
响应头:
响应数据设置
web服务器对HTTP协议的响应数据进行了封装\((HttpServletResoonse)\),并在调用\(Controller\)方法的时候传递给了该方法.这样,就是得程序员不用直接对协议进行操作.(和请求数据设置的是一样的)
第一种方式设置响应数据:
package com.example;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
public class ResponseController {
@RequestMapping("/response")
public void response(HttpServletResponse response) throws IOException {
//1.设置响应状态码
response.setStatus(401);
//2.设置响应头
response.setHeader("Content-Type","text/html;charset=utf-8");
//3.设置响应体
response.getWriter().write("hello response");
// return "response";
}
}
第二种方式设置响应数据(Spring提供的一种方法)基于\(ResponseEntity\):
@RequestMapping("/response2")
public ResponseEntity<String> response2() {
return ResponseEntity
.status(401)
.header("name","javaweb")
.body("hello response2");
}
两种方式的总结:
三层架构
- controller:控制层,接收前端发送的请求,对请求进行处理,并相应数据
- service:业务逻辑层,处理具体的业务逻辑
- dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增、删、改、查。
带impl后缀的一般是一个实现类
分层解耦
耦合
:用来衡量软件中各个层/各个模块的依赖关联程度
内聚
:软件中各个功能模块内部的功能联系
解耦的思路:将对象交给一个容器管理,而不是在一层中去new另一层的对象
而交给容器管理对象需要用到spring中提供的两个工具,一个是控制反转,一个是依赖注入
控制反转
:\(inversion \; of \; control\;\)简称\(IOC\)。对象创建的控制权由程序自身转移到了外部(容器),这种思想被称为控制反转
依赖注入
:\(Dependency \; Injection \;\)简称\(DI\)。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
Bean对象
:\(IOC\)容器中创建、管理的对象,称之为\(Bean\)对象。
\(IOC\&DI\)入门
- 将\(Dao\)及\(Service\)层的实现类,交给\(IOC\)容器管理
- 为\(Controller\)及\(Service\)注入运行时所依赖的对象
实现上面的第一步需要一个注解@Component
,在类前面加上@Component
表示将这个类交给\(IOC\)容器进行管理
实现上面的第二步只需要在成员变量上加上@Autowired
即可,这个注解的作用就是在运行时,自动去\(IOC\)容器中找到对应类型的\(Bean\)对象赋值给当前类中创建的引用
\(IOC\)和\(DI\)详解
要把某个对象交给\(IOC\)容器管理,需要在对应的类上加上如下注解之一:
声明\(bean\)的时候,可以通过注解的\(value\)属性指定\(bean\)的名字,如果没有指定,默认为类名首字母小写
- 上面的\(bean\)的四大注解,要想在声明之后生效,还需要被 组件扫描注解\(@ComponentScan\)。
- 但是在实际开发中,虽然我们没有显示配置,但是这个注解实际上已经包含在启动类声明注解\(@SpringBootApplication\)中,默认的扫描范围是启动类所在包及其子包。
\(DI\)依赖注入
基于@\(Autowired\) 进行依赖注入的常见方式有如下三种:
-
.属性注入
-
.构造函数注入
-
.setter注入
真实的项目中,很多企业都是用第一种属性注入,代码更加简洁。
@\(Autowired\)注解,默认是按照类型进行注入的。
如果存在多个相同类型的\(bean\),将会报出错误.
解决方案如下:
- 在我们要注入的\(bean\)上面加上@\(Primary\)注解
- 通过@\(Qualifier\)来指定我们要注入哪个\(bean\),@\(Qualifier\)的\(value\)属性中指定要注入\(bean\)的名字
- @\(Resource\)注解