SpringBoot入门
注解
- @RestController 请求处理类
- @RequestMapping(“/hello”) 根据请求地址调用方法
pom.xml文件概述
所有springboot的工程都要继承这个parent工程
依赖信息
启动类
用于启动Spring Boot工程
请求处理类
@RequestMapping指定请求路径
HTTP协议
概述
规定了浏览器和服务器之间数据传输的规则(格式)
基于TCP,面向连接,基于请求-响应模型,一次请求一次响应
HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的->多次请求间不能共享数据,速度快
请求协议
- 请求行:请求数据第一行(请求方式、资源路径、协议)
- 请求头:请求数据第二行开始,格式key:value。常见key:Host(请求的主机名)、User-Agent(浏览器版本)、Accept(浏览器能接收的资源类型)Accept-Language(浏览器偏好的语言)、Accept-Encoding(浏览器支持的压缩类型)、Content-Type(请求主题的数据类型)、Content-Length(请求主体的大小)
- 请求体:POST请求独有,存放请求参数(POST和GET区别:GET的请求参数在请求行中,没有请求体,GET请求大小有限制;POST的请求参数在请求体中,POST请求大小没有限制)
响应协议
- 响应行:响应数据第一行(协议、状态码、描述)
- 响应头:响应数据第二行开始,格式:key:value
- 响应体:最后一部分,存放响应数据
协议解析
概念:超文本传输协议,规定了浏览器和服务器之间数据传输的规则
Tomcat
目录格式
- bin:可执行文件
- conf:配置文件
- lib:Tomcat依赖的jar包
- logs:日志文件
- temp:临时文件
- webapps:应用发布目录(如果我们要部署应用程序就放在这)
- work:工作目录
Tomcat基本使用
- 启动:bin/startup.bat
若无法启动,参考“startup.bat无法启动” - 关闭:直接X,shutdown.bar,Ctrl+C
- 部署:将web应用放置到webapps目录下,然后在浏览器访问locakhost:端口/“webapps下的应用相对路径”
SpringBoot起步依赖
在pom.xml内加入起步依赖:如spring-boot-starter-web
,包含web应用开发所需要的常见依赖。并且通过Maven的依赖传递将其他依赖传递下来。而web的依赖传递内包括Tomcat,因此在使用SpringBoot和Maven构建项目时不需要手动下载Tomcat(内嵌Tomcat服务器)。
请求数据
请求
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。
作用:进行接口测试
可以在Postman内直接发出请求,这样就不用后端工程师再自己去写前端的代码进行发送HTTP请求。
简单参数
原始方法:在controller(即加了@RestController的方法)中定义一个方法,在方法形参中声明HttpServletRequest对象,这个对象中会封装前端发送的所有请求数据,之后我们可以调用HttpServletRequest的方法getParameter("参数名")
来获取请求参数
Tips:GET方式要在请求行中填入参数,POST方式要在请求体中填入参数
获取参数方式
- HttpServeletRequest方法:通过在根据请求url导航的方法的形参部分添加HttpServeletRequest对象获取
繁琐,由于读入的都是String类型所以需要手动进行类型转换
@RequestMapping("/simpleParam")
public String simpleParam(HttpServletRequest request){
//获取参数
String name = request.getParameter("name");
String Agestr = request.getParameter("age");
//类型转化
int age = Integer.parseInt(Agestr);
- SpringBoot方法:只需要导航到的方法的参数名与形参变量名相同,定义形参即可接受参数
SpringBoot会自动进行绑定和数据类型转换
@RequestMapping("/simpleParam")
public String simpleParam(String name, Integer age){
如果方法形参的名称和请求参数名称不匹配,可以使用@RequestParam
完成映射。
public String simpleParam(@RequestParam(name="name") String username, Integer age)
@RequestParam
注解隐含一个required属性,默认为true,表示在前端发出请求时,此参数必须传递,如果不传递则报错,如果设置为false则为可选。
实体参数
请求参数名和形参对象属性名相同,定义POJO接受即可
如果请求参数很多,我们用一个一个形参去接收明显不合适,因此有了另一种方法:定义一个实体类,在其中设定与所有参数对应的变量,并且作为方法的形参去接收所收到请求中的参数。
规则:实体类的属性名要和请求参数名保证一致
//实体类
public class User {
private String name;
private Integer age;
}
//请求处理函数
@RequestMapping("/simplePojo")
public String simplePojo(User user){
System.out.println(user);
return "OK";
}
复杂实体参数
如果一个请求参数有多个属性值,就要运用下面的写法
//实体类
public class User {
private String name;
private Integer age;
private local Local;
//实体类内的实体类属性
public class local {
private String city;
private String province;
数组参数
请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数(比如在使用复选框要传送所选择数据的时候)
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){
System.out.println(Arrays.toString(hobby));
return "OK";
}
集合参数
请求参数名和形参集合名相同且请求参数为多个,@RequestParam
绑定参数关系(数组可以直接封装)
@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby){
System.out.println(hobby);
return "OK";
}
日期参数
使用@DataTimeFormat
注解完成日期参数格式转换
方法形参的名称要和请求参数的名称一致
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
System.out.println(updateTime);
return "OK";
}//注意是MM和HH
JSON参数
JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,使用@RequestBody
注解标识
JSON数据放在请求体中传递,因此要用POST请求方式
`
@RequestMapping("/jsonParam")
public String dateParam(@RequestBody User user){
System.out.println(user);
return "OK";
}
路径参数
通过请求URL直接传递参数,使用{…}来标识该路径参数,需要使用@PathVariable
获取路径参数
多个路径参数
@RequestMapping("/path/{id}/{name}")
public String PathParam(@PathVariable Integer id,@PathVariable String name){
System.out.println(id+": "+name);
return "OK";
}
{…}和形参要名字相同。
响应数据
ResponseBody
- 类型:方法注解、类注解
- 位置:Controller类上/方法上
- 作用:将方法返回值直接响应,如果返回值类型是实体对象/集合,将会直接转换为JSON格式响应
- 说明:@RestController = @Controller + @ResponseBody
为了让前端可以收到统一格式的数据,我们可以创建一个响应类,用于存储响应数据,返回响应数据的时候直接返回这个响应类对象,会自动转化为JSON格式
分层解耦
三层架构
- controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据
- service:业务逻辑层,处理具体的业务逻辑
- dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增删改查
分层解耦
内聚:软件中各个功能模块内部的功能联系
耦合:衡量软件中各个层/模块之间的依赖、关联的程度
软件设计原则:高内聚低耦合
我们在进行分层架构时,我们会去调用new一个实现类的对象从而使用其的方法,但是这样也造成了一种情况:如果实现类发生了改变,那调用层的代码也要进行修改,那这就造成了耦合,我们要去降低不同层之间的耦合程度。
由此出现了容器:我们不去new一个实现类对象B,并且采用多态的写法,用B所继承的接口/类A,去声明一个对象,并且这个对象不用new,而是让被调用对象自己创建一个对象放到容器内,当调用层的函数内需要实现类对象时再去容器内寻找对应的多态,自动赋值。这样B修改的时候,继承的接口/类不变,这样调用层的函数一样可以在容器内找到所需的对象,而不用去改变代码。
这里面就涉及了两个概念:控制反转(IOC),依赖注入(DI)
IOC&DI入门
IOC:Inversion Of Control。对象的创建控制权由程序自身转移到外部(容器),这种思维成为控制反转。IOC容器也成为Spring容器
DI:Dependency Injection。容器为应用程序提供运行时所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象,称之为bean。
- 要向将类交给容器来进行管理创建则要在类上加入
@Component
注解。 - 要进行自动依赖注入则要在类变量上加上
@Autowired
注解,运行时,IOC容器会提供该类型的bean对象,并赋值给该变量,即依赖注入。
IOC详解
@RestController内部就包含了@Controller
bean的名字可以自定义,也可以默认(类名的首字母小写形式);要自定义则加上属性值value=“…”,
@Component( "...")
Tips:
- 在Springboot集成web开发中,声明控制类bean只能用
@Controller
- 要想让注解生效,还需要被组件扫描注解
@ComponentScan
扫描,这个注解以及包含在启动类声明注解@SpringBootApplication中,默认扫描的范围是启动类所在的包及其子包,虽然可以通过设置参数来达到扫描外面的包的情况,但是由于这个不符合项目目录规范,所以不作说明。
DI详解
如果同一个类型的类有两个实现,并且两个实现上都加上了注解@Service/@Component
,就会报错。
解决方式:
- @Primary:设置优先级,在想优先生效的实现类上再加上此注解:
@Primary
。 - @Qualifier:设置有限即,将想优先生效的实现类的bean名通过此注解和@Autowired配合使用,添加在调用类上:
@Qualifier("bean名")+@Autowired
。 - @Resource:使用@Resource注解代替@Autowired,@Autowired默认根据类型进行注入,而@Resource默认根据bean名进行注入:
@Resource(name = "bean名")
Tips:@Resource和@Autowired的区别:1. @Autowired是spring框架提供的注解,@Resource是JDK提供的注解。 2. @Autowired是默认按照类型注入,@Resource是默认按照bean名注入。