我是小先,一个专注大数据、分布式技术的非斜杠青年,爱Coding,爱阅读、爱摄影,更爱生活!
源代码仓库:https://github.com/zhshuixian/learn-spring-boot-2
大数据小先的博客:https://me.csdn.net/u010974701
《Spring Boot 2.X 实战》系列文章将分为如下几个模块,本小节将实战如何构建 RESTful API,并自定义返回数据和HTTP 返回码和传入数据,下一小节将实战 Spring Boot 整合 Log4j2 与 Slf4j 实现日志打印和输出到文件:
上一章中主要介绍了 Spring Boot 和如何在 IDEA 中创建 Spring Boot 项目,本章将在上一章的基础上,介绍如何运行 Spring Boot 项目,并编写一些 RESTful API,本章主要包含如下内容:
运行 Spring Boot 项目
编写 RESTful API 接口
编写、运行单元测试
设置端口号和 HTTPS
打包成 Jar
1、运行 Spring Boot 程序
IDEA 在完成 Spring Boot 项目的依赖资源下载后,会自动配置 Spring Boot 的启动方式。可以通过快捷键 "Shift + F10" ,或者直接点击右上角的运行按钮。如果是社区版的 Idea,可以通过直接运行 @SpringBootApplication 注解的类,这个类会在项目创建的时候自动生成。
启动完成后,会在下方窗口出现如下提示:
in 0.884 seconds (JVM running
打开 Postman,访问 http://localhost:8080 会出现如下提示,这不是因为程序出错,我们还没有编写任何 API 接口。
1.1、Spring Boot 入口类和 @SpringBootApplication
Spring Boot 项目在新建的时候会自动生成入口类,默认名称为 *Application,一般情况,把入口类放在 groupId + arctifactID 的 package 路径下。入口类的 mian 方法其实就是启动 Java 程序标准的 main 方法,SpringApplication.run(BootApplication.class, args) 表示启动 Spring Boot 项目。
@SpringBootApplication
@SpringBootApplication 是 Spring Boot 的核心注解,可以写成如下三个注解,效果是等同的:
@Configuration
代码解析:
@Configuration 实际上是 @Component 的再封装,用于定义配置类,用于替换相应的 xml 配置文件,标识这个类可以用 Spring IOC 容器作为 Bean 定义的来源。被注解的类包含一个多个 @Bean 注解的方法。
@Bean 注解的方法将产生一个 Bean 对象,这些方法只会调用一次,然后由 Spring 放入 IOC 容器中。
@ComponentScan 默认把当前 package 路径作为扫描路径,扫描并把标识了@Controller,@Service,@Repository,@Component 注解的类到 Spring 容器中。可以使用 @ComponentScan(value = "") 指定扫描路径。
@EnableAutoConfiguration 让 Spring Boot 根据依赖自动为当前项目进行自动配置。例如添加了 mybatis-plus-boot-starter 这个依赖,Spring Boot 会自动进行相关配置。
2、实战 RESTful API
这一小节,将介绍实战如何构建 RESTful API 接口,如何返回和传入不同格式的数据。
2.1、 Hello Spring Boot
实现一个 API 接口,返回字符串 “ Hello Spring Boot”。
新建一个 HelloSpringBoot 的类,输入如下内容,然后再次运行 Spring Boot:
@RestController
打开 Postman,访问 http://localhost:8080/hello/string ,可以看到返回了字符串 “ Hello Spring Boot”。
代码解释 这段代码。主要使用了两个注解和写了一个方法返回一个字符串。
@RestController 是一个组合注解,等同于 @Controller 加 @ResponseBody 。
@Controller 声明这是一个控制器,注解的类可以接受 HTTP 请求,只使用该注解的话,视图解析器会解析 return 返回字符对应的 HTML 、JSP 页面等;
@ResponseBody 会直接把 return 的内容写入 HTTP Response Body 中,视图解析器 InternalResourceViewResolver 将不起作用。
@ResponseStatus(HttpStatus.XXX) 设置 HTTP Response 的状态码,默认 200。
@RequestMapping 可以注解在类上,也可以注解在方法上。用于指定请求 URL 和对应处理方法的映射。注解在类上的 @RequestMapping("hello") 表示这个类下的所有 URL 为 /hello/ 加 注解在方法上的 RequestMapping 的值。可以通过如下方法指定 HTTP 请求方法;如果指定请求方法 method 则必须使用改方法请求,否则报 "Request method 'XXX' not supported"。
// 等同于 @GetMapping("string") 仅支持 GET 方法访问
2.2、返回 JSON数据
上一个例子中,RESTful API 接口返回了字符串 String。对于 Spring Boot 来说,返回 JSON 数据也是相当简单的。这一小节将实现一个返回如下 JSON 数据的接口:
{
"status": "success",
"messages": "Hello Spring Boot By JSON"
}
新建一个类 Messages:这里使用 lombok ,记得引入 'org.projectlombok:lombok' 这个依赖、 IDEA 勾选 “Enable annotation processing ” 和安装 lombok 插件。
@AllArgsConstructor
在 HelloSpringBoot 这个类新增方法 helloJson,然后重新运行项目:
@RequestMapping(
通过 Postman 访问 http://localhost:8080/hello/json , 则返回了如上所示的 JSON 数据。
2.3、传入数据 @RequestParam
@RequestParam 是传入 ?name0=value0&name1=value1 这中类型参数的注解,用法如下:
@RequestParam(value =
value:参数名,可以不设置,默认跟方法函数的形参名相同
required :是否必须传入,默认 false ,设置为 true 则必须传入这个参数,否则报错
defaultValue:默认值,如果设置了默认值,设置 required = true 的情况下不传入该参数不会报错
在 HelloSpringBoot 这个类新增方法 param ,然后重新运行项目:
@GetMapping(value =
通过 Postman 使用 GET 方法访问 http://localhost:8080/hello/param?username=xiaoxian , 改变 username 参数的值,查看不同值返回的结果。
{
"status": "success",
"messages": "Hello xiaoxian"
}
@PathVariable 注解的作用是把 URL 路径的变量作为参数传入方法函数中。例如 GitHub 的个人主页URL https://github.com/zhshuixian 就是访问到小先的主页。https://github.com/{username} 中的 username 就是 PathVariable。
"username" ,name =
value:PathVariable 名称,需要跟 RequestMapping 中括号括起来的一样 { }
name:PathVariable 名称,跟 value 一样,两者仅需使用一个即可
required:是否需要传入,默认 true
在 HelloSpringBoot 这个类新增方法 pathVariable,然后重新运行项目:
@PostMapping(value =
通过 Postman 使用 POST 方法访问 http://localhost:8080/hello/path/username 改变 {username} 的值,查看不同值返回的结果。
{
"status": "success",
"messages": "Hello username"
}
@RequestBody 注解的作用是接收前端传入的 JSON 数据,假如我们需要提交如下数据:
{
"username": "user",
"password": "springboot"
}
@RequestBody
required : 是否必须传入,默认为 true,设置 false 时候,如何没有传任何 json 数据,将不会 new 该对象,因此在使用对象的时候要注意 Null PointerException
新建一个 SysUser 的类:
@AllArgsConstructor
在 HelloSpringBoot 这个类新增方法 body,然后重新运行项目:
@PostMapping(
打开 Postman,使用 POST 方法访问 http://localhost:8080/hello/body 并传入 JSON 数据:
通过示例可以看出 @RequestBody 注解主要是接收传入的 JSON 数据,并根据JSON 数据的 key 名称和成员变量名称对应,然后将 value 值通过 Setter 或者 AllArgsConstructor 构造函数赋值给对应名称的成员变量。在 Getter 成员变量的时候一定要注意 Null PointerException。如果 @RequestBody 注解的是 String,这会 Body 的内容当做字符串赋值:
@PostMapping(
代码运行效果如下:
Form 表单有application/x-www-form-urlencoded 、multipart/form-data 和 text/plain 三种方式,其中前两种可以比较简单的在 Spring Boot 中使用,只需把上一小节的 body 函数中的 @RequestBody 删掉即可,同样在 Getter 的时候要注意 Null PointerException:
@PostMapping(
重启项目后,打开 Postman,使用 POST 方法访问 http://localhost:8080/hello/form 并传入 Form 表单数据,如下框起来的方式都可以使用:
对于如何上传、下载文件,如何传入 XML 格式的数据,这里暂不做介绍。
单元测试作为开发过程中重要的一环,在于发现各小模块内部可能存在的错误,提高代码质量,这里将使用 JUnit 5,实战如何使用 MockMvc 和 TestRestTemplate 对刚刚构建的 RESTful API 进行单元测试。
Spring Boot 的 spring-boot-starter-test 支持 JUnit 4 和 JUnit 5 单元测试,如果你只想使用 JUnit 5 ,则应排除 JUnit 4 的依赖。
注:Spring Boot 2.2.3.RELEASE 版本新建的时候默认排除了JUnit 4 的依赖。
Gradle 排除 JUnit 4
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
Maven 排除 JUnit 4
鼠标光标放在需要新建测试类 HelloSpringBoot 的中,然后按下快捷键 Alt + Enter ,会弹出一个选项菜单,点击 Create Test ,IDEA 会自动在 test 目录下的同 package 包创建 相应的测试类 HelloSpringBootTest 。
选择 JUnit 5,勾选需要进行单元测试的函数:
打开 HelloSpringBootTest ,新增如下几个注解:
@ExtendWith(SpringExtension.class)
@ExtendWith(SpringExtension.class) 是 Spring Boot 运行 JUnit 5 所需的注解,放在测试类名之前,用来确定这个类怎么运行的。在 Spring Boot 2.1.x 之前的版本需要此注解,之后的版本,如实战项目用了 2.2.3 这个版本,已经在 @SpringBootTest 中了,你可以将其删除。
@SpringBootTest 是 1.4.0 开始引入的一个测试的注解,SpringBootTest.WebEnvironment.RANDOM_PORT 表示项目运行使用随机的端口号,classes = BootApplication.class Spring Boot 项目的启动类,以上两个参数都为非必须项。
@AutoConfigureMockMvc 自动配置 MockMVC。
实战如何使用 MockMVC 进行 POST、GET 请求,并对 HTTP 返回的状态码和 content() 中的内容进行验证是否正确。
@Autowired
代码解析
@Autowired 对类中的成员变量、方法和构造函数进行标注,完成自动装配。在本代码中,使用了此注解后,在使用 mvc 这个成员变量时,并不需要 new,交给 Spring 自动装配。有一个 required = true/false 的参数,默认为 true。
@Test 注解是 JUnit 的注解,JUnit 5 没有参数可以设置,其注解的 void 类型的方法将会当做测试用例,在执行测试的时候才会运行。
实战如何使用 TestRestTemplate进行 POST、GET 请求,上传 JSON、String 类型的数据,并接受返回的 JSON 数据和使用 assertThat 断言验证数据是否正确返回。
@Test
在 IDEA 中,单元测试代码中会自动出现绿色三角形箭头,点击即自动运行单元测试。点击类名左边的小箭头、右键“Run .....”或者快捷键 “Ctrl + Shift + F10”,运行完成后会在下方显示测试通过的案例和失败的案例。
Spring Boot 项目在启动的时候默认端口号是 8080,我们可以通过修改 src/main/resources/application.properties 这个文件来自定义端口号和启用 HTTPS。
设置端口号
在 application.properties 文件新增如下配置:
# 自定义端口号
对于 HTTPS 来说,在开发项目中你可以生成自签名证书文件,当然通过浏览器访问的话会提示你此连接不安全,以及在 Postman 中你要关闭验证 HTTPS 的功能,在部署的时候换成 CA 机构的 SSL 数字证书即可。
生成自签名证书文件
# keytool 是 JDK 提供的自签名证书生成工具,以下两个命令都可以用于生成证书
HTTPS 配置
# 启用 HTTPS
重新运行项目,打开浏览器访问 https://localhost:8000/hello/string。
打开 IDEA 的 Gradle 的工具窗口,双击运行 bootJar:
运行完成后会在 build/lib 文件夹生成一个 Jar 文件,拷贝到部署环境,运行如下命令即可部署运行:
java -jar ./boot-0.0.1-SNAPSHOT.jar
- MORE | 更多精彩文章 -
如何"干掉"恶心的 SQL 注入?
全球最厉害的 14 位程序员!请收下我的膝盖
60个Chrome神器插件大收集:助你快速成为老司机,一键分析网站技术栈
如果你喜欢本文,
请长按二维码,关注 编程技术进阶
转发至朋友圈,是对我最大的支持。
好文章,我在看❤️