diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/util/ServletUtils.java b/continew-starter-core/src/main/java/top/continew/starter/core/util/ServletUtils.java index 94983646..0d8dcdd0 100644 --- a/continew-starter-core/src/main/java/top/continew/starter/core/util/ServletUtils.java +++ b/continew-starter-core/src/main/java/top/continew/starter/core/util/ServletUtils.java @@ -346,8 +346,8 @@ public class ServletUtils extends JakartaServletUtil { * @since 2.13.1 * @see #write(HttpServletResponse, String, String) */ - public static void writeJSON(HttpServletResponse response, Object data) { - write(response, JSONUtil.toJsonStr(data), MediaType.APPLICATION_JSON_VALUE); + public static void writeJSON(HttpServletResponse response, String data) { + write(response, data, MediaType.APPLICATION_JSON_VALUE); } /** diff --git a/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/exception/JSONException.java b/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/exception/JSONException.java new file mode 100644 index 00000000..9445eb3b --- /dev/null +++ b/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/exception/JSONException.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.starter.json.jackson.exception; + +import top.continew.starter.core.exception.BaseException; + +import java.io.Serial; + +/** + * JSON 异常 + * + * @author Charles7c + * @since 2.13.2 + */ +public class JSONException extends BaseException { + + @Serial + private static final long serialVersionUID = 1L; + + public JSONException() { + } + + public JSONException(String message) { + super(message); + } + + public JSONException(Throwable cause) { + super(cause); + } + + public JSONException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/util/JSONBuilder.java b/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/util/JSONBuilder.java index 9cab7b0d..881b8aac 100644 --- a/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/util/JSONBuilder.java +++ b/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/util/JSONBuilder.java @@ -27,7 +27,9 @@ import java.util.Map; import java.util.Objects; /** - * json 构建工具 + * JSON 构建工具 + * + * @see ObjectMapper * * @author echo * @since 2.11.0 diff --git a/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/util/JSONUtils.java b/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/util/JSONUtils.java index c11ca319..bd8e1237 100644 --- a/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/util/JSONUtils.java +++ b/continew-starter-json/continew-starter-json-jackson/src/main/java/top/continew/starter/json/jackson/util/JSONUtils.java @@ -19,33 +19,33 @@ package top.continew.starter.json.jackson.util; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.extra.spring.SpringUtil; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import top.continew.starter.json.jackson.exception.JSONException; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.Map; /** - * json 工具 + * JSON 工具类 + * + * @see ObjectMapper + * @see cn.hutool.json.JSONUtil * * @author echo + * @author Charles7c * @since 2.11.0 */ public class JSONUtils { + private static final ObjectMapper OBJECT_MAPPER = SpringUtil.getBean(ObjectMapper.class); + private JSONUtils() { } /** - * Jackson 对象映射器,用于 JSON 解析与序列化。 - */ - private static final ObjectMapper OBJECT_MAPPER = SpringUtil.getBean(ObjectMapper.class); - - /** - * 获取 Jackson 对象映射器。 + * 获取 Jackson 对象映射器 * * @return {@link ObjectMapper} Jackson 对象映射器 */ @@ -54,183 +54,136 @@ public class JSONUtils { } /** - * 对象转为 json 字符串 + * 转换对象为JsonNode
* - * @param object 对象 - * @return {@link String } + * @param obj 对象 + * @return JsonNode */ - public static String toJsonStr(Object object) { - if (object == null) { + public static JsonNode parseObj(Object obj) { + if (obj == null) { return null; } - try { - return OBJECT_MAPPER.writeValueAsString(object); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + return OBJECT_MAPPER.valueToTree(obj); } /** - * 将对象转换为 JsonNode。 + * 转换为JSON字符串 * - * @param obj 需要转换的对象 - * @return 转换后的 {@link JsonNode},如果 obj 为空,则返回 null + * @param obj 被转为JSON的对象 + * @return JSON字符串 */ - public static JsonNode toJson(Object obj) { + public static String toJsonStr(Object obj) { if (obj == null) { return null; } try { - return OBJECT_MAPPER.valueToTree(obj); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException(e); - } - } - - /** - * 将 List 转换为 JsonNode。 - * - * @param list 输入的 List - * @return 转换后的 {@link JsonNode} - */ - public static JsonNode listToJson(List list) { - return toJson(list); - } - - /** - * 将 Map 转换为 JsonNode。 - * - * @param map 输入的 Map - * @return 转换后的 {@link JsonNode} - */ - public static JsonNode mapToJson(Map map) { - return toJson(map); - } - - /** - * 将 JsonNode 转换为 List,用于环境变量格式解析。 - * - * @param jsonNode 需要转换的 JsonNode - * @return 转换后的 List - */ - public static List jsonToEnvList(JsonNode jsonNode) { - if (jsonNode == null || jsonNode.isNull()) { - return new ArrayList<>(); - } - List envList = new ArrayList<>(); - jsonNode.fields().forEachRemaining(field -> { - String key = field.getKey(); - JsonNode valueNode = field.getValue(); - String value = valueNode.isValueNode() ? valueNode.asText() : valueNode.toString(); - envList.add(key + "=" + value); - }); - return envList; - } - - /** - * 将 JsonNode 转换为 List。 - * - * @param jsonNode 需要转换的 JsonNode - * @return 转换后的 List - */ - public static List jsonToStringList(JsonNode jsonNode) { - if (jsonNode == null || jsonNode.isNull()) { - return new ArrayList<>(); - } - try { - return OBJECT_MAPPER.convertValue(jsonNode, new TypeReference<>() { - }); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException(e); - } - } - - /** - * 将 JsonNode 转换为指定类型的 Java 对象。 - * - * @param jsonNode JSON 数据 - * @param clazz 目标 Java 类 - * @return 解析后的 Java 对象 - */ - public static T fromJson(JsonNode jsonNode, Class clazz) { - try { - return OBJECT_MAPPER.treeToValue(jsonNode, clazz); + return OBJECT_MAPPER.writeValueAsString(obj); } catch (JsonProcessingException e) { - throw new RuntimeException(e); + throw new JSONException(e); } } /** - * 解析 JSON 字符串为 Java 对象。 + * JSON字符串转为实体类对象,转换异常将被抛出 * - * @param str JSON 字符串 - * @param clazz 目标 Java 类 - * @return 解析后的 Java 对象 + * @param Bean类型 + * @param jsonString JSON字符串 + * @param beanClass 实体类对象 + * @return 实体类对象 */ - public static T parseObject(String str, Class clazz) { - if (CharSequenceUtil.isEmpty(str)) { + public static T toBean(String jsonString, Class beanClass) { + if (CharSequenceUtil.isBlank(jsonString)) { return null; } try { - return OBJECT_MAPPER.readValue(str, clazz); + return OBJECT_MAPPER.readValue(jsonString, beanClass); } catch (IOException e) { - throw new RuntimeException(e); + throw new JSONException(e); } } /** - * 字符串 解析为 list + * 将JSON字符串转换为Bean的List,默认为ArrayList * - * @param str 字符串 - * @param clazz 目标 Java 类 - * @return 解析后的 List + * @param jsonStr 需要转换的JSON字符串 + * @param elementType 列表元素类型 + * @return 转换后的 List + * @since 2.13.2 */ - public static List parseArray(String str, Class clazz) { - if (CharSequenceUtil.isEmpty(str)) { - return new ArrayList<>(); + public static List toList(String jsonStr, Class elementType) { + if (jsonStr == null || jsonStr.trim().isEmpty()) { + return new ArrayList<>(0); } try { - return OBJECT_MAPPER.readValue(str, OBJECT_MAPPER.getTypeFactory() - .constructCollectionType(List.class, clazz)); + return OBJECT_MAPPER.readValue(jsonStr, OBJECT_MAPPER.getTypeFactory() + .constructCollectionType(List.class, elementType)); } catch (IOException e) { - throw new RuntimeException(e); + throw new JSONException("Failed to parse JSON string to list", e); } } /** - * 判断字符串是否为 JSON 格式。 + * 将JSONArray转换为Bean的List,默认为ArrayList + * + * @param jsonNode 需要转换的 JsonNode + * @param elementType 列表元素类型 + * @return 转换后的 List + * @since 2.13.2 + */ + public static List toList(JsonNode jsonNode, Class elementType) { + if (jsonNode == null || jsonNode.isNull()) { + return new ArrayList<>(0); + } + try { + return OBJECT_MAPPER.convertValue(jsonNode, OBJECT_MAPPER.getTypeFactory() + .constructCollectionType(List.class, elementType)); + } catch (IllegalArgumentException e) { + throw new JSONException("Failed to convert JSON to list", e); + } + } + + /** + * 是否为JSON类型字符串,首尾都为大括号或中括号判定为JSON字符串 * * @param str 字符串 - * @return 是否为 JSON 格式 + * @return 是否为JSON类型字符串 + * @since 2.13.2 + * @see cn.hutool.json.JSONUtil#isTypeJSON(String) + * @author Looly(Hutool) */ public static boolean isTypeJSON(String str) { - if (CharSequenceUtil.isEmpty(str)) { - return false; - } - try { - OBJECT_MAPPER.readTree(str); - return true; - } catch (IOException e) { - return false; - } + return isTypeJSONObject(str) || isTypeJSONArray(str); } /** - * 将 JSON 字符串转换为指定类型的 Java 对象。 + * 是否为JSONObject类型字符串,首尾都为大括号判定为JSONObject字符串 * - * @param str 字符串 - * @param clazz 目标对象的 Class 类型 - * @return 解析后的 Java 对象 + * @param str 字符串 + * @return 是否为JSON字符串 + * @since 2.13.2 + * @see cn.hutool.json.JSONUtil#isTypeJSONObject(String) + * @author Looly(Hutool) */ - public static T toBean(String str, Class clazz) { - if (CharSequenceUtil.isEmpty(str)) { - return null; - } - try { - return OBJECT_MAPPER.readValue(str, clazz); - } catch (IOException e) { - throw new RuntimeException(e); + public static boolean isTypeJSONObject(String str) { + if (CharSequenceUtil.isBlank(str)) { + return false; } + return CharSequenceUtil.isWrap(CharSequenceUtil.trim(str), '{', '}'); } + /** + * 是否为JSONArray类型的字符串,首尾都为中括号判定为JSONArray字符串 + * + * @param str 字符串 + * @return 是否为JSONArray类型字符串 + * @since 2.13.2 + * @see cn.hutool.json.JSONUtil#isTypeJSONArray(String) + * @author Looly(Hutool) + */ + public static boolean isTypeJSONArray(String str) { + if (CharSequenceUtil.isBlank(str)) { + return false; + } + return CharSequenceUtil.isWrap(CharSequenceUtil.trim(str), '[', ']'); + } }