当前位置: 首页 > news >正文

JSON工具-JSONUtil

对象转JSON

JSONUtil.toJsonStr可以将任意对象(Bean、Map、集合等)直接转换为JSON字符串。 如果对象是有序的Map等对象,则转换后的JSON字符串也是有序的。

  //region 处理POST请求,将TreeMap转换为JSON字符串返回
  /**
   * 处理POST请求,将TreeMap转换为JSON字符串返回
   * 路径:/jsonToStr
   *
   * @return 返回排序后的Map转换成的JSON字符串
   */
  @PostMapping("/jsonToStr")  // 定义POST请求映射路径
  public String jsonToStr() {
    // 创建一个TreeMap,它会自动按照key的自然顺序排序
    TreeMap<Object, Object> sortedMap = new TreeMap<>();

    // 向Map中添加键值对
    // 添加key为"attributes",value为"a"的条目
    sortedMap.put("attributes", "a");
    // 添加key为"b",value为"b"的条目
    sortedMap.put("b", "b");
    // 添加key为"c",value为"c"的条目
    sortedMap.put("c", "c");

    System.out.println("JSONUtil.toJsonStr(sortedMap) = " + JSONUtil.toJsonStr(sortedMap));
    System.out.println("JSONUtil.toJsonPrettyStr(sortedMap) = " + JSONUtil.toJsonPrettyStr(sortedMap));
    // 使用JSONUtil工具类将Map转换为JSON格式的字符串并返回
    return JSONUtil.toJsonStr(sortedMap);
  }
  //endregion

运行结果: 

  //region 处理POST请求,将Map按照插入顺序转换为JSON字符串返回
  /**
   * 处理POST请求,将Map按照插入顺序转换为JSON字符串返回
   * 路径:/jsonToStr
   *
   * @return 返回按照插入顺序排列的Map转换成的JSON字符串
   */
  @PostMapping("/jsonToStrOrder")  // 定义POST请求映射路径
  public String jsonToStrOrder() throws JsonProcessingException {
    // 使用LinkedHashMap,它会按照put的顺序存储键值对
    Map<Object, Object> orderedMap = new LinkedHashMap<>();

    // 向Map中添加键值对(顺序会被保留)
    // 第1个插入
    orderedMap.put("attributes", "a");
    // 第2个插入
    orderedMap.put("b", "b");
    // 第3个插入
    orderedMap.put("c", "c");
    // 遍历输出,确认顺序
    orderedMap.forEach((k, v) -> System.out.println(k + " -> " + v));

    ObjectMapper objectMapper = new ObjectMapper();
    // 禁用排序
    objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false);
    return objectMapper.writeValueAsString(orderedMap);
  }
  //endregion

 运行结果:

JSON字符串解析

  //region 处理POST请求,返回一个固定的JSON对象并演示JSON解析操作
  /**
   * 处理POST请求,返回一个固定的JSON对象并演示JSON解析操作
   * @return 返回一个预定义的JSON对象
   */
  @PostMapping("/jsonObject")
  public JSONObject jsonObject() {
    // 定义一个多行JSON字符串(使用转义字符保持格式)
    String json = "{\n" +
      "  \"id\" : \"a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8\",\n" +
      "  \"name\" : \"User_4821\",\n" +
      "  \"age\" : 32,\n" +
      "  \"isActive\" : true,\n" +
      "  \"scores\" : [ 87, 45, 63 ],\n" +
      "  \"address\" : {\n" +
      "    \"street\" : \"Street 42\",\n" +
      "    \"city\" : \"Tokyo\",\n" +
      "    \"zipCode\" : 54321\n" +
      "  }\n" +
      "}";

    // 使用Hutool的JSONUtil将字符串解析为JSONObject
    JSONObject jsonObject = JSONUtil.parseObj(json);

    // 演示不同取值方法:
    // 1. get() 方法返回Object类型,需要手动转型
    // 返回Object类型(实际是String)
    Object id = jsonObject.get("id");
    // 直接打印Object
    System.out.println("id = " + id);

    // 2. getStr() 方法直接返回String类型(自动转换,避免转型)
    // 直接返回String
    String name = jsonObject.getStr("name");
    System.out.println("name = " + name);

    // 3. 获取数值类型(使用getBigDecimal处理整数/小数)
    // 适合所有数值类型
    BigDecimal age = jsonObject.getBigDecimal("age");
    System.out.println("age = " + age);

    // 返回完整的JSON对象
    return jsonObject;
  }
  //endregion

运行结果:

 

  //region 获取用户列表API
  /**
   * 获取用户列表API
   * 路径:/getUserList
   *
   * @param requestBody 请求体(可以是单个User对象或User列表)
   * @return 返回User对象列表
   *
   * 优化说明:
   * 1. 支持灵活接收单个对象或集合
   * 2. 使用泛型方法处理不同类型输入
   * 3. 增强类型安全和异常处理
   * 4. 规范日志记录
   */
  @PostMapping("/getUserList")
  public ResponseEntity<List<User>> getUserList(@RequestBody Object requestBody) {
    try {
      // 1. 将输入统一转换为JSON格式处理
      String jsonStr = JSONUtil.toJsonStr(requestBody);

      // 2. 智能判断输入类型(单个对象或数组)
      List<User> users;
      if (jsonStr.startsWith("[")) {
        // 数组情况:直接转换为List<User>
        users = JSONUtil.toList(JSONUtil.parseArray(jsonStr), User.class);
      } else {
        // 单个对象情况:转换为User后包装为List
        User user = JSONUtil.toBean(jsonStr, User.class);
        users = Collections.singletonList(user);
      }

      System.out.println("users = " + JSONUtil.toJsonStr(users));
      // 3. 返回统一格式的成功响应
      return ResponseEntity.ok(users);

    } catch (Exception e) {
      return ResponseEntity.badRequest().body(Collections.emptyList());
    }
  }
  //endregion
  
  class User {
    private String id;
    private String name;
    private int age;
    private boolean isActive;
    private List<Integer> scores;
    private Address address;

    public String getId() {
      return id;
    }

    public void setId(String id) {
      this.id = id;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public int getAge() {
      return age;
    }

    public void setAge(int age) {
      this.age = age;
    }

    public boolean isActive() {
      return isActive;
    }

    public void setActive(boolean active) {
      isActive = active;
    }

    public List<Integer> getScores() {
      return scores;
    }

    public void setScores(List<Integer> scores) {
      this.scores = scores;
    }

    public Address getAddress() {
      return address;
    }

    public void setAddress(Address address) {
      this.address = address;
    }
  }
  class Address {
    private String street;
    private String city;
    private int zipCode;

    public String getStreet() {
      return street;
    }

    public void setStreet(String street) {
      this.street = street;
    }

    public String getCity() {
      return city;
    }

    public void setCity(String city) {
      this.city = city;
    }

    public int getZipCode() {
      return zipCode;
    }

    public void setZipCode(int zipCode) {
      this.zipCode = zipCode;
    }
  }

运行结果:

curl --request POST \
  --url http://localhost:8080/demo/getUserList \
  --header 'Accept: */*' \
  --header 'Accept-Encoding: gzip, deflate, br' \
  --header 'Connection: keep-alive' \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: PostmanRuntime-ApipostRuntime/1.1.0' \
  --data '{
    "id": "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8",
    "name": "User_4821",
    "age": 32,
    "isActive": true,
    "scores": [
        87,
        45,
        63
    ],
    "address": {
        "street": "Street 42",
        "city": "Tokyo",
        "zipCode": 54321
    }
}'

XML字符串转换为JSON

  //region 将XML数据转换为JSON格式的API端点
  /**
   * 将XML数据转换为JSON格式的API端点
   * 路径:/xmlToJson
   *
   * @param xml 客户端提交的XML格式字符串
   * @return 包含解析结果的ResponseEntity,成功时返回name和city字段,失败时返回错误信息
   * 功能说明:
   * 1. 将输入的XML字符串转换为JSON格式
   * 2. 从XML结构中提取user节点的name和address下的city字段
   * 3. 提供完善的错误处理和日志记录
   */
  @PostMapping("/xmlToJson")
  public ResponseEntity<?> xmlToJson(@RequestBody String xml) {
    try {
      // 1. 将XML字符串转换为JSONObject对象
      // 使用Hutool工具的JSONUtil进行转换,自动处理XML标签、属性和嵌套结构
      JSONObject jsonObject = JSONUtil.parseFromXml(xml);

      // 2. 安全获取root节点
      // XML转换后的JSON对象最外层是root节点,需要先获取这个节点
      // 如果root节点不存在,说明XML格式不符合预期
      JSONObject root = jsonObject.getJSONObject("root");
      if (root == null) {
        // 返回400错误,提示缺少root节点
        return ResponseEntity.badRequest().body(Collections.singletonMap("error", "XML格式错误:缺少root节点"));
      }

      // 3. 安全获取user节点
      // 从root节点下获取user节点,这是业务数据的主要容器
      // 如果user节点不存在,说明XML缺少关键数据结构
      JSONObject user = root.getJSONObject("user");
      if (user == null) {
        // 返回400错误,提示缺少user节点
        return ResponseEntity.badRequest().body(Collections.singletonMap("error", "XML格式错误:缺少user节点"));
      }

      // 4. 获取关键字段:name和address.city
      // 4.1 直接获取user节点下的name字段
      String name = user.getStr("name");

      // 4.2 安全获取address节点及其city字段
      // 先获取address节点对象,可能为null(如果address节点不存在)
      JSONObject address = user.getJSONObject("address");
      // 使用三元表达式安全获取city字段,如果address不存在则city为null
      String city = (address != null) ? address.getStr("city") : null;

      // 5. 构建返回结果Map
      // 使用HashMap存储返回字段,保证字段顺序(如果需要有序可使用LinkedHashMap)
      Map<String, Object> result = new HashMap<>();
      // 必填字段:name
      result.put("name", name);

      // 处理可能为空的city字段
      if (city != null) {
        // 如果city存在,直接放入结果
        result.put("city", city);
      } else {
        // 如果city不存在,添加警告信息
        result.put("city_warning", "address或city节点不存在");
      }

      // 6. 记录解析日志
      // 在实际项目中建议使用日志框架(如SLF4J)替代System.out
      System.out.println("解析结果 - name: " + name + ", city: " + city);

      // 7. 返回成功响应(HTTP 200)
      // 使用ResponseEntity封装返回结果和状态码
      return ResponseEntity.ok(result);

    } catch (Exception e) {
      // 全局异常处理
      // 捕获所有可能的异常(XML解析异常、JSON处理异常等)

      // 记录错误日志(实际项目应使用log.error())
      System.err.println("XML解析异常: " + e.getMessage());

      // 返回400错误和异常信息
      // 注意:生产环境可能需要过滤敏感异常信息
      return ResponseEntity.badRequest()
        .body(Collections.singletonMap("error", "XML解析失败: " + e.getMessage()));
    }
  }
  //endregion

运行结果:

curl --request POST \
  --url http://localhost:8080/demo/xmlToJson \
  --header 'Accept: */*' \
  --header 'Accept-Encoding: gzip, deflate, br' \
  --header 'Connection: keep-alive' \
  --header 'User-Agent: PostmanRuntime-ApipostRuntime/1.1.0' \
  --data '<?xml version="1.0" encoding="UTF-8"?>
<root>
    <user id="1001">
        <name>张三</name>
        <age>28</age>
        <gender>男</gender>
        <address>
            <street>科技路123号</street>
            <city>北京</city>
            <zipcode>100000</zipcode>
        </address>
        <hobbies>
            <hobby>游泳</hobby>
            <hobby>编程</hobby>
            <hobby>阅读</hobby>
        </hobbies>
    </user>
    <product>
        <id>P1001</id>
        <name>智能手机</name>
        <price>3999.00</price>
        <specs>
            <color>黑色</color>
            <memory>128GB</memory>
        </specs>
    </product>
    <order>
        <orderNo>ORD20230001</orderNo>
        <date>2023-05-15</date>
        <items>
            <item>
                <productId>P1001</productId>
                <quantity>2</quantity>
            </item>
        </items>
    </order>
</root>'

JSON转换为XML

  //region JSON转XML的API端点

  /**
   * JSON转XML的API端点
   * 路径:/jsonToXml
   *
   * @param json 客户端提交的JSON格式字符串
   * @return 转换后的XML字符串(成功)或错误信息(失败)
   */
  @PostMapping("/jsonToXml")
  public ResponseEntity<String> jsonToXml(@RequestBody String json) {
    // 参数校验
    if (!StringUtils.hasText(json)) {
      return ResponseEntity.badRequest().body("错误:输入JSON不能为空");
    }

    try {
      // 解析JSON并转换为XML
      JSONObject jsonObject = JSONUtil.parseObj(json);
      String xmlStr = JSONUtil.toXmlStr(jsonObject);

      // 验证转换结果
      if (!StringUtils.hasText(xmlStr)) {
        return ResponseEntity.badRequest().body("错误:XML转换失败");
      }

      // 返回成功响应
      return ResponseEntity.ok()
        .header("Content-Type", "application/xml")
        .body(xmlStr);

    } catch (Exception e) {
      // 异常处理
      return ResponseEntity.badRequest()
        .body("转换失败: " + e.getMessage());
    }
  }
  //endregion

运行结果:

curl --request POST \
  --url http://localhost:8080/demo/jsonToXml \
  --header 'Accept: */*' \
  --header 'Accept-Encoding: gzip, deflate, br' \
  --header 'Connection: keep-alive' \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: PostmanRuntime-ApipostRuntime/1.1.0' \
  --data '{
  "id" : "a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8",
  "name" : "User_4821",
  "age" : 32,
  "isActive" : true,
  "scores" : [ 87, 45, 63 ],
  "address" : {
    "street" : "Street 42",
    "city" : "Tokyo",
    "zipCode" : 54321
  }
}'

相关文章:

  • 网站模板之家长沙网红打卡景点排行榜
  • 美味西式餐饮美食网站模板域名大全查询
  • 哪个网站做logo好代写文案的软件
  • wordpress 按分类显示图片无锡百度快速优化排名
  • 个人做外贸网站西安seo公司
  • 广州城市建设档案馆网站博为峰软件测试培训学费
  • 【OS】Process Management(3)
  • 蓝桥杯比赛对于时间和空间的限制
  • 进程同步和进程互斥的区别
  • 用栈实现队列
  • android audiorecord
  • PowerBI累计分析
  • Agent 开发 笔记
  • 本地项目HTTPS访问问题解决方案
  • 【后端开发】Maven
  • LeetCode热题100记录-【二分查找】
  • 单片机软件设计文档模板
  • skynet.call使用详解
  • kafka 的存储文件结构
  • fpga系列 HDL:跨时钟域同步 4-phase handshake(四相握手通信协议,请求-确认机制)浅释与代码实现
  • Boost库搜索引擎项目(版本1)
  • Nodejs回调函数
  • 使用uglifyjs对静态引入的js文件进行压缩
  • 网络安全小知识课堂(十三)
  • css专题1-----给div盒子的边框添加阴影
  • 地质科研智能革命:当大语言模型“扎根”地质现场、大语言模型本地化部署与AI智能体协同创新实践