超级实用,高效处理复杂 JSON 数据

在现代 Java 开发中,我们经常需要处理和解析 JSON 数据,尤其是在与外部 API 交互时,JSON 格式几乎是唯一的标准数据格式。对于复杂的 JSON 数据,我们通常需要一个高效且灵活的工具来解析并提取特定的信息。今天,我们将深入探讨两个非常强大的工具:GsonOGNL,并展示它们如何结合使用,帮助我们高效地处理 JSON 数据。


什么是 Gson?

Gson 是 Google 提供的一个 Java 库,用于将 Java 对象转换为 JSON 格式,或者将 JSON 数据解析为 Java 对象。Gson 库非常轻量级,简单易用,并且具备非常强的灵活性。它自动处理了很多细节,比如类型转换、嵌套对象的处理等,使得开发者不需要手动编写复杂的解析代码。

Gson 的优势:

  • 高效性:Gson 提供快速的序列化(将 Java 对象转换为 JSON)和反序列化(将 JSON 转换为 Java 对象)功能。

  • 灵活性:支持多种类型转换,包括复杂的嵌套对象、泛型等。

  • 简洁性:API 使用简单,开发者只需少量代码即可完成 JSON 处理。

通过 Gson,我们可以轻松地将一个复杂的 JSON 字符串转换成 Java 对象,同时在这些对象中提取出我们所需的数据。


什么是 OGNL?

OGNL(Object-Graph Navigation Language) 是一种表达式语言,它允许我们通过表达式来访问 Java 对象的内部数据。OGNL 使得我们可以在不事先知道对象结构的情况下,灵活地访问和操作 Java 对象。它在一些框架中得到了广泛使用,比如 SpringStruts,并且对于动态查询和操作对象图非常有用。

OGNL 的优势:

  • 动态性:OGNL 可以在运行时动态地查询 Java 对象的属性,而不需要显式的代码编写。

  • 灵活性:OGNL 支持深层次的嵌套查询,可以处理复杂的对象结构,适用于需要快速访问复杂数据的场景。

  • 简洁性:OGNL 的表达式非常简洁,可以通过类似路径表达式的方式快速访问对象字段。

OGNL 在许多应用场景中都非常有用,尤其是在需要访问对象内部属性时,可以通过表达式快速完成。


Gson 和 OGNL 的结合:高效处理复杂 JSON 数据

在实际开发中,GsonOGNL 的结合使用可以让我们在处理复杂的 JSON 数据时既高效又灵活。Gson 用于将 JSON 字符串解析成 Java 对象,而 OGNL 则使得我们能够在这些对象中动态地查询或修改特定的数据字段。二者结合,能够充分发挥它们各自的优势,使得 JSON 数据的解析和访问更加便捷。

pom:
        <dependency>
            <groupId>ognl</groupId>
            <artifactId>ognl</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
package com.kjwl.sdt.convert.utils;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import ognl.Ognl;
import ognl.OgnlContext;

import java.util.Map;

public class JsonUtils {
    /**
     * 将指定JSON转为Map对象,Key固定为String,对应JSONkey
     * Value分情况:
     * 1. Value是字符串,自动转为字符串,例如:{"a":"b"}
     * 2. Value是其他JSON对象,自动转为Map,例如:{"a":{"b":"2"}}}
     * 3. Value是数组,自动转为List<Map>,例如:{"a":[{"b":"2"},{"c":"3"}]}
     * @param json 输入的JSON对象
     * @return 动态的Map集合
     */
    public static Map<String,Object> transferToMap(String json) {
        Gson gson = new Gson();
        Map<String, Object> map = gson.fromJson(json,
                new TypeToken<Map<String, Object>>() {
                }.getType());
        return map;
    }

    /**
     * 简化方法
     * @param json 原始的JSON数据
     * @param path OGNL规则表达式
     * @param clazz Value对应的目标类
     * @return clazz对应数据
     */
    public static <T> T getValue(String json, String path, Class<T> clazz) {
        try {
            Map map = transferToMap(json);
            OgnlContext context = new OgnlContext();
            context.setRoot(map);
            T value = (T) Ognl.getValue(path, context, context.getRoot());
            return value;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T getValueFromMap(Map map, String path, Class<T> clazz) {
        try {
            OgnlContext context = new OgnlContext();
            context.setRoot(map);
            T value = (T) Ognl.getValue(path, context, context.getRoot());
            return value;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
package com.kjwl.sdt.convert.test;

import com.kjwl.sdt.convert.utils.JsonUtils;
import org.junit.Test;
import java.util.List;
import java.util.Map;

public class JsonCase {
    /**
     * {
     *     "a": {
     *         "b": {
     *             "c": {
     *                 "d": {
     *                     "e": "nothing"
     *                 }
     *             }
     *         }
     *     }
     * }
     */
    /**
     * 超多层级JSON嵌套的快速提取
     */
    @Test
    public void case0(){
        String text = "{\n" +
                "    \"a\": {\n" +
                "        \"b\": {\n" +
                "            \"c\": {\n" +
                "                \"d\": {\n" +
                "                    \"e\": \"nothing\"\n" +
                "                }\n" +
                "            }\n" +
                "        }\n" +
                "    }\n" +
                "}";
        Map<String, Object> jsonMap = JsonUtils.transferToMap(json);

        String e = JsonUtils.getValue(text, "a.b.c.d.e", String.class);
        System.out.println(e);
    }

    /**
     * {
     * "showapi_res_error": "",
     * "showapi_res_id": "628cc9850de3769f06edbb49",
     * "showapi_res_code": 0,
     * "showapi_fee_num": 1,
     * "showapi_res_body": {"ret_code":0,"area":"南安","areaid":"101230506","areaCode":"350583","hourList":[{"weather_code":"07","time":"202205242000","area":"南安","wind_direction":"东南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"20"},{"weather_code":"07","time":"202205242100","area":"南安","wind_direction":"东风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"20"},{"weather_code":"07","time":"202205242200","area":"南安","wind_direction":"东风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"20"},{"weather_code":"07","time":"202205242300","area":"南安","wind_direction":"东风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"20"},{"weather_code":"07","time":"202205250000","area":"南安","wind_direction":"南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"21"},{"weather_code":"07","time":"202205250100","area":"南安","wind_direction":"西风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"21"},{"weather_code":"07","time":"202205250200","area":"南安","wind_direction":"西北风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"21"},{"weather_code":"02","time":"202205250300","area":"南安","wind_direction":"西北风","wind_power":"0-3级 微风 <5.4m/s","weather":"阴","areaid":"101230506","temperature":"21"},{"weather_code":"02","time":"202205250400","area":"南安","wind_direction":"西北风","wind_power":"0-3级 微风 <5.4m/s","weather":"阴","areaid":"101230506","temperature":"21"},{"weather_code":"02","time":"202205250500","area":"南安","wind_direction":"西风","wind_power":"0-3级 微风 <5.4m/s","weather":"阴","areaid":"101230506","temperature":"21"},{"weather_code":"07","time":"202205250600","area":"南安","wind_direction":"西北风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"21"},{"weather_code":"07","time":"202205250700","area":"南安","wind_direction":"西北风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"21"},{"weather_code":"07","time":"202205250800","area":"南安","wind_direction":"西北风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"21"},{"weather_code":"07","time":"202205250900","area":"南安","wind_direction":"西南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"22"},{"weather_code":"07","time":"202205251000","area":"南安","wind_direction":"南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"23"},{"weather_code":"07","time":"202205251100","area":"南安","wind_direction":"东风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"24"},{"weather_code":"07","time":"202205251200","area":"南安","wind_direction":"东风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"24"},{"weather_code":"07","time":"202205251300","area":"南安","wind_direction":"东风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"25"},{"weather_code":"07","time":"202205251400","area":"南安","wind_direction":"东南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"25"},{"weather_code":"07","time":"202205251500","area":"南安","wind_direction":"东南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"25"},{"weather_code":"07","time":"202205251600","area":"南安","wind_direction":"东南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"24"},{"weather_code":"07","time":"202205251700","area":"南安","wind_direction":"东南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"23"},{"weather_code":"07","time":"202205251800","area":"南安","wind_direction":"东南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"23"},{"weather_code":"07","time":"202205251900","area":"南安","wind_direction":"东南风","wind_power":"0-3级 微风 <5.4m/s","weather":"小雨","areaid":"101230506","temperature":"23"}]}
     * }
     */
    private String json = "{\n" +
            "\"showapi_res_error\": \"\",\n" +
            "\"showapi_res_id\": \"628cc9850de3769f06edbb49\",\n" +
            "\"showapi_res_code\": 0,\n" +
            "\"showapi_fee_num\": 1,\n" +
            "\"showapi_res_body\": {\"ret_code\":0,\"area\":\"南安\",\"areaid\":\"101230506\",\"areaCode\":\"350583\",\"hourList\":[{\"weather_code\":\"07\",\"time\":\"202205242000\",\"area\":\"南安\",\"wind_direction\":\"东南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"20\"},{\"weather_code\":\"07\",\"time\":\"202205242100\",\"area\":\"南安\",\"wind_direction\":\"东风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"20\"},{\"weather_code\":\"07\",\"time\":\"202205242200\",\"area\":\"南安\",\"wind_direction\":\"东风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"20\"},{\"weather_code\":\"07\",\"time\":\"202205242300\",\"area\":\"南安\",\"wind_direction\":\"东风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"20\"},{\"weather_code\":\"07\",\"time\":\"202205250000\",\"area\":\"南安\",\"wind_direction\":\"南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"07\",\"time\":\"202205250100\",\"area\":\"南安\",\"wind_direction\":\"西风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"07\",\"time\":\"202205250200\",\"area\":\"南安\",\"wind_direction\":\"西北风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"02\",\"time\":\"202205250300\",\"area\":\"南安\",\"wind_direction\":\"西北风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"阴\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"02\",\"time\":\"202205250400\",\"area\":\"南安\",\"wind_direction\":\"西北风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"阴\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"02\",\"time\":\"202205250500\",\"area\":\"南安\",\"wind_direction\":\"西风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"阴\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"07\",\"time\":\"202205250600\",\"area\":\"南安\",\"wind_direction\":\"西北风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"07\",\"time\":\"202205250700\",\"area\":\"南安\",\"wind_direction\":\"西北风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"07\",\"time\":\"202205250800\",\"area\":\"南安\",\"wind_direction\":\"西北风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"21\"},{\"weather_code\":\"07\",\"time\":\"202205250900\",\"area\":\"南安\",\"wind_direction\":\"西南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"22\"},{\"weather_code\":\"07\",\"time\":\"202205251000\",\"area\":\"南安\",\"wind_direction\":\"南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"23\"},{\"weather_code\":\"07\",\"time\":\"202205251100\",\"area\":\"南安\",\"wind_direction\":\"东风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"24\"},{\"weather_code\":\"07\",\"time\":\"202205251200\",\"area\":\"南安\",\"wind_direction\":\"东风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"24\"},{\"weather_code\":\"07\",\"time\":\"202205251300\",\"area\":\"南安\",\"wind_direction\":\"东风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"25\"},{\"weather_code\":\"07\",\"time\":\"202205251400\",\"area\":\"南安\",\"wind_direction\":\"东南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"25\"},{\"weather_code\":\"07\",\"time\":\"202205251500\",\"area\":\"南安\",\"wind_direction\":\"东南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"25\"},{\"weather_code\":\"07\",\"time\":\"202205251600\",\"area\":\"南安\",\"wind_direction\":\"东南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"24\"},{\"weather_code\":\"07\",\"time\":\"202205251700\",\"area\":\"南安\",\"wind_direction\":\"东南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"23\"},{\"weather_code\":\"07\",\"time\":\"202205251800\",\"area\":\"南安\",\"wind_direction\":\"东南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"23\"},{\"weather_code\":\"07\",\"time\":\"202205251900\",\"area\":\"南安\",\"wind_direction\":\"东南风\",\"wind_power\":\"0-3级 微风 <5.4m/s\",\"weather\":\"小雨\",\"areaid\":\"101230506\",\"temperature\":\"23\"}]}\n" +
            "}";

    //将JSON转为标准Map结构
    @Test
    public void case1(){
        Map<String, Object> jsonMap = JsonUtils.transferToMap(json);
        System.out.println(jsonMap);
    }
    /**
     * OGNL直接提取数据,Value为子JSON对象的情况
     */
    @Test
    public void case2(){
        Map<String, Object> jsonMap = JsonUtils.transferToMap(json);
        Map resBody = JsonUtils.getValue(json, "showapi_res_body", Map.class);
        System.out.println(resBody);
    }

    /**
     * OGNL直接提取数据,Value为标准字符串的情况
     */
    @Test
    public void case3(){
        Map<String, Object> jsonMap = JsonUtils.transferToMap(json);
        String value = JsonUtils.getValue(json, "showapi_res_body.area", String.class);
        System.out.println(value);
    }

    /**
     * OGNL直接提取数据,Value为标准字符串的情况,Value为数组的情况
     */
    @Test
    public void case4(){
        Map<String, Object> jsonMap = JsonUtils.transferToMap(json);
        List<Map> hourList = JsonUtils.getValue(json, "showapi_res_body.hourList", List.class);
        System.out.println(hourList);
        // 每一个集合对象都是List
        for(Map hour : hourList){
            System.out.println(hour);
        }
    }

    /**
     * 利用List语法获取第6个时点天气预报
     */
    @Test
    public void case5(){
        Map<String, Object> jsonMap = JsonUtils.transferToMap(json);
        String area = JsonUtils.getValue(json, "showapi_res_body.hourList[5].weather_code", String.class);
        System.out.println(area);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

javachen__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值