本文为您介绍如何通过Java UDF实现向基础JSON字符串中增加(覆盖)一个或多个键值对(支持嵌套JSON),接受奇数个参数。

JSON字符串增加键值UDF说明

  • 函数名:PutJsonValues
  • 功能:向基础JSON串中增加(覆盖)一个或多个键值对支持嵌套JSON,接受奇数个参数。可以和不同类型数据转换JSONString示例中的ToJsonObeject配合使用(请先完成ToJsonObeject函数的注册)。
  • 参数说明:
    • 参数1:基础JSON串。
    • 参数2:键1。
    • 参数3:值1。
    • 参数4:键2。
    • 参数5:值2。

UDF使用示例

  • 资源上传

    实际在MaxCompute公共云运行时,由于沙箱等限制,需要把fastjson.JSON包和UDF Jar包分别作为资源上传至MaxCompute,并且在DataWorks创建函数时同时引用两个资源。您可以在MVN手动下载fastjson.JSON包。

  • 注册函数

    PutJsonValues.java测试通过后,将其注册函数。

    本例中PutJsonValues.jar是UDF打包后生成的Jar,ODPSUDF-1.0-SNAPSHOT2.jar是上例ToJsonString打包后生成的Jar,而fastjson-1.2.28.odps.jarfastjson.JSON包。

    说明
    • 本例的操作步骤详情请参见资源
    • 一个UDF从发布到服务端供生产使用,需要经过打包、上传、注册这三个步骤。您可以使用一键发布功能一次性完成这些步骤(Studio会依次执行mvn clean package、上传Jar和注册UDF这三个步骤)。详情请参见打包、上传和注册
    • 通过客户端使用常用命令进行资源上传操作,请参见资源操作
  • 使用示例
    成功注册UDF后,执行以下命令。
    SELECT tojson(NULL)
    ,  tojson(concat('123', chr(3)))
    ,  tojson(123)
    ,  tojson(12.3)
    ,  tojson(true)
    ,  tojson(CAST(123  AS  DECIMAL))
    ,  putJsonValuesTest('{}', 'a', '123', 'b', tojson('abc'), 'c', '{"c1":567}')
    FROM dual;
    运行结果:
    null
    "123\u0003"
    123
    12.3
    true
    123
    {"a":123,"b":"abc","c":{"c1":567}}

UDF代码示例

import com.alibaba.fastjson.JSON; //阿里云UDF。
import com.alibaba.fastjson.JSONObject; //引入fastjson.JSON类。
import com.aliyun.odps.udf.UDF;

public class PutJsonValues extends UDF {
//MaxCompute中String类型数据与JAVA UDF中类型一致,String... keyValues为可变形参,表示参数个数不定。
    public  PutJsonValues(){
    }

    public  String evaluate(String jsonBase, String... keyValues) {
        if (jsonBase == null) {
            return null;
        }
        JSONObject outputObj = JSON.parseObject(jsonBase);
        for (int i = 1; i < keyValues.length; i = i + 2) {
            String key = keyValues[i - 1];
            String value = keyValues[i];
            if (key == null || value == null) {
                continue;
            }
            Object valueObj = JSON.parse(value);
            outputObj.put(key, valueObj);
        }
        return JSON.toJSONString(outputObj);
    }
}
说明
  • null代表"null"。a的值是数值没有引号。b的值是字符串,需要使用tojson转义为json元素(json字符串)。{"c1":567}本身已经是一个合法的json元素,因此可以直接传入。
  • PutJsonValuestojson是您使用DataWorksIntellij IDEA注册的函数名称。

单元测试

//下列代码为测试代码,用于测试数据转换是否生效,您在实际使用过程中可注释掉。
public static void main(String[] args) {
    PutJsonValues putJsonValues=new PutJsonValues();
    System.out.println(putJsonValues.hashCode();

    String js=putJsonValues.evaluate("{}", "k", "null");
    System.out.println(js);
    System.out.println(new PutJsonValues().evaluate("{}", "a", "123", "b", "234", "c", "345"));
    System.out.println(new PutJsonValues().evaluate("{}", "k", "\"abc\""));
    System.out.println(new PutJsonValues().evaluate("{}", "k", "{\"kk\":123}"));
}