实现一个JSON工具类自动处理JSON转String
文章目录
- 核心功能说明
- 输出结果
- 注意事项
以下是一个自定义的JSON工具类
JsonUtils,实现了对象到JSON字符串的转换,并能自动处理常见类型的格式转换(包括基本类型、字符串、日期、集合、数组、枚举、自定义对象等):
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Collection;
import java.lang.reflect.Array;/*** 自定义JSON工具类,实现对象到JSON字符串的转换*/
public class JsonUtils {// 日期格式化器(线程安全处理:局部变量)private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";/*** 将对象转换为JSON字符串* @param obj 待转换的对象* @return JSON格式字符串*/public static String toJsonString(Object obj) {if (obj == null) {return "null";}// 处理基本类型及其包装类if (obj instanceof Number || obj instanceof Boolean) {return obj.toString();}// 处理字符串if (obj instanceof String) {return escapeString((String) obj);}// 处理日期类型if (obj instanceof Date) {return formatDate((Date) obj);}// 处理枚举类型if (obj instanceof Enum) {return escapeString(((Enum<?>) obj).name());}// 处理数组if (obj.getClass().isArray()) {return handleArray(obj);}// 处理集合(List/Set等)if (obj instanceof Collection<?>) {return handleCollection((Collection<?>) obj);}// 处理Mapif (obj instanceof Map<?, ?>) {return handleMap((Map<?, ?>) obj);}// 处理自定义对象(通过反射获取字段)return handleObject(obj);}/*** 处理字符串转义(符合JSON规范)* 转义双引号、反斜杠、控制字符等*/private static String escapeString(String s) {if (s == null) {return "null";}StringBuilder sb = new StringBuilder();sb.append("\""); // 字符串起始引号for (char c : s.toCharArray()) {switch (c) {case '"':sb.append("\\\"");break;case '\\':sb.append("\\\\");break;case '\b':sb.append("\\b");break;case '\f':sb.append("\\f");break;case '\n':sb.append("\\n");break;case '\r':sb.append("\\r");break;case '\t':sb.append("\\t");break;default:// 非ASCII字符转义为Unicodeif (c < 32 || c > 126) {sb.append(String.format("\\u%04x", (int) c));} else {sb.append(c);}}}sb.append("\""); // 字符串结束引号return sb.toString();}/*** 格式化日期为指定字符串*/private static String formatDate(Date date) {SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);return escapeString(sdf.format(date));}/*** 处理数组类型*/private static String handleArray(Object array) {StringBuilder sb = new StringBuilder("[");int length = Array.getLength(array);for (int i = 0; i < length; i++) {Object element = Array.get(array, i);sb.append(toJsonString(element));if (i != length - 1) {sb.append(", "); // 最后一个元素后不加逗号}}sb.append("]");return sb.toString();}/*** 处理集合类型(List/Set等)*/private static String handleCollection(Collection<?> collection) {StringBuilder sb = new StringBuilder("[");int index = 0;for (Object element : collection) {sb.append(toJsonString(element));if (index != collection.size() - 1) {sb.append(", ");}index++;}sb.append("]");return sb.toString();}/*** 处理Map类型*/private static String handleMap(Map<?, ?> map) {StringBuilder sb = new StringBuilder("{");int index = 0;for (Map.Entry<?, ?> entry : map.entrySet()) {Object key = entry.getKey();Object value = entry.getValue();// Map的key转换为JSON字符串键(加引号)sb.append(escapeString(key.toString()));sb.append(": ");sb.append(toJsonString(value));if (index != map.size() - 1) {sb.append(", ");}index++;}sb.append("}");return sb.toString();}/*** 处理自定义对象(通过反射获取字段)*/private static String handleObject(Object obj) {try {StringBuilder sb = new StringBuilder("{");Class<?> clazz = obj.getClass();List<Field> allFields = new ArrayList<>();// 获取所有字段(包括父类,直到Object)while (clazz != null && clazz != Object.class) {allFields.addAll(Arrays.asList(clazz.getDeclaredFields()));clazz = clazz.getSuperclass();}// 过滤掉静态字段和transient字段List<Field> fieldsToProcess = new ArrayList<>();for (Field field : allFields) {int modifiers = field.getModifiers();if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) {fieldsToProcess.add(field);}}// 拼接字段键值对int index = 0;for (Field field : fieldsToProcess) {field.setAccessible(true); // 访问私有字段String fieldName = field.getName();Object fieldValue = field.get(obj);sb.append(escapeString(fieldName)); // 字段名加引号sb.append(": ");sb.append(toJsonString(fieldValue)); // 递归处理字段值if (index != fieldsToProcess.size() - 1) {sb.append(", ");}index++;}sb.append("}");return sb.toString();} catch (IllegalAccessException e) {throw new RuntimeException("转换对象为JSON失败", e);}}
}
核心功能说明
-
支持的类型:
- 基本类型及其包装类(int、Integer、boolean、Double等)
- 字符串(自动转义特殊字符,如双引号、换行符)
- 日期(Date):默认格式化为
yyyy-MM-dd HH:mm:ss - 枚举:使用枚举的
name()作为值 - 数组(包括基本类型数组和对象数组)
- 集合(List、Set等Collection接口实现类)
- Map(键值对转换为JSON对象)
- 自定义对象(通过反射获取字段,支持父类字段,排除静态和transient字段)
-
使用示例:
import java.util.*;
import java.text.ParseException;public class JsonTest {// 自定义测试类static class User {private String name;private int age;private boolean isStudent;private Date birthday;private List<String> hobbies;private int[] scores;private Map<String, Object> info;private Gender gender;// 构造器public User(String name, int age, boolean isStudent, Date birthday,List<String> hobbies, int[] scores, Map<String, Object> info, Gender gender) {this.name = name;this.age = age;this.isStudent = isStudent;this.birthday = birthday;this.hobbies = hobbies;this.scores = scores;this.info = info;this.gender = gender;}}// 枚举测试enum Gender {MALE, FEMALE}public static void main(String[] args) throws ParseException {// 构建测试数据Date birthday = new SimpleDateFormat("yyyy-MM-dd").parse("2000-01-01");List<String> hobbies = Arrays.asList("篮球", "编程", "阅读");int[] scores = {90, 85, 95};Map<String, Object> info = new HashMap<>();info.put("height", 180);info.put("weight", 70.5);info.put("address", "北京市");User user = new User("张三", 23, true, birthday, hobbies, scores, info, Gender.MALE);// 转换为JSON字符串String json = JsonUtils.toJsonString(user);System.out.println(json);}
}
输出结果
{"name": "张三","age": 23,"isStudent": true,"birthday": "2000-01-01 00:00:00","hobbies": ["篮球", "编程", "阅读"],"scores": [90, 85, 95],"info": {"height": 180, "weight": 70.5, "address": "北京市"},"gender": "MALE"
}
注意事项
- 该工具类为简化实现,未处理循环引用(如对象A包含对象B,对象B又包含对象A会导致递归栈溢出)。
- 日期格式可通过修改
DATE_FORMAT常量自定义。 - 对于特殊类型(如BigDecimal、LocalDateTime等),可通过添加对应类型的处理逻辑扩展。
- 反射处理字段时会访问私有字段,若有特殊权限控制需求需额外处理。
