欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

jolt 自定义函数实现通用接口结果体返回

程序员文章站 2022-06-01 16:22:38
...

背景:因为公司目前有个对接引擎模块,需要做到适配第三方接口返回结果参数。

如:现在我们公司现有的返回结果体如下

{
“code”: 0,
“msg”: “ok”,
“data”:{}
}

A公司的第三方接口返回的结果体为

{
“status”: 200,
“notes”: “ok”,
“trades”:{}
}

B公司的第三方接口返回的结果体为

{
“code”: 1,
“message”: “ok”,
“errors”:null
}

现在的工作就是要实现通用,无论对接的公司返回的结果体是怎么样的,我都能通过配置将其转换为本公司的果体。

思路如下,我们首先要利用jolt现有的功能将第三方接口结果体的值映射到字段code、msg、data中,这个我们可以用shift来实现,但由于我们公司code为0才是成功,第三方的接口则不然可能是200或1,又或者是其他的什么值,所以我们此时需要一个判断,判断映射后的code值是否为成功,如果成为则设为0。拿A公司接口为例,如果映射后的code值为200,说明此时接口返回结果为成功,我们则将其设为0,否则直接返回。但我没找到jolt提供的比较函数,所以求人不如求己,我打算自己定以一个

由于jolt支持自定义函数,接下来我们就要动手敲代码。核心代码如下:

package tech.rongxin.oryx.test.jolt;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.bazaarvoice.jolt.ContextualTransform;
import com.bazaarvoice.jolt.SpecDriven;
import com.bazaarvoice.jolt.common.Optional;
import com.bazaarvoice.jolt.common.tree.MatchedElement;
import com.bazaarvoice.jolt.common.tree.WalkedPath;
import com.bazaarvoice.jolt.modifier.OpMode;
import com.bazaarvoice.jolt.modifier.TemplatrSpecBuilder;
import com.bazaarvoice.jolt.modifier.function.Function;
import com.bazaarvoice.jolt.modifier.spec.ModifierCompositeSpec;

public class CustomizeTransform implements SpecDriven, ContextualTransform {
    private final ModifierCompositeSpec rootSpec;

    public CustomizeTransform(Object spec) {
        EqualsFunction equalMapping = new EqualsFunction();
        Map<String,Function> functionsMap = new HashMap<>();
        // 定义方法名
        functionsMap.put("equals", equalMapping);

        functionsMap = Collections.unmodifiableMap(functionsMap);
        TemplatrSpecBuilder templatrSpecBuilder = new TemplatrSpecBuilder(OpMode.OVERWRITR, functionsMap);
        rootSpec = new ModifierCompositeSpec(ROOT_KEY, (Map<String, Object>) spec, OpMode.OVERWRITR,
                templatrSpecBuilder);
    }

    @Override
    public Object transform(Object input, Map<String, Object> context) {
        
        Map<String, Object> contextWrapper = new HashMap<>(  );
        contextWrapper.put( ROOT_KEY, context );

        MatchedElement rootLpe = new MatchedElement( ROOT_KEY );
        WalkedPath walkedPath = new WalkedPath();
        walkedPath.add( input, rootLpe );

        rootSpec.apply( ROOT_KEY, Optional.of( input), walkedPath, null, contextWrapper );
        return input;
    }
}
package tech.rongxin.oryx.test.jolt;

import com.bazaarvoice.jolt.common.Optional;
import com.bazaarvoice.jolt.modifier.function.Function;



public class EqualsFunction implements Function {


    @Override
    public Optional<Object> apply(Object... objects) {
       //定以该方法有三个参数
        if(objects[0] == null || objects[1] == null || objects[2] == null){
            return Optional.empty();
        }
        如果前两个参数相等,则返回第三个参数的值,否则返回一个参数的值
        if(objects[0].equals(objects[1])){
            return Optional.of(objects[2]);
        }else {
            return Optional.of(objects[0]);
        }
    }
}
//接口返回的结果如下:
{
    "status": 200,
    "notes": "ok",
    "trades":"调用成功"
}

//编写的表达式如下:
[{
	"operation": "shift",
	"spec": {
		"status": "code",
		"notes": "msg",
		"trades": "data"
	}
}, {
	"operation": "tech.rongxin.oryx.test.jolt.CustomizeTransform",
	"spec": {
	  "code": "=equals(@(1,code),200,0)"
	}
}]

以下是测试类

package tech.rongxin.oryx.test;


import com.bazaarvoice.jolt.Chainr;
import com.bazaarvoice.jolt.JsonUtils;

import java.util.List;

public class Test7 {
    public static void main(String[] args) {
        List chainrSpecJSON =  JsonUtils.jsonToList("[{\n" +
                "\t\"operation\": \"shift\",\n" +
                "\t\"spec\": {\n" +
                "\t\t\"status\": \"code\",\n" +
                "\t\t\"notes\": \"msg\",\n" +
                "\t\t\"trades\": \"data\"\n" +
                "\t}\n" +
                "}, {\n" +
                "\t\"operation\": \"tech.rongxin.oryx.test.jolt.CustomizeTransform\",\n" +
                "\t\"spec\": {\n" +
                "\t  \"code\": \"=equals(@(1,code),200,0)\"\n" +
                "\t}\n" +
                "}]");
        Chainr chainr = Chainr.fromSpec( chainrSpecJSON );
        Object inputJSON = JsonUtils.jsonToObject("{\n" +
                "    \"status\": 200,\n" +
                "    \"notes\": \"ok\",\n" +
                "    \"trades\":\"调用成功\"\n" +
                "}");
        Object transformedOutput = chainr.transform(inputJSON);
        System.out.println( JsonUtils.toJsonString(transformedOutput) );

    }
}

返回结果如下
jolt 自定义函数实现通用接口结果体返回
值得注意的是如果想用到我们自定义的函数operation的类型就必须是我们编写的CustomizeTransform类路径

希望这篇文章能对各位有所帮助!!!

相关标签: 技术积累