Springboot3.x 进阶-配置和序列化
Spring Boot 应用程序以其灵活和强大的配置机制而著称,其中配置文件扮演着不可或缺的角色。以下是有关 Spring Boot 配置文件的详细说明:
-
基础配置文件:
application.properties
文件:作为最常用的配置文件,它采用了传统的键值对形式,以简单的 key=value 格式来定义配置项,非常适合表示层次结构较为简单的设置。此格式直观易懂,便于快速编辑和维护,为开发者提供了极大的便利性。
# 服务器端口和上下文路径
server.port=8080
server.servlet.context-path=/myqpp
# Mysql数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/data_test
spring.datasource.username=myuser
spring.datasource.password=mypassword
spring.jpa.hibernate.ddl-auto=update
# 日志配置
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate.SQL=INFO
# 模板引擎
spring.thymeleaf.cache=false
# 用户自定义配置
myapp.custom.message=Hello, welcome to study of springboot application!
application.yml
或 application.yaml
:这两种文件格式是等价的,均使用 YAML (YAML Ain't Markup Language) 格式。相较于传统的 properties
文件,YAML 格式更注重数据结构的层次感与配置项之间的关系,并且提高了配置的可读性,特别适合用来管理复杂和嵌套的配置信息。
● 下面将上述关于 application.properties
的示例内容转换为 application.yml
格式:
server:
port: 8080
servlet:
context-path: /myqpp
spring:
datasource:
url: jdbc:mysql://localhost:3306/data_test
username: myuser
password: mypassword
hikari:
driver-class-name: com.mysql.cj.jdbc.Driver # 如果需要指定驱动类名,可以这样配置
jpa:
hibernate:
ddl-auto: update
thymeleaf:
cache: false
logging:
level:
org:
springframework:
web: DEBUG
hibernate:
SQL: INFO
myapp:
custom:
message: "Hello, welcome to study of springboot application!"
多环境配置支持:
Spring Boot 提供了灵活的机制来支持不同部署环境下的配置管理,通过使用 profile(环境标识)来区分如开发、测试和生产等不同的运行环境。针对特定环境的配置文件可以命名为:
这些文件允许你为每个环境定义独特的设置,而不会影响其他环境的配置。
在应用程序启动时,可以通过系统属性或命令行参数指定要激活的 profile,例如使用 -Dspring.profiles.active=dev
来激活开发环境配置。Spring Boot 会自动加载对应的环境配置文件,并将其与通用的 application.yml
或 application.properties
文件中的配置合并。这样可以确保在不同环境中运行时,应用能够获取正确的配置信息,同时保持配置管理的一致性和简洁性。
application-dev.yml
或application-dev.properties
(用于开发环境)application-prod.yml
或application-prod.properties
(用于生产环境
Bootstrap 配置文件:
bootstrap.properties
或 bootstrap.yml
是 Spring Boot 应用中的一种特殊配置文件,它在应用程序的初始化阶段即开始加载,其优先级高于标准的 application
配置文件。这类配置文件主要用于配置那些需要在应用启动前就确定的外部化设置,例如配置中心的服务地址、加密和解密所需的密钥等关键信息。这确保了应用程序能够在初始化过程中正确地连接到配置中心,从而获取动态配置和其他运行时参数。
使用 bootstrap
配置文件的主要场景包括但不限于:
总之,bootstrap
配置文件为那些必须在应用上下文创建之前处理的任务提供了支持,确保了应用能够以正确的配置启动并运行。
- 配置中心集成:当使用如 Spring Cloud Config 这样的配置中心时,你需要在应用启动时就连接到配置中心以加载最新的配置。
- 安全性和加密:对于涉及敏感数据(如数据库密码)的加密/解密操作,可以在
bootstrap
文件中定义必要的密钥或凭证。 - 微服务注册与发现:如果应用依赖于服务发现机制(如 Eureka),那么相关配置也通常放置在此类文件中,以便尽早完成服务注册和发现过程。
spring:
application:
name: my-application # 应用名称,用于识别当前应用
cloud:
config:
uri: http://config-server-host:8888 # 配置中心地址,用于微服务之间的通信
fail-fast: true # 当无法从配置中心获取配置时,是否立即失败
encrypt:
key-store:
location: classpath:keystore.jks # 加密密钥库位置
password: mysecret # 密钥库访问密码
alias: mykey # 密钥别名
secret: anothersecret # 解密密钥密码
Springboot 提供了更多丰富的配置项,有兴趣的小伙伴们可以查询官方文档,这里我们就不在过多的赘述。
JSON序列化
在 Spring Boot 中,Jackson JSON 处理库是默认集成的工具,它使得将 Java 对象转换成 JSON 格式的数据以及从 JSON 数据反序列化为 Java 对象变得非常简便。在 RESTful API 开发中,Jackson 提供的一系列注解允许开发者定制 Java 类和 JSON 数据之间的映射规则,从而实现更灵活的数据处理。以下是 Jackson 常用注解的功能说明:
-
@JsonInclude(JsonInclude.Include.NON_NULL):此注解用于类级别或字段级别,指示 Jackson 在序列化过程中忽略那些值为
null
的属性,避免了不必要的数据传输。 -
@JsonIgnoreProperties(ignoreUnknown = true):当应用于类时,该注解确保 Jackson 在遇到未映射到 Java 类中的额外 JSON 属性时不会抛出异常,而是直接忽略这些未知属性。
-
@JsonPropertyOrder({...}):通过指定一个属性名数组,可以控制 JSON 输出时对象属性的顺序,这对于保持 API 返回结果的一致性特别有用。
-
@JsonProperty({...}):
- 此注解主要用于字段上,用来定义 Java 字段与 JSON key 之间的映射关系,例如,可以将 Java 类中的
id
字段映射为 JSON 中的"emp_id"
。 - 它还支持设置
required = true
,以确保该属性在 JSON 输入中必须存在,否则会触发反序列化失败。
- 此注解主要用于字段上,用来定义 Java 字段与 JSON key 之间的映射关系,例如,可以将 Java 类中的
-
@JsonFormat({...}):对于日期时间类型的属性(如
LocalDate
),可以通过这个注解来指定格式化模式,保证日期在序列化和反序列化时按照预期的方式呈现。 -
@JsonIgnore:当这个注解被添加到字段上时,意味着该字段将在序列化和反序列化的过程中被完全忽略,常用于处理不想暴露给客户端的敏感信息,比如
socialSecurityNumber
。 -
@JsonInclude(JsonInclude.Include.NON_EMPTY):不同于
@JsonInclude.Include.NON_NULL
,这个注解应用于集合类型(如列表)时,表示只有当集合非空且至少包含一项时才会出现在最终的 JSON 输出中,有助于减少冗余数据。
上述注解帮助开发人员更加精细地控制 JSON 和 Java 对象之间的转换过程,从而提高了应用程序的灵活性和安全性。在实际应用中,合理运用这些注解能够显著提升 API 设计的质量,并简化数据处理逻辑。
示例
//定义一个员工类
package com.coderlk.demo.model;
import com.fasterxml.jackson.annotation.*;
import lombok.Data;
import java.time.LocalDate;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonPropertyOrder({"id", "firstName", "lastName", "birthday", "address", "departments"})
@Data
public class Employee {
public Employee() {
}
public Employee(long id, String firstName, String lastName, LocalDate birthday, Address address, String socialSecurityNumber) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.birthday = birthday;
this.address = address;
this.socialSecurityNumber = socialSecurityNumber;
}
@JsonProperty("emp_id")
private long id;
@JsonProperty(value = "first_name", required = true)
private String firstName;
@JsonProperty("last_name")
private String lastName;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate birthday;
private Address address;
// Ignore the sensitive property
@JsonIgnore
private String socialSecurityNumber;
// Include only if not empty or null
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<String> departments;
}
员工的地址
package com.coderlk.demo.model;
import lombok.Data;
@Data
public class Address {
public Address() {
}
public Address(String street, String city, String state, String postalCode) {
this.street = street;
this.city = city;
this.state = state;
this.postalCode = postalCode;
}
private String street;
private String city;
private String state;
private String postalCode;
}
上面这段代码简单的定义了员工类(Emplyee) 和地址类(Address)
接下来我们写个controller来验证序列化后的结果
package com.coderlk.demo;
import com.coderlk.demo.model.Address;
import com.coderlk.demo.model.Employee;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import java.util.Arrays;
@RestController
@RequestMapping("/v1/")
public class JsonDemoController {
@GetMapping("/employees")
public Employee getEmployee() {
Address address = new Address("武汉文化大道", "武汉",
"中国", "430064");
// 创建 Employee 对象
Employee employee = new Employee(1L, "kevin",
"Lee", LocalDate.of(1980, 12, 10),
address, "420105198012107895");
employee.setDepartments(Arrays.asList("OT", "Development"));
return employee;
}
}
执行返回结果如下:
{
"emp_id": 1,
"first_name": "kevin",
"last_name": "Lee",
"birthday": "1980-12-10",
"address": {
"street": "武汉文化大道",
"city": "武汉",
"state": "中国",
"postalCode": "430064"
},
"departments": [
"OT",
"Development"
]
}
从运行结果可以看出,firstName,lastName,birthday已经按照json制定的转换格式输出,本节完毕。
注:各位亲爱的小伙伴们,今年是我从事软件行业的第20年,通过博客记录的方式将我知道的、理解的、有帮助的都分享给大家。同时,也提供就业指导,专业简历优化服务。你们的支持是我最大的动力