之前一直用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代码里判断处理,在最后一行时开始完整拼接输出,中间过程可参照代码
收尾
版权声明:本文为zidielang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。