1. 程式人生 > 其它 >jolt 自定義函式實現通用介面結果體返回

jolt 自定義函式實現通用介面結果體返回

技術標籤:技術積累

背景:因為公司目前有個對接引擎模組,需要做到適配第三方介面返回結果引數。

如:現在我們公司現有的返回結果體如下

{
“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) );

    }
}

返回結果如下
在這裡插入圖片描述
值得注意的是如果想用到我們自定義的函式operation的型別就必須是我們編寫的CustomizeTransform類路徑

希望這篇文章能對各位有所幫助!!!