ai-engineering-init 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/.claude/hooks/skill-forced-eval.js +46 -62
  2. package/.claude/settings.json +10 -1
  3. package/.claude/skills/api-development/SKILL.md +179 -130
  4. package/.claude/skills/architecture-design/SKILL.md +102 -212
  5. package/.claude/skills/backend-annotations/SKILL.md +166 -220
  6. package/.claude/skills/bug-detective/SKILL.md +225 -186
  7. package/.claude/skills/code-patterns/SKILL.md +127 -244
  8. package/.claude/skills/collaborating-with-codex/SKILL.md +96 -113
  9. package/.claude/skills/crud-development/SKILL.md +226 -307
  10. package/.claude/skills/data-permission/SKILL.md +131 -202
  11. package/.claude/skills/database-ops/SKILL.md +158 -355
  12. package/.claude/skills/error-handler/SKILL.md +224 -285
  13. package/.claude/skills/file-oss-management/SKILL.md +174 -169
  14. package/.claude/skills/git-workflow/SKILL.md +123 -341
  15. package/.claude/skills/json-serialization/SKILL.md +121 -137
  16. package/.claude/skills/performance-doctor/SKILL.md +83 -89
  17. package/.claude/skills/redis-cache/SKILL.md +134 -185
  18. package/.claude/skills/scheduled-jobs/SKILL.md +187 -224
  19. package/.claude/skills/security-guard/SKILL.md +168 -276
  20. package/.claude/skills/sms-mail/SKILL.md +266 -228
  21. package/.claude/skills/social-login/SKILL.md +257 -195
  22. package/.claude/skills/tenant-management/SKILL.md +172 -188
  23. package/.claude/skills/utils-toolkit/SKILL.md +214 -222
  24. package/.claude/skills/websocket-sse/SKILL.md +251 -172
  25. package/.claude/skills/workflow-engine/SKILL.md +178 -250
  26. package/.codex/skills/api-development/SKILL.md +179 -130
  27. package/.codex/skills/architecture-design/SKILL.md +102 -212
  28. package/.codex/skills/backend-annotations/SKILL.md +166 -220
  29. package/.codex/skills/bug-detective/SKILL.md +225 -186
  30. package/.codex/skills/code-patterns/SKILL.md +127 -244
  31. package/.codex/skills/collaborating-with-codex/SKILL.md +96 -113
  32. package/.codex/skills/crud-development/SKILL.md +226 -307
  33. package/.codex/skills/data-permission/SKILL.md +131 -202
  34. package/.codex/skills/database-ops/SKILL.md +158 -355
  35. package/.codex/skills/error-handler/SKILL.md +224 -285
  36. package/.codex/skills/file-oss-management/SKILL.md +174 -169
  37. package/.codex/skills/git-workflow/SKILL.md +123 -341
  38. package/.codex/skills/json-serialization/SKILL.md +121 -137
  39. package/.codex/skills/performance-doctor/SKILL.md +83 -89
  40. package/.codex/skills/redis-cache/SKILL.md +134 -185
  41. package/.codex/skills/scheduled-jobs/SKILL.md +187 -224
  42. package/.codex/skills/security-guard/SKILL.md +168 -276
  43. package/.codex/skills/sms-mail/SKILL.md +266 -228
  44. package/.codex/skills/social-login/SKILL.md +257 -195
  45. package/.codex/skills/tenant-management/SKILL.md +172 -188
  46. package/.codex/skills/utils-toolkit/SKILL.md +214 -222
  47. package/.codex/skills/websocket-sse/SKILL.md +251 -172
  48. package/.codex/skills/workflow-engine/SKILL.md +178 -250
  49. package/.cursor/hooks/cursor-skill-eval.js +66 -6
  50. package/.cursor/skills/api-development/SKILL.md +179 -130
  51. package/.cursor/skills/architecture-design/SKILL.md +102 -212
  52. package/.cursor/skills/backend-annotations/SKILL.md +166 -220
  53. package/.cursor/skills/bug-detective/SKILL.md +225 -186
  54. package/.cursor/skills/code-patterns/SKILL.md +127 -244
  55. package/.cursor/skills/collaborating-with-codex/SKILL.md +96 -113
  56. package/.cursor/skills/crud-development/SKILL.md +226 -307
  57. package/.cursor/skills/data-permission/SKILL.md +131 -202
  58. package/.cursor/skills/database-ops/SKILL.md +158 -355
  59. package/.cursor/skills/error-handler/SKILL.md +224 -285
  60. package/.cursor/skills/file-oss-management/SKILL.md +174 -169
  61. package/.cursor/skills/git-workflow/SKILL.md +123 -341
  62. package/.cursor/skills/json-serialization/SKILL.md +121 -137
  63. package/.cursor/skills/performance-doctor/SKILL.md +83 -89
  64. package/.cursor/skills/redis-cache/SKILL.md +134 -185
  65. package/.cursor/skills/scheduled-jobs/SKILL.md +187 -224
  66. package/.cursor/skills/security-guard/SKILL.md +168 -276
  67. package/.cursor/skills/sms-mail/SKILL.md +266 -228
  68. package/.cursor/skills/social-login/SKILL.md +257 -195
  69. package/.cursor/skills/tenant-management/SKILL.md +172 -188
  70. package/.cursor/skills/utils-toolkit/SKILL.md +214 -222
  71. package/.cursor/skills/websocket-sse/SKILL.md +251 -172
  72. package/.cursor/skills/workflow-engine/SKILL.md +178 -250
  73. package/AGENTS.md +49 -540
  74. package/CLAUDE.md +73 -119
  75. package/README.md +37 -6
  76. package/bin/index.js +5 -1
  77. package/package.json +1 -1
  78. package/src/skills/api-development/SKILL.md +179 -130
  79. package/src/skills/architecture-design/SKILL.md +102 -212
  80. package/src/skills/backend-annotations/SKILL.md +166 -220
  81. package/src/skills/bug-detective/SKILL.md +225 -186
  82. package/src/skills/code-patterns/SKILL.md +127 -244
  83. package/src/skills/collaborating-with-codex/SKILL.md +96 -113
  84. package/src/skills/crud-development/SKILL.md +226 -307
  85. package/src/skills/data-permission/SKILL.md +131 -202
  86. package/src/skills/database-ops/SKILL.md +158 -355
  87. package/src/skills/error-handler/SKILL.md +224 -285
  88. package/src/skills/file-oss-management/SKILL.md +174 -169
  89. package/src/skills/git-workflow/SKILL.md +123 -341
  90. package/src/skills/json-serialization/SKILL.md +121 -137
  91. package/src/skills/performance-doctor/SKILL.md +83 -89
  92. package/src/skills/redis-cache/SKILL.md +134 -185
  93. package/src/skills/scheduled-jobs/SKILL.md +187 -224
  94. package/src/skills/security-guard/SKILL.md +168 -276
  95. package/src/skills/sms-mail/SKILL.md +266 -228
  96. package/src/skills/social-login/SKILL.md +257 -195
  97. package/src/skills/tenant-management/SKILL.md +172 -188
  98. package/src/skills/utils-toolkit/SKILL.md +214 -222
  99. package/src/skills/websocket-sse/SKILL.md +251 -172
  100. package/src/skills/workflow-engine/SKILL.md +178 -250
  101. package/.claude/skills/skill-creator/LICENSE.txt +0 -202
  102. package/.claude/skills/skill-creator/SKILL.md +0 -479
  103. package/.claude/skills/skill-creator/agents/analyzer.md +0 -274
  104. package/.claude/skills/skill-creator/agents/comparator.md +0 -202
  105. package/.claude/skills/skill-creator/agents/grader.md +0 -223
  106. package/.claude/skills/skill-creator/assets/eval_review.html +0 -146
  107. package/.claude/skills/skill-creator/eval-viewer/generate_review.py +0 -471
  108. package/.claude/skills/skill-creator/eval-viewer/viewer.html +0 -1325
  109. package/.claude/skills/skill-creator/references/schemas.md +0 -430
  110. package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
  111. package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
  112. package/.claude/skills/skill-creator/scripts/generate_report.py +0 -326
  113. package/.claude/skills/skill-creator/scripts/improve_description.py +0 -248
  114. package/.claude/skills/skill-creator/scripts/package_skill.py +0 -136
  115. package/.claude/skills/skill-creator/scripts/quick_validate.py +0 -103
  116. package/.claude/skills/skill-creator/scripts/run_eval.py +0 -310
  117. package/.claude/skills/skill-creator/scripts/run_loop.py +0 -332
  118. package/.claude/skills/skill-creator/scripts/utils.py +0 -47
@@ -11,12 +11,12 @@ description: |
11
11
  - JSON 格式验证
12
12
  - 数据类型映射与转换
13
13
 
14
- 触发词:JSON、序列化、反序列化、JsonUtils、日期格式、精度、BigDecimal、Long、类型转换、JSON验证
14
+ 触发词:JSON、序列化、反序列化、JsonUtils、日期格式、精度、BigDecimal、Long、类型转换、JSON验证、ObjectMapper、Jackson
15
15
  ---
16
16
 
17
17
  # JSON 序列化与数据转换指南
18
18
 
19
- > 模块位置:`ruoyi-common/ruoyi-common-json`
19
+ > 基于 Jackson(Spring Boot 默认 JSON 处理库)
20
20
 
21
21
  ## 快速索引
22
22
 
@@ -25,46 +25,97 @@ description: |
25
25
  | 对象转 JSON | `JsonUtils.toJsonString()` | null 返回 null |
26
26
  | JSON 转对象 | `JsonUtils.parseObject()` | 空返回 null |
27
27
  | JSON 转 List | `JsonUtils.parseArray()` | 空返回空 ArrayList |
28
- | JSON 转 Dict | `JsonUtils.parseMap()` | 非 JSON 返回 null |
29
- | JSON 数组转 Dict 列表 | `JsonUtils.parseArrayMap()` | 空返回 null |
28
+ | JSON 转 Map | `JsonUtils.parseMap()` | 非 JSON 返回 null |
30
29
  | 复杂类型转换 | `JsonUtils.parseObject(text, TypeReference)` | 支持泛型 |
31
30
  | JSON 验证 | `JsonUtils.isJson()` / `isJsonObject()` / `isJsonArray()` | |
32
- | 字段校验注解 | `@JsonPattern` | 支持 OBJECT/ARRAY/ANY |
33
31
 
34
32
  ---
35
33
 
36
- ## 核心工具类 JsonUtils
34
+ ## 核心工具类 JsonUtils(通用实现)
35
+
36
+ > 推荐封装一个项目级的 `JsonUtils`,内部使用 Jackson `ObjectMapper` 单例。
37
37
 
38
38
  ```java
39
- import org.dromara.common.json.utils.JsonUtils;
40
- ```
39
+ import com.fasterxml.jackson.databind.ObjectMapper;
40
+ import com.fasterxml.jackson.core.type.TypeReference;
41
41
 
42
- ### 序列化
42
+ public class JsonUtils {
43
43
 
44
- ```java
45
- // 对象转 JSON 字符串(null 返回 null)
46
- String json = JsonUtils.toJsonString(user);
44
+ private static final ObjectMapper MAPPER = SpringUtil.getBean(ObjectMapper.class);
45
+ // 或者:private static final ObjectMapper MAPPER = new ObjectMapper();
46
+
47
+ public static String toJsonString(Object obj) {
48
+ if (obj == null) return null;
49
+ try {
50
+ return MAPPER.writeValueAsString(obj);
51
+ } catch (Exception e) {
52
+ throw new RuntimeException("JSON序列化失败", e);
53
+ }
54
+ }
55
+
56
+ public static <T> T parseObject(String json, Class<T> clazz) {
57
+ if (json == null || json.isBlank()) return null;
58
+ try {
59
+ return MAPPER.readValue(json, clazz);
60
+ } catch (Exception e) {
61
+ throw new RuntimeException("JSON反序列化失败", e);
62
+ }
63
+ }
64
+
65
+ public static <T> T parseObject(String json, TypeReference<T> typeRef) {
66
+ if (json == null || json.isBlank()) return null;
67
+ try {
68
+ return MAPPER.readValue(json, typeRef);
69
+ } catch (Exception e) {
70
+ throw new RuntimeException("JSON反序列化失败", e);
71
+ }
72
+ }
73
+
74
+ public static <T> List<T> parseArray(String json, Class<T> clazz) {
75
+ if (json == null || json.isBlank()) return new ArrayList<>();
76
+ try {
77
+ return MAPPER.readValue(json,
78
+ MAPPER.getTypeFactory().constructCollectionType(ArrayList.class, clazz));
79
+ } catch (Exception e) {
80
+ throw new RuntimeException("JSON反序列化失败", e);
81
+ }
82
+ }
83
+
84
+ public static boolean isJson(String str) {
85
+ return isJsonObject(str) || isJsonArray(str);
86
+ }
87
+
88
+ public static boolean isJsonObject(String str) {
89
+ if (str == null || str.isBlank()) return false;
90
+ return str.trim().startsWith("{") && str.trim().endsWith("}");
91
+ }
92
+
93
+ public static boolean isJsonArray(String str) {
94
+ if (str == null || str.isBlank()) return false;
95
+ return str.trim().startsWith("[") && str.trim().endsWith("]");
96
+ }
97
+
98
+ public static ObjectMapper getObjectMapper() {
99
+ return MAPPER;
100
+ }
101
+ }
47
102
  ```
48
103
 
49
- ### 反序列化
104
+ ---
105
+
106
+ ## 序列化与反序列化
107
+
108
+ ### 基本用法
50
109
 
51
110
  ```java
52
- // JSON 转简单对象(空返回 null)
53
- User user = JsonUtils.parseObject(json, User.class);
111
+ // 对象转 JSON 字符串
112
+ String json = JsonUtils.toJsonString(user);
54
113
 
55
- // 字节数组转对象
56
- User user = JsonUtils.parseObject(bytes, User.class);
114
+ // JSON 转简单对象
115
+ User user = JsonUtils.parseObject(json, User.class);
57
116
 
58
- // JSON 数组转 List(空返回空 ArrayList)
117
+ // JSON 数组转 List
59
118
  List<User> users = JsonUtils.parseArray(json, User.class);
60
-
61
- // JSON 转 Dict(非 JSON 返回 null)
62
- Dict dict = JsonUtils.parseMap(json);
63
- String name = dict.getStr("name");
64
- int age = dict.getInt("age");
65
-
66
- // JSON 数组转 Dict 列表
67
- List<Dict> dicts = JsonUtils.parseArrayMap(json);
68
119
  ```
69
120
 
70
121
  ### 复杂泛型类型
@@ -89,67 +140,46 @@ List<User> users = JsonUtils.parseObject(json, USER_LIST_TYPE);
89
140
  ### JSON 验证
90
141
 
91
142
  ```java
92
- // 判断是否为合法 JSON(对象或数组)
93
- JsonUtils.isJson("{\"name\":\"张三\"}"); // true
94
- JsonUtils.isJson("[1,2,3]"); // true
95
- JsonUtils.isJson("not json"); // false
96
-
97
- // 判断是否为 JSON 对象
98
- JsonUtils.isJsonObject("{\"a\":1}"); // true
99
- JsonUtils.isJsonObject("[1,2,3]"); // false
100
-
101
- // 判断是否为 JSON 数组
102
- JsonUtils.isJsonArray("[1,2,3]"); // true
103
- JsonUtils.isJsonArray("{\"a\":1}"); // false
104
- ```
105
-
106
- ### 获取 ObjectMapper
143
+ JsonUtils.isJson("{\"name\":\"test\"}"); // true
144
+ JsonUtils.isJson("[1,2,3]"); // true
145
+ JsonUtils.isJson("not json"); // false
107
146
 
108
- ```java
109
- ObjectMapper mapper = JsonUtils.getObjectMapper();
110
- JsonNode node = mapper.readTree(json);
147
+ JsonUtils.isJsonObject("{\"a\":1}"); // true
148
+ JsonUtils.isJsonArray("[1,2,3]"); // true
111
149
  ```
112
150
 
113
151
  ---
114
152
 
115
- ## @JsonPattern 校验注解
153
+ ## Jackson 自动配置
116
154
 
117
- 用于 BO 类字段的 JSON 格式校验。
155
+ ### 推荐配置类
118
156
 
119
157
  ```java
120
- import org.dromara.common.json.validate.JsonPattern;
121
- import org.dromara.common.json.validate.JsonType;
122
-
123
- public class ConfigBo {
124
-
125
- // 任意 JSON 格式(对象或数组)
126
- @JsonPattern
127
- private String configValue;
128
-
129
- // 必须是 JSON 对象
130
- @JsonPattern(type = JsonType.OBJECT, message = "配置必须是 JSON 对象格式")
131
- private String objectConfig;
132
-
133
- // 必须是 JSON 数组
134
- @JsonPattern(type = JsonType.ARRAY, message = "列表必须是 JSON 数组格式")
135
- private String arrayConfig;
158
+ @Configuration
159
+ public class JacksonConfig {
160
+
161
+ @Bean
162
+ public Jackson2ObjectMapperBuilderCustomizer customizer() {
163
+ return builder -> {
164
+ // LocalDateTime 格式化
165
+ builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
166
+ builder.serializers(new LocalDateTimeSerializer(
167
+ DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
168
+ builder.deserializers(new LocalDateTimeDeserializer(
169
+ DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
170
+
171
+ // 大数字精度保护
172
+ SimpleModule module = new SimpleModule();
173
+ module.addSerializer(Long.class, new BigNumberSerializer());
174
+ module.addSerializer(Long.TYPE, new BigNumberSerializer());
175
+ module.addSerializer(BigInteger.class, new BigNumberSerializer());
176
+ module.addSerializer(BigDecimal.class, ToStringSerializer.instance);
177
+ builder.modules(module);
178
+ };
179
+ }
136
180
  }
137
181
  ```
138
182
 
139
- **JsonType 枚举**:
140
-
141
- | 值 | 说明 | 示例 |
142
- |----|------|------|
143
- | `ANY` | 对象或数组都可以(默认) | `{}` 或 `[]` |
144
- | `OBJECT` | 必须是 JSON 对象 | `{"a":1}` |
145
- | `ARRAY` | 必须是 JSON 数组 | `[1,2,3]` |
146
-
147
- ---
148
-
149
- ## Jackson 自动配置
150
-
151
- 配置类:`org.dromara.common.json.config.JacksonConfig`
152
-
153
183
  ### 大数字处理(BigNumberSerializer)
154
184
 
155
185
  **问题**:JavaScript 最大安全整数为 `2^53 - 1`(9007199254740991),超出范围会丢失精度。
@@ -157,11 +187,11 @@ public class ConfigBo {
157
187
  **解决方案**:自动将超出 JS 安全范围的数字序列化为字符串。
158
188
 
159
189
  ```java
160
- // 安全范围内 保持数字
190
+ // 安全范围内 -> 保持数字
161
191
  Long id = 123456L;
162
192
  // 序列化结果:{"id": 123456}
163
193
 
164
- // 超出安全范围 转为字符串
194
+ // 超出安全范围 -> 转为字符串
165
195
  Long id = 9007199254740992L;
166
196
  // 序列化结果:{"id": "9007199254740992"}
167
197
 
@@ -189,20 +219,6 @@ BigDecimal amount = new BigDecimal("123.45");
189
219
  LocalDateTime now = LocalDateTime.now();
190
220
  String json = JsonUtils.toJsonString(now);
191
221
  // 输出:"2026-02-06 14:30:45"
192
-
193
- LocalDateTime parsed = JsonUtils.parseObject("\"2026-02-06 14:30:45\"", LocalDateTime.class);
194
- ```
195
-
196
- ### Date 自动解析(CustomDateDeserializer)
197
-
198
- 使用 Hutool 的 `DateUtil.parse()` 自动识别多种日期格式:
199
-
200
- ```java
201
- // 支持的格式(自动识别)
202
- Date d1 = JsonUtils.parseObject("\"2026-02-06 14:30:45\"", Date.class);
203
- Date d2 = JsonUtils.parseObject("\"2026-02-06\"", Date.class);
204
- Date d3 = JsonUtils.parseObject("\"2026/02/06 14:30:45\"", Date.class);
205
- Date d4 = JsonUtils.parseObject("\"20260206143045\"", Date.class);
206
222
  ```
207
223
 
208
224
  ---
@@ -214,17 +230,17 @@ Date d4 = JsonUtils.parseObject("\"20260206143045\"", Date.class);
214
230
  ```java
215
231
  @Service
216
232
  @RequiredArgsConstructor
217
- public class ConfigServiceImpl implements IConfigService {
233
+ public class ConfigServiceImpl {
218
234
 
219
- private final ConfigMapper baseMapper;
235
+ private final ConfigMapper configMapper;
220
236
 
221
237
  /**
222
238
  * 获取配置为对象
223
239
  */
224
240
  public <T> T getConfig(String configKey, Class<T> clazz) {
225
- SysConfig config = baseMapper.selectOne(
226
- Wrappers.<SysConfig>lambdaQuery()
227
- .eq(SysConfig::getConfigKey, configKey));
241
+ Config config = configMapper.selectOne(
242
+ Wrappers.<Config>lambdaQuery()
243
+ .eq(Config::getConfigKey, configKey));
228
244
  if (config == null) {
229
245
  return null;
230
246
  }
@@ -235,10 +251,10 @@ public class ConfigServiceImpl implements IConfigService {
235
251
  * 保存配置
236
252
  */
237
253
  public void saveConfig(String configKey, Object value) {
238
- SysConfig config = new SysConfig();
254
+ Config config = new Config();
239
255
  config.setConfigKey(configKey);
240
256
  config.setConfigValue(JsonUtils.toJsonString(value));
241
- baseMapper.insert(config);
257
+ configMapper.insert(config);
242
258
  }
243
259
 
244
260
  /**
@@ -246,7 +262,7 @@ public class ConfigServiceImpl implements IConfigService {
246
262
  */
247
263
  public void importData(String jsonData) {
248
264
  if (!JsonUtils.isJsonArray(jsonData)) {
249
- throw new ServiceException("数据格式不正确,应为 JSON 数组");
265
+ throw new [你的异常类]("数据格式不正确,应为 JSON 数组");
250
266
  }
251
267
  List<DataBo> list = JsonUtils.parseArray(jsonData, DataBo.class);
252
268
  // 处理数据...
@@ -254,25 +270,6 @@ public class ConfigServiceImpl implements IConfigService {
254
270
  }
255
271
  ```
256
272
 
257
- ### BO 中使用 JSON 校验
258
-
259
- ```java
260
- @Data
261
- @AutoMapper(target = SysConfig.class, reverseConvertGenerate = false)
262
- public class SysConfigBo extends BaseEntity {
263
-
264
- @NotNull(message = "ID不能为空", groups = EditGroup.class)
265
- private Long id;
266
-
267
- @NotBlank(message = "配置键不能为空")
268
- private String configKey;
269
-
270
- @NotBlank(message = "配置值不能为空")
271
- @JsonPattern(type = JsonType.OBJECT, message = "配置值必须是有效的 JSON 对象")
272
- private String configValue;
273
- }
274
- ```
275
-
276
273
  ---
277
274
 
278
275
  ## 常见问题
@@ -280,12 +277,12 @@ public class SysConfigBo extends BaseEntity {
280
277
  ### 1. 什么时候用 parseObject vs parseArray?
281
278
 
282
279
  ```java
283
- // JSON 对象 parseObject
284
- String json = "{\"name\":\"张三\"}";
280
+ // JSON 对象 -> parseObject
281
+ String json = "{\"name\":\"test\"}";
285
282
  User user = JsonUtils.parseObject(json, User.class);
286
283
 
287
- // JSON 数组 parseArray
288
- String json = "[{\"name\":\"张三\"},{\"name\":\"李四\"}]";
284
+ // JSON 数组 -> parseArray
285
+ String json = "[{\"name\":\"test1\"},{\"name\":\"test2\"}]";
289
286
  List<User> users = JsonUtils.parseArray(json, User.class);
290
287
  ```
291
288
 
@@ -305,7 +302,6 @@ Map<String, User> map = JsonUtils.parseObject(json,
305
302
  ```java
306
303
  // toJsonString
307
304
  JsonUtils.toJsonString(null); // 返回 null
308
- JsonUtils.toJsonString(user); // 返回 JSON 字符串
309
305
 
310
306
  // parseObject
311
307
  JsonUtils.parseObject(null, User.class); // 返回 null
@@ -316,18 +312,6 @@ JsonUtils.parseArray(null, User.class); // 返回空 ArrayList
316
312
  JsonUtils.parseArray("", User.class); // 返回空 ArrayList
317
313
  ```
318
314
 
319
- ### 4. 如何在解析前验证 JSON?
320
-
321
- ```java
322
- public void processData(String data) {
323
- // 先验证再解析
324
- if (!JsonUtils.isJsonArray(data)) {
325
- throw new ServiceException("数据格式不正确");
326
- }
327
- List<User> users = JsonUtils.parseArray(data, User.class);
328
- }
329
- ```
330
-
331
315
  ---
332
316
 
333
317
  ## 禁止事项
@@ -337,7 +321,7 @@ public void processData(String data) {
337
321
  ObjectMapper mapper = new ObjectMapper();
338
322
  String json = mapper.writeValueAsString(user);
339
323
 
340
- // ✅ 正确:使用 JsonUtils
324
+ // ✅ 正确:使用项目统一的 JsonUtils
341
325
  String json = JsonUtils.toJsonString(user);
342
326
 
343
327
  // ❌ 禁止:不验证直接解析(可能报错)