kettle自定义输出json

大数据 同时被 2 个专栏收录
2 篇文章 0 订阅
1 篇文章 0 订阅

之前一直用kettle采集数据,效果还不错。近期,需使用json数据发起http请求,所以研究下json数据的生成,中间过程踩了一些坑,记录下,将完整的效果也分享下。

进入正题

最终ktr文件(版本:kettle7,仅测试效果,简化了步骤)

 源码文件下载:json_output.ktr


1、原始数据

2、输出效果(原始是一行,为方便查看,做了格式化)

 {
    "Student":[
        {
            "Name":"张三",
            "Sex":"男",
            "Age":"56"
        },
        {
            "Name":"李四",
            "Sex":"女",
            "Age":"26"
        },
        {
            "Name":"王五",
            "Sex":"男",
            "Age":"30"
        }
    ]
}

3、方案一、常规玩法 json output组件

使用kettle处理json数据,首先想到了json组件,也是最初的尝试,操作简单,直接拖拽,效果如下

 存在问题,输出的排序非原始字段顺序,有顺序要求的可以再研究下,没去细究,各位看官有碰到并处理的可以交流下

4、方案二、深度使用 Java代码组件

可随心所欲,难度稍大些,可参考自带的帮助文档,如下效果,按原始顺序输出

 Java代码如下:


StringBuilder jsonStr;

public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException  
{  
		
		Object[] r = getRow();
	    if (r == null) {
	      setOutputDone();
	      return false;
	    }
	    if (first) { 
		   //初始化变量
		  jsonStr=new StringBuilder();
	      first=false;
	    }
		
		//取值.是否最后一行
		boolean isLastRow = get(Fields.In, "result").getBoolean(r);
		//是否数组
		boolean isArray = true;

		//取拼接后的json串
		String outJsonStr = getJsonStr(r,"Student",isArray,isLastRow);
		
		
		//输出.置最后
	    Object[] outputRow = createOutputRow(r, data.outputRowMeta.size());	    
	    get(Fields.Out, "outStr").setValue(outputRow, outJsonStr);
	    putRow(data.outputRowMeta, outputRow);
	    return true;
}

//最后一行数据的时候返回拼接的json字符串
public String getJsonStr(Object[] r , String strNode, boolean isArray, boolean isLastRow){
	//先拼接数据
	getRowStr(r,isLastRow);
	
	if(isArray){
		//返回最后拼接结果
		if(isLastRow){
			return "{\""+ strNode + "\":[" + jsonStr + "]}";
		}
	}else{
		return "{\""+ strNode + "\":" + jsonStr + "}";
		
	}
	return "";
}

//拼接数据,注意最后一行没有逗号
public void getRowStr(Object[] r , boolean isLastRow){
	if(isLastRow){
		jsonStr.append( "{" + getKeyValue(r) + "}");
	}else{
		jsonStr.append( "{" + getKeyValue(r) + "},");
	}
}

//字段属性和字段值拼接
public String getKeyValue(Object[] row){
	String[] fields=getInputRowMeta().getFieldNames();
	String 	formatStr="";
	//遍历所有字段,按字符串处理,有格式要求的,可再做判断
	//另需注意Input fields的接收值,看存在几个非业务字段,减掉
	for(int i=0;i<fields.length - 1;i++){		
		//区分是否最后一个字段,最后没有逗号
		if(i == fields.length - 2){
			formatStr+="\""+fields[i]+"\":\""+row[i]+"\"";	
		}else{
			formatStr+="\""+fields[i]+"\":\""+row[i]+"\",";	
		}
	}
	return formatStr;
}

增加了isArray(是否数组对象)处理,单行数据根据值返回是否带[],当然也可后续replace处理

使用了识别最后一行组件,同时java代码里判断处理,在最后一行时开始完整拼接输出,中间过程可参照代码

收尾

  • 0
    点赞
  • 2
    评论
  • 5
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 2 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

紫蝶郎

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值