Java中使用JSONUtil处理JSON数据:从前端到后端的完美转换
在现代Web开发中,JSON(JavaScript Object Notation)已经成为前后端数据交互的标准格式。作为Java开发者,我们经常需要处理从前端传来的JSON数据,将其转换为Java对象,或者将Java对象转换为JSON格式返回给前端。本文将详细介绍如何使用Hutool工具包中的JSONUtil来高效处理JSON数据。
为什么选择JSONUtil?
JSONUtil是Hutool工具包中的一个强大的JSON处理工具类,它具有以下优势:
- 简单易用:API设计简洁,学习成本低
- 功能全面:支持各种JSON操作需求
- 性能优良:基于成熟的JSON库实现
- 零依赖冲突:与Spring Boot等框架完美集成
环境准备
首先,在项目中添加Hutool依赖:
Maven依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
Gradle依赖
implementation 'cn.hutool:hutool-all:5.8.22'
基础用法
1. JSON字符串与Java对象互转
创建示例实体类
public class User {
private Long id;
private String username;
private String email;
private Integer age;
private Date createTime;
// 构造方法、getter和setter省略
}
对象转JSON字符串
import cn.hutool.json.JSONUtil;
public class JsonExample {
public static void main(String[] args) {
// 创建用户对象
User user = new User();
user.setId(1L);
user.setUsername("张三");
user.setEmail("zhangsan@example.com");
user.setAge(25);
user.setCreateTime(new Date());
// 对象转JSON字符串
String jsonStr = JSONUtil.toJsonStr(user);
System.out.println(jsonStr);
// 输出:{"id":1,"username":"张三","email":"zhangsan@example.com","age":25,"createTime":"2023-12-01 10:30:00"}
}
}
JSON字符串转对象
// JSON字符串转对象
String jsonString = """
{
"id": 1,
"username": "李四",
"email": "lisi@example.com",
"age": 28,
"createTime": "2023-12-01 10:30:00"
}
""";
User user = JSONUtil.toBean(jsonString, User.class);
System.out.println("用户名:" + user.getUsername());
System.out.println("邮箱:" + user.getEmail());
2. 处理集合类型
List转JSON
import java.util.Arrays;
import java.util.List;
List<User> userList = Arrays.asList(
new User(1L, "张三", "zhangsan@example.com", 25, new Date()),
new User(2L, "李四", "lisi@example.com", 28, new Date())
);
// List转JSON字符串
String listJson = JSONUtil.toJsonStr(userList);
System.out.println(listJson);
JSON转List
String jsonArray = """
[
{"id": 1, "username": "张三", "email": "zhangsan@example.com", "age": 25},
{"id": 2, "username": "李四", "email": "lisi@example.com", "age": 28}
]
""";
// JSON字符串转List
List<User> users = JSONUtil.toList(jsonArray, User.class);
users.forEach(user -> System.out.println(user.getUsername()));
3. 处理Map类型
import java.util.Map;
// JSON字符串转Map
String jsonStr = """
{
"name": "张三",
"age": 25,
"city": "北京",
"skills": ["Java", "Spring", "MySQL"]
}
""";
Map<String, Object> map = JSONUtil.parseObj(jsonStr);
System.out.println("姓名:" + map.get("name"));
System.out.println("年龄:" + map.get("age"));
// Map转JSON字符串
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("status", "success");
dataMap.put("message", "操作成功");
dataMap.put("data", userList);
String result = JSONUtil.toJsonStr(dataMap);
在Spring Boot中的实际应用
1. 控制器中处理JSON请求
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<?> createUser(@RequestBody String jsonData) {
try {
// 将JSON字符串转换为User对象
User user = JSONUtil.toBean(jsonData, User.class);
// 业务逻辑处理...
userService.save(user);
// 返回成功响应
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("message", "用户创建成功");
response.put("data", user);
return ResponseEntity.ok(JSONUtil.toJsonStr(response));
} catch (Exception e) {
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("status", "error");
errorResponse.put("message", "数据格式错误:" + e.getMessage());
return ResponseEntity.badRequest().body(JSONUtil.toJsonStr(errorResponse));
}
}
}
2. 批量处理JSON数据
@PostMapping("/batch")
public ResponseEntity<?> batchCreateUsers(@RequestBody String jsonArray) {
try {
// 将JSON数组转换为User列表
List<User> users = JSONUtil.toList(jsonArray, User.class);
// 数据验证
for (User user : users) {
if (user.getUsername() == null || user.getEmail() == null) {
throw new IllegalArgumentException("用户名和邮箱不能为空");
}
}
// 批量保存
List<User> savedUsers = userService.batchSave(users);
// 返回结果
Map<String, Object> response = new HashMap<>();
response.put("status", "success");
response.put("message", "批量创建成功");
response.put("count", savedUsers.size());
response.put("data", savedUsers);
return ResponseEntity.ok(JSONUtil.toJsonStr(response));
} catch (Exception e) {
return ResponseEntity.badRequest()
.body(JSONUtil.toJsonStr(Map.of("status", "error", "message", e.getMessage())));
}
}
高级特性
1. 自定义日期格式
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
// 创建自定义JSON配置
JSONConfig config = JSONConfig.create()
.setDateFormat("yyyy-MM-dd HH:mm:ss");
User user = new User();
user.setCreateTime(new Date());
// 使用自定义配置转换
String jsonStr = JSONUtil.toJsonStr(user, config);
2. 处理复杂嵌套对象
public class Department {
private Long id;
private String name;
private List<User> employees;
// getter和setter省略
}
// 处理嵌套对象
String complexJson = """
{
"id": 1,
"name": "技术部",
"employees": [
{"id": 1, "username": "张三", "email": "zhangsan@example.com", "age": 25},
{"id": 2, "username": "李四", "email": "lisi@example.com", "age": 28}
]
}
""";
Department dept = JSONUtil.toBean(complexJson, Department.class);
System.out.println("部门:" + dept.getName());
System.out.println("员工数量:" + dept.getEmployees().size());
实际案例:处理IoT设备数据
在物联网应用中,我们经常需要处理来自设备的复杂嵌套JSON数据。以下是一个智能手表设备上报数据的处理示例:
// 定义设备数据相关的实体类
public class DeviceNotification {
private String resource;
private String event;
@JsonProperty("event_time")
private String eventTime;
@JsonProperty("event_time_ms")
private String eventTimeMs;
@JsonProperty("request_id")
private String requestId;
@JsonProperty("notify_data")
private NotifyData notifyData;
// getter和setter省略
}
public class NotifyData {
private Header header;
private Body body;
// getter和setter省略
}
public class Header {
@JsonProperty("app_id")
private String appId;
@JsonProperty("device_id")
private String deviceId;
@JsonProperty("node_id")
private String nodeId;
@JsonProperty("product_id")
private String productId;
@JsonProperty("gateway_id")
private String gatewayId;
// getter和setter省略
}
public class Body {
private List<Service> services;
// getter和setter省略
}
public class Service {
@JsonProperty("service_id")
private String serviceId;
private Properties properties;
@JsonProperty("event_time")
private String eventTime;
// getter和setter省略
}
public class Properties {
@JsonProperty("BodyTemp")
private Integer bodyTemp;
@JsonProperty("HeartRate")
private Double heartRate;
private Double xueyang;
@JsonProperty("BatteryPercentage")
private Double batteryPercentage;
// getter和setter省略
}
// 处理设备上报的JSON数据
public void processDeviceData(String deviceJsonData) {
String iotDeviceJson = """
{
"resource": "device.property",
"event": "report",
"event_time": "20250217T083248Z",
"event_time_ms": "2025-02-17T08:32:48.938Z",
"request_id": "57f53c8e-9f20-4ce8-aceb-83953391c6c2",
"notify_data": {
"header": {
"app_id": "d51bfac701644b9daa4363cf76c661af",
"device_id": "67ad95860c504e29c72b2436_watch88",
"node_id": "watch88",
"product_id": "67ad95860c504e29c72b2436",
"gateway_id": "67ad95860c504e29c72b2436_watch88"
},
"body": {
"services": [
{
"service_id": "watch_services",
"properties": {
"BodyTemp": 1,
"HeartRate": 87.6276,
"xueyang": 93.12909,
"BatteryPercentage": 6.9553375
},
"event_time": "20250217T083248Z"
}
]
}
}
}
""";
try {
// 将复杂JSON转换为Java对象
DeviceNotification notification = JSONUtil.toBean(iotDeviceJson, DeviceNotification.class);
// 提取设备信息
Header header = notification.getNotifyData().getHeader();
System.out.println("设备ID: " + header.getDeviceId());
System.out.println("产品ID: " + header.getProductId());
// 处理设备服务数据
List<Service> services = notification.getNotifyData().getBody().getServices();
for (Service service : services) {
Properties props = service.getProperties();
System.out.println("=== 设备健康数据 ===");
System.out.println("体温: " + props.getBodyTemp() + "°C");
System.out.println("心率: " + props.getHeartRate() + " bpm");
System.out.println("血氧: " + props.getXueyang() + "%");
System.out.println("电池电量: " + props.getBatteryPercentage() + "%");
// 可以进一步处理数据,如存储到数据库或触发告警
if (props.getBatteryPercentage() < 10) {
System.out.println("⚠️ 设备电量不足,请及时充电!");
}
if (props.getHeartRate() > 100) {
System.out.println("⚠️ 心率异常,建议关注健康状况!");
}
}
} catch (Exception e) {
System.err.println("处理设备数据失败: " + e.getMessage());
// 记录错误日志并进行相应处理
}
}
简化版处理方式
如果不需要严格的类型约束,也可以使用Map方式灵活处理:
public void processDeviceDataWithMap(String deviceJsonData) {
try {
// 使用Map处理复杂JSON
Map<String, Object> deviceData = JSONUtil.parseObj(deviceJsonData);
// 获取嵌套数据
Map<String, Object> notifyData = (Map<String, Object>) deviceData.get("notify_data");
Map<String, Object> header = (Map<String, Object>) notifyData.get("header");
Map<String, Object> body = (Map<String, Object>) notifyData.get("body");
List<Map<String, Object>> services = (List<Map<String, Object>>) body.get("services");
// 提取设备信息
String deviceId = (String) header.get("device_id");
String nodeId = (String) header.get("node_id");
System.out.println("处理设备: " + nodeId + " (" + deviceId + ")");
// 处理服务数据
for (Map<String, Object> service : services) {
Map<String, Object> properties = (Map<String, Object>) service.get("properties");
// 安全地获取属性值
Double heartRate = getDoubleValue(properties, "HeartRate");
Double xueyang = getDoubleValue(properties, "xueyang");
Double battery = getDoubleValue(properties, "BatteryPercentage");
Integer bodyTemp = getIntegerValue(properties, "BodyTemp");
// 构建响应数据
Map<String, Object> healthData = new HashMap<>();
healthData.put("deviceId", nodeId);
healthData.put("heartRate", heartRate);
healthData.put("bloodOxygen", xueyang);
healthData.put("batteryLevel", battery);
healthData.put("bodyTemperature", bodyTemp);
healthData.put("timestamp", deviceData.get("event_time_ms"));
// 转换为JSON并存储或发送
String healthDataJson = JSONUtil.toJsonStr(healthData);
System.out.println("健康数据JSON: " + healthDataJson);
}
} catch (Exception e) {
System.err.println("处理设备数据失败: " + e.getMessage());
}
}
// 辅助方法:安全获取Double值
private Double getDoubleValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
return null;
}
// 辅助方法:安全获取Integer值
private Integer getIntegerValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value instanceof Number) {
return ((Number) value).intValue();
}
return null;
}
3. JSON路径查询
import cn.hutool.json.JSONObject;
String jsonStr = """
{
"user": {
"profile": {
"name": "张三",
"contact": {
"email": "zhangsan@example.com",
"phone": "13800138000"
}
}
}
}
""";
JSONObject jsonObj = JSONUtil.parseObj(jsonStr);
// 使用路径获取深层嵌套的值
String email = jsonObj.getByPath("user.profile.contact.email", String.class);
System.out.println("邮箱:" + email);
错误处理和最佳实践
1. 异常处理
public User parseUserSafely(String jsonData) {
try {
return JSONUtil.toBean(jsonData, User.class);
} catch (Exception e) {
log.error("JSON解析失败:{}", e.getMessage());
throw new BusinessException("数据格式不正确");
}
}
2. 数据验证
public boolean isValidJson(String jsonStr) {
try {
JSONUtil.parseObj(jsonStr);
return true;
} catch (Exception e) {
return false;
}
}
public List<User> parseAndValidateUsers(String jsonArray) {
if (!isValidJson(jsonArray)) {
throw new IllegalArgumentException("JSON格式不正确");
}
List<User> users = JSONUtil.toList(jsonArray, User.class);
// 数据验证
for (User user : users) {
if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
throw new IllegalArgumentException("用户名不能为空");
}
if (user.getAge() != null && (user.getAge() < 0 || user.getAge() > 150)) {
throw new IllegalArgumentException("年龄数值不合法");
}
}
return users;
}
性能优化建议
1. 大量数据处理
// 对于大量数据,考虑分批处理
public void processBatchData(String largeJsonArray) {
List<Map> rawList = JSONUtil.toList(largeJsonArray, Map.class);
int batchSize = 100;
for (int i = 0; i < rawList.size(); i += batchSize) {
int endIndex = Math.min(i + batchSize, rawList.size());
List<Map> batch = rawList.subList(i, endIndex);
// 转换并处理这一批数据
List<User> users = batch.stream()
.map(map -> JSONUtil.toBean(JSONUtil.toJsonStr(map), User.class))
.collect(Collectors.toList());
// 批量处理...
processBatch(users);
}
}
2. 缓存JSON模板
// 对于频繁使用的JSON模板,可以预定义
public class JsonTemplates {
public static final String SUCCESS_TEMPLATE = """
{
"status": "success",
"message": "%s",
"timestamp": "%s"
}
""";
public static String createSuccessResponse(String message) {
return String.format(SUCCESS_TEMPLATE, message,
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}
}
总结
JSONUtil是Java开发中处理JSON数据的利器,它不仅提供了简洁的API,还具有强大的功能和良好的性能。通过本文的介绍,我们学习了:
- JSONUtil的基础用法:对象与JSON的互转
- 集合类型的处理:List、Map与JSON的转换
- 在Spring Boot中的实际应用场景
- 高级特性:自定义配置、复杂对象处理
- 错误处理和性能优化的最佳实践
在实际开发中,合理使用JSONUtil可以大大简化JSON数据的处理逻辑,提高开发效率。记住要始终进行适当的异常处理和数据验证,确保系统的稳定性和安全性。
希望这篇文章能帮助你更好地掌握Java中的JSON数据处理技巧!