Spring Boot中将特定字段映射到HTML页面:DTO与视图渲染实践
在Spring Boot Web开发中,经常需要将后端数据传递到前端HTML页面进行展示。直接使用实体类(Entity)可能会暴露敏感信息或包含不必要的字段,这时DTO(Data Transfer Object)就派上用场了。本文将详细介绍如何使用DTO将特定字段映射到HTML页面,并结合Thymeleaf模板引擎实现视图渲染。
一、为什么需要使用DTO?
在实际项目中,我们通常会遇到以下场景:
实体类包含敏感字段(如密码、权限信息)
需要组合多个实体的字段到一个页面展示
前端只需要实体类的部分字段
需要对字段进行格式化或转换后再展示
此时,直接使用实体类进行数据传输会带来安全风险和维护困难。DTO作为数据传输的载体,可以有效解决这些问题。
二、项目准备
首先创建一个简单的Spring Boot项目,添加以下依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies>
三、创建实体类和DTO
1. 实体类 User
public class User {
private Long id;
private String username;
private String password; // 敏感字段
private String email;
private LocalDateTime createTime;
// 构造方法、getter和setter省略
}2. DTO类 UserDTO
public class UserDTO {
private Long id;
private String username;
private String email;
private String formattedCreateTime; // 格式化后的时间
// 构造方法、getter和setter省略
}四、创建Controller实现数据传递
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUserById(@PathVariable Long id, Model model) {
// 模拟从数据库获取用户信息
User user = getUserFromDB(id);
// 将User转换为UserDTO
UserDTO userDTO = convertToDTO(user);
// 将DTO添加到模型,供Thymeleaf模板使用
model.addAttribute("user", userDTO);
return "user-detail"; // 返回对应的HTML模板
}
private User getUserFromDB(Long id) {
// 实际项目中这里会从数据库查询
User user = new User();
user.setId(1L);
user.setUsername("john_doe");
user.setPassword("123456"); // 敏感信息
user.setEmail("john@ippipp.com");
user.setCreateTime(LocalDateTime.now());
return user;
}
private UserDTO convertToDTO(User user) {
UserDTO dto = new UserDTO();
dto.setId(user.getId());
dto.setUsername(user.getUsername());
dto.setEmail(user.getEmail());
// 格式化时间
dto.setFormattedCreateTime(user.getCreateTime().format(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
));
return dto;
}
}五、使用Thymeleaf渲染页面
创建src/main/resources/templates/user-detail.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>用户详情</title>
</head>
<body>
<h1>用户详情</h1>
<div>
<p><strong>ID:</strong> <span th:text="${user.id}"></span></p>
<p><strong>用户名:</strong> <span th:text="${user.username}"></span></p>
<p><strong>邮箱:</strong> <span th:text="${user.email}"></span></p>
<p><strong>创建时间:</strong> <span th:text="${user.formattedCreateTime}"></span></p>
</div>
</body>
</html>六、高级用法:使用MapStruct简化转换
手动编写转换代码比较繁琐,可以使用MapStruct自动生成映射代码。
1. 添加MapStruct依赖
<dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.3.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.5.3.Final</version> <scope>provided</scope> </dependency>
2. 定义Mapper接口
@Mapper(componentModel = "spring")
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
@Mapping(source = "createTime", target = "formattedCreateTime",
dateFormat = "yyyy-MM-dd HH:mm:ss")
UserDTO toDTO(User user);
}3. 在Controller中使用Mapper
@Autowired
private UserMapper userMapper;
@GetMapping("/{id}/mapstruct")
public String getUserWithMapStruct(@PathVariable Long id, Model model) {
User user = getUserFromDB(id);
UserDTO userDTO = userMapper.toDTO(user);
model.addAttribute("user", userDTO);
return "user-detail";
}七、处理集合数据
当需要展示用户列表时,同样可以使用DTO:
@GetMapping("/list")
public String getUserList(Model model) {
List<User> users = getUsersFromDB();
List<UserDTO> userDTOs = users.stream()
.map(userMapper::toDTO)
.collect(Collectors.toList());
model.addAttribute("users", userDTOs);
return "user-list";
}对应的HTML模板:
<table>
<thead>
<tr>
<th>ID</th>
<th>用户名</th>
<th>邮箱</th>
<th>创建时间</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}">
<td th:text="${user.id}"></td>
<td th:text="${user.username}"></td>
<td th:text="${user.email}"></td>
<td th:text="${user.formattedCreateTime}"></td>
</tr>
</tbody>
</table>八、总结
通过本文的介绍,我们学习了:
DTO的作用和使用场景
如何在Spring Boot中创建和使用DTO
结合Thymeleaf模板引擎渲染页面
使用MapStruct简化对象转换
处理集合数据的映射
使用DTO可以有效地控制数据传输的范围和格式,提高系统的安全性和可维护性。在实际项目中,建议始终使用DTO来进行前后端的数据交互。