当前位置:首页 > 后端开发 > 正文

java 怎么打印json

Java中,可通过ObjectMapper的writerWithDefaultPrettyPrinter()或JSONObject的toString(int indentFactor)方法实现 JSON的格式化打印

使用Jackson库实现格式化输出

Jackson是高性能的JSON处理器,支持自动将对象序列化为带缩进结构的字符串,核心步骤如下:

  1. 添加依赖
    若使用Maven管理项目,需在pom.xml中引入:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>最新稳定版</version>
    </dependency>
  2. 基础用法示例
    通过ObjectMapper默认启用了美观打印(缩进2空格):

    import com.fasterxml.jackson.databind.ObjectMapper;
    import java.util.HashMap;
    import java.util.Map;
    public class JacksonDemo {
        public static void main(String[] args) throws Exception {
            Map<String, Object> data = new HashMap<>();
            data.put("name", "Alice");
            data.put("age", 28);
            data.put("isStudent", false);
            ObjectMapper mapper = new ObjectMapper();
            String jsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data);
            System.out.println(jsonStr);
        }
    }

    输出结果类似:

    {
      "name" : "Alice",
      "age" : 28,
      "isStudent" : false
    }
  3. 自定义缩进规则
    可通过SerializationFeature调整细节,例如强制换行或禁用空值:

    mapper.enable(SerializationFeature.INDENT_OUTPUT); // 确保缩进生效
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 忽略未知字段
  4. 处理复杂类型
    对于嵌套对象、数组等结构,Jackson会自动递归展开,例如处理List集合时:

    List<String> hobbies = Arrays.asList("reading", "gaming");
    data.put("hobbies", hobbies); // 自动转换为JSON数组格式 ["reading","gaming"]

采用Gson库的配置方案

Google提供的Gson同样支持美化输出,关键在于构建器模式的配置:

  1. 初始化带格式设置的实例
    调用new GsonBuilder().setPrettyPrinting()激活可读性优化:

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import java.util.ArrayList;
    import java.util.List;
    public class GsonExample {
        public static void main(String[] args) {
            List<String> skills = new ArrayList<>();
            skills.add("Java");
            skills.add("Python");
            User user = new User("Bob", skills); // 假设存在User类
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            String prettyJson = gson.toJson(user);
            System.out.println(prettyJson);
        }
    }

    生成的JSON会按层级自动换行并添加制表符:

    {
      "username": "Bob",
      "skills": [
        "Java",
        "Python"
      ]
    }
  2. 排除特定字段
    如果只需展示部分属性,可以使用注解或动态过滤策略:

    // 方法一:通过@Expose注释控制可见性(需修改实体类)
    // 方法二:运行时指定包含/排除模式
    FieldNamingPolicy policy = FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES;
    gson = new GsonBuilder().setFieldNamingPolicy(policy).create();
  3. 性能对比
    相较于Jackson,Gson在简单场景下代码更简洁,但在复杂泛型解析时可能稍慢,建议根据项目规模选型。


标准API javax.json的应用

JDK自带的javax.json包无需第三方依赖,适合轻量级任务:

  1. 创建JsonObject并生成字符串
    直接操作JSON模型接口:

    import javax.json.;
    import javax.json.stream.JsonGenerator;
    public class StdLibTest {
        public static void main(String[] args) {
            JsonObject root = Json.createObjectBuilder()
                .add("id", 1001)
                .add("description", "Sample item")
                .add("tags", JsonArray.of("tag1", "tag2"))
                .build();
            StringWriter sw = new StringWriter();
            try (JsonWriter writer = Json.createWriter(sw)) {
                writer.setPrettyPrinting(); // 关键设置!
                writer.write(root);
            } catch (Exception e) { e.printStackTrace(); }
            System.out.println(sw.toString());
        }
    }

    此方式产生的结构化文本便于调试日志记录。

  2. 流式写入优化
    针对大文件传输场景,可采用事件驱动模型逐块写入,减少内存占用。


不同方案对比表

特性 Jackson Gson javax.json
依赖性 需要外部库 需要外部库 JDK内置
配置灵活性 (高度定制) (较灵活) (基础功能)
执行速度 快(基准测试领先) 中等 较慢
学习曲线 适中 简单 简单
生态整合度 Spring框架原生支持 Android友好 标准化协议兼容性好

常见问题FAQs

Q1: 为什么有时打印出来的JSON没有换行和缩进?

A: 这是由于未启用“美化打印”模式导致的,各库的解决方案分别为:

  • Jackson → 使用writerWithDefaultPrettyPrinter()
  • Gson → 构造时调用setPrettyPrinting()
  • javax.json → 调用setPrettyPrinting()方法,该功能主要用于提升人类可读性,生产环境传输通常关闭此选项以节省带宽。

Q2: 如何处理日期类型的字段以避免乱码?

A: 所有库均支持自定义序列化策略,以Jackson为例:

  1. 注册模块:mapper.registerModule(new JavaTimeModule())
  2. 或者在字段上添加注解:@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd"),这样就能正确解析LocalDate等新型日期API类型,对于旧版Java,建议转为`SimpleDateFormat
0