5.6 KiB
5.6 KiB
一、JsonView
JsonView 是 Jackson 提供的注解,用于控制对象序列化/反序列化时包含哪些字段。可以实现:
- 不同接口返回不同字段
- 敏感字段过滤
- 前后端数据分离
1.1 添加依赖
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
1.2 使用
- 定义视图接口
// JsonView 视图定义
public class Views {
// 基础视图 - 所有接口都包含的字段
public interface Basic {}
// 返回给前端时使用
public interface Response extends Basic {}
// 接收前端数据时使用
public interface Request extends Basic {}
// 管理视图 - 包含所有字段
public interface AdminView extends ReadView {}
}
- Dto对象使用JsonView
@Data
public class UserDTO {
@JsonView(Views.Response.class)
private Long id;
@JsonView(Views.Request.class)
@NotBlank(message = "密码不能为空")
@Size(min = 6, message = "密码至少6位")
private String password;
@JsonView(Views.Basic.class)
@NotBlank(message = "用户名不能为空")
private String username;
@JsonView(Views.Basic.class)
@Email(message = "邮箱格式不正确")
private String email;
@JsonView(Views.Basic.class)
private String nickname;
@JsonView(AdminView.class)
private Boolean isActive;
}
- Controller中使用
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
@JsonView(UserDTO.Response.class)
public UserDTO createUser(@RequestBody @JsonView(UserDTO.Request.class) UserDTO userDTO) {
return userService.createUser(userDTO);
}
@PutMapping("/{id}")
@JsonView(UserDTO.Response.class)
public UserDTO updateUser(@PathVariable Long id,
@RequestBody @JsonView(UserDTO.Request.class) UserDTO userDTO) {
return userService.updateUser(id, userDTO);
}
@GetMapping("/{id}")
@JsonView(UserDTO.Response.class)
public UserDTO getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
@GetMapping("/{id}/admin")
@JsonView(UserDTO.AdminView.class)
public UserDTO getAdminUser(@PathVariable Long id) {
return userService.getAdminUserById(id);
}
}
二、MapStruct
MapStruct 是一个 Java 注解处理器,用于生成类型安全的 Bean 映射代码:
- 编译时生成映射代码,无运行时性能损失
- 类型安全
- 支持复杂映射
2.1 添加依赖
<properties>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2.2 使用
import org.mapstruct.*;
import java.util.List;
import java.time.format.DateTimeFormatter;
@Mapper
public interface UserMapper {
@Mapping(target = "name", source = "userName") // 字段名不同
@Mapping(target = "phoneNumber", source = "phone") // 字段名不同
@Mapping(target = "description", source = "remark") // 字段名不同
@Mapping(target = "statusDesc", ignore = true) // 需要特殊处理
@Mapping(target = "createTime", ignore = true) // 需要格式化
UserDTO toDTO(User user);
@Mapping(target = "userName", source = "name")
@Mapping(target = "phone", source = "phoneNumber")
@Mapping(target = "remark", source = "description")
@Mapping(target = "password", ignore = true) // 密码不映射
User toEntity(UserDTO dto);
// 列表映射
List<UserDTO> toDTOList(List<User> users);
// 带默认值的映射
@Mapping(target = "name", source = "userName")
@Mapping(target = "phoneNumber", source = "phone")
@Mapping(target = "description", source = "remark", defaultValue = "暂无描述")
@Mapping(target = "statusDesc", expression = "java(convertStatus(user.getStatus()))")
@Mapping(target = "createTime", expression = "java(formatTime(user.getCreateTime()))")
UserDTO toDTOWithDefault(User user);
// 自定义转换方法
default String convertStatus(Integer status) {
if (status == null) return "未知";
switch (status) {
case 0: return "禁用";
case 1: return "正常";
case 2: return "锁定";
default: return "未知";
}
}
// 时间格式化方法
default String formatTime(LocalDateTime time) {
if (time == null) return "";
return time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
}
需要执行mvn compile后检查target/generated-sources文件夹下是否存在生成的转换代码。