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
  }
}'

### Hutool JSONArray 类 使用方法 #### 创建 JSONArray 对象 在 Hutool 库中,`JSONArray` 是用于表示 JSON 数组的对象。可以通过 `JSONUtil.parseArray()` 方法将字符串或列表转换为 `JSONArray`。 ```java import cn.hutool.json.JSONArray; import cn.hutool.json.JSONUtil; public class Example { public static void main(String[] args) { // 将字符串转为 JSONArray String jsonString = "[\"apple\", \"banana\", \"orange\"]"; JSONArray jsonArrayFromString = JSONUtil.parseArray(jsonString); System.out.println("From string: " + jsonArrayFromString); // 将 List 转为 JSONArray java.util.List<String> list = java.util.Arrays.asList("red", "green", "blue"); JSONArray jsonArrayFromList = JSONUtil.parseArray(list); System.out.println("From list: " + jsonArrayFromList); } } ``` #### 添加元素至 JSONArray 可以向已有的 `JSONArray` 中添加新的元素,支持多种数据类型的添加。 ```java jsonArrayFromList.add("yellow"); // 添加单个元素 System.out.println("After adding element: " + jsonArrayFromList); // 批量添加多个元素 jsonArrayFromList.addAll(java.util.Arrays.asList("black", "white")); System.out.println("After batch addition: " + jsonArrayFromList); ``` #### 获取 JSONArray 中的元素 访问 `JSONArray` 内部的具体项可通过索引位置获取指定的数据条目。 ```java Object firstElement = jsonArrayFromList.get(0); System.out.println("First Element is : " + firstElement); // 如果知道具体类型也可以直接强转 String secondElementAsString = jsonArrayFromList.getString(1); System.out.println("Second Element as String is : " + secondElementAsString); ``` #### 遍历 JSONArray 并读取值 当需要逐一遍历整个数组时,可利用增强型for循环轻松完成此操作。 ```java for (int i = 0; i < jsonArrayFromList.size(); ++i){ Object item = jsonArrayFromList.get(i); System.out.println("Item at index "+i+" is:"+item); } // 或者更简洁的方式使用迭代器模式 for(Object obj : jsonArrayFromList.toArray()){ System.out.println(obj); } ``` #### 将 JSONArray 转换为其他结构 有时可能希望把 `JSONArray` 变回普通的 Java 列表形式以便进一步处理。 ```java java.util.List<Object> convertedToList = jsonArrayFromList.toList(); System.out.println("Converted to List: " + convertedToList); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值