refactor #I5EU86 序列化类库fastjson转为jackson

This commit is contained in:
zendwang
2022-08-02 17:19:52 +08:00
parent cfb22ac327
commit 931e6da455
14 changed files with 315 additions and 11 deletions

View File

@@ -32,6 +32,10 @@
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>

View File

@@ -0,0 +1,11 @@
package com.yomahub.liteflow.builder.prop;
import java.util.List;
/**
* 构建 node 的中间属性
*/
public class FlowPropBean {
List<NodePropBean> nodes;
List<ChainPropBean> chain;
}

View File

@@ -0,0 +1,22 @@
package com.yomahub.liteflow.exception;
public class JsonProcessException extends RuntimeException {
private static final long serialVersionUID = 1L;
/** 异常信息 */
private String message;
public JsonProcessException(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -1,6 +1,7 @@
package com.yomahub.liteflow.parser;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.builder.LiteFlowChainBuilder;
import com.yomahub.liteflow.builder.prop.ChainPropBean;
import com.yomahub.liteflow.enums.ConditionTypeEnum;
@@ -28,7 +29,7 @@ public abstract class JsonFlowParser extends BaseJsonFlowParser {
* 解析一个chain的过程
*/
@Override
public void parseOneChain(JSONObject chainObject) {
public void parseOneChain(JsonNode chainObject) {
ParserHelper.parseOneChain(chainObject);
}

View File

@@ -1,6 +1,7 @@
package com.yomahub.liteflow.parser;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.base.BaseZookeeperJsonFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
@@ -16,7 +17,7 @@ public class ZookeeperJsonFlowParser extends BaseZookeeperJsonFlowParser {
}
@Override
public void parseOneChain(JSONObject chainObject) {
public void parseOneChain(JsonNode chainObject) {
ParserHelper.parseOneChain(chainObject);
}

View File

@@ -4,7 +4,9 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.helper.ParserHelper;
import com.yomahub.liteflow.util.JsonUtil;
import java.util.List;
import java.util.Set;
@@ -30,13 +32,12 @@ public abstract class BaseJsonFlowParser implements FlowParser {
return;
}
List<JSONObject> jsonObjectList = ListUtil.toList();
List<JsonNode> jsonObjectList = ListUtil.toList();
for (String content : contentList) {
//把字符串原生转换为json对象如果不加第二个参数OrderedField会无序
JSONObject flowJsonObject = JSONObject.parseObject(content, Feature.OrderedField);
jsonObjectList.add(flowJsonObject);
JsonNode flowJsonNode = JsonUtil.parseObject(content);
jsonObjectList.add(flowJsonNode);
}
ParserHelper.parseJsonObject(jsonObjectList, CHAIN_NAME_SET, this::parseOneChain);
ParserHelper.parseJsonNode(jsonObjectList, CHAIN_NAME_SET, this::parseOneChain);
}
/**
@@ -44,6 +45,6 @@ public abstract class BaseJsonFlowParser implements FlowParser {
*
* @param chainObject chain 节点
*/
public abstract void parseOneChain(JSONObject chainObject);
public abstract void parseOneChain(JsonNode chainObject);
}

View File

@@ -1,6 +1,7 @@
package com.yomahub.liteflow.parser.base;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.ZookeeperJsonFlowParser;
import com.yomahub.liteflow.parser.helper.ZkParserHelper;
import org.apache.curator.framework.CuratorFramework;
@@ -54,5 +55,5 @@ public abstract class BaseZookeeperJsonFlowParser extends BaseJsonFlowParser {
* @param chainObject chain 节点
*/
@Override
public abstract void parseOneChain(JSONObject chainObject);
public abstract void parseOneChain(JsonNode chainObject);
}

View File

@@ -1,6 +1,7 @@
package com.yomahub.liteflow.parser.el;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
import com.yomahub.liteflow.parser.base.BaseJsonFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
@@ -21,7 +22,7 @@ public abstract class JsonFlowELParser extends BaseJsonFlowParser {
* @param chainObject chain 节点
*/
@Override
public void parseOneChain(JSONObject chainObject) {
public void parseOneChain(JsonNode chainObject) {
ParserHelper.parseOneChainEl(chainObject);
}

View File

@@ -1,6 +1,7 @@
package com.yomahub.liteflow.parser.el;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.base.BaseZookeeperJsonFlowParser;
import com.yomahub.liteflow.parser.helper.ParserHelper;
@@ -16,7 +17,7 @@ public class ZookeeperJsonFlowELParser extends BaseZookeeperJsonFlowParser {
}
@Override
public void parseOneChain(JSONObject chainObject) {
public void parseOneChain(JsonNode chainObject) {
ParserHelper.parseOneChainEl(chainObject);
}

View File

@@ -7,6 +7,7 @@ import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowSwitchCmpDefine;
import com.yomahub.liteflow.builder.LiteFlowChainBuilder;
@@ -286,6 +287,65 @@ public class ParserHelper {
}
}
public static void parseJsonNode(List<JsonNode> flowJsonObjectList, Set<String> chainNameSet, Consumer<JsonNode> parseOneChainConsumer) {
//先在元数据里放上chain
//先放有一个好处可以在parse的时候先映射到FlowBus的chainMap然后再去解析
//这样就不用去像之前的版本那样回归调用
//同时也解决了不能循环依赖的问题
flowJsonObjectList.forEach(jsonObject -> {
// 解析chain节点
Iterator<JsonNode> iterator = jsonObject.get(FLOW).get(CHAIN).elements();
//先在元数据里放上chain
while (iterator.hasNext()) {
JsonNode innerJsonObject = iterator.next();
//校验加载的 chainName 是否有重复的
// TODO 这里是否有个问题当混合格式加载的时候2个同名的Chain在不同的文件里就不行了
String chainName = innerJsonObject.get(NAME).textValue();
if (!chainNameSet.add(chainName)) {
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
}
FlowBus.addChain(innerJsonObject.get(NAME).textValue());
}
});
// 清空
chainNameSet.clear();
for (JsonNode flowJsonNode : flowJsonObjectList) {
// 当存在<nodes>节点定义时解析node节点
if (flowJsonNode.get(FLOW).has(NODES)) {
Iterator<JsonNode> nodeIterator = flowJsonNode.get(FLOW).get(NODES).get(NODE).elements();
String id, name, clazz, script, type, file;
while ((nodeIterator.hasNext())) {
JsonNode nodeObject = nodeIterator.next();
id = nodeObject.get(ID).textValue();
name = nodeObject.hasNonNull(NAME) ? nodeObject.get(NAME).textValue() : "";
clazz = nodeObject.get(_CLASS).textValue();
type = nodeObject.hasNonNull(TYPE) ? nodeObject.get(TYPE).textValue() : "";
script = nodeObject.hasNonNull(VALUE) ? nodeObject.get(VALUE).textValue() : "";
file = nodeObject.hasNonNull(FILE) ? nodeObject.get(FILE).textValue() : "";
// 构建 node
NodePropBean nodePropBean = new NodePropBean()
.setId(id)
.setName(name)
.setClazz(clazz)
.setScript(script)
.setType(type)
.setFile(file);
ParserHelper.buildNode(nodePropBean);
}
}
//解析每一个chain
Iterator<JsonNode> chainIterator = flowJsonNode.get(FLOW).get(CHAIN).elements();
while (chainIterator.hasNext()) {
JsonNode jsonNode = chainIterator.next();
parseOneChainConsumer.accept(jsonNode);
}
}
}
/**
* 解析一个chain的过程
*
@@ -325,6 +385,44 @@ public class ParserHelper {
}
}
/**
* 解析一个chain的过程
*
* @param chainNode chain 节点
*/
public static void parseOneChain(JsonNode chainNode) {
String condValueStr;
ConditionTypeEnum conditionType;
String group;
String errorResume;
String any;
String threadExecutorClass;
//构建chainBuilder
String chainName = chainNode.get(NAME).textValue();
LiteFlowChainBuilder chainBuilder = LiteFlowChainBuilder.createChain().setChainName(chainName);
Iterator<JsonNode> iterator = chainNode.get(CONDITION).iterator();
while (iterator.hasNext()) {
JsonNode condNode = iterator.next();
conditionType = ConditionTypeEnum.getEnumByCode(condNode.get(TYPE).textValue());
condValueStr = condNode.get(VALUE).textValue();
errorResume = condNode.get(ERROR_RESUME).textValue();
group = condNode.get(GROUP).textValue();
any = condNode.get(ANY).textValue();
threadExecutorClass = condNode.get(THREAD_EXECUTOR_CLASS).textValue();
ChainPropBean chainPropBean = new ChainPropBean()
.setCondValueStr(condValueStr)
.setGroup(group)
.setErrorResume(errorResume)
.setAny(any)
.setThreadExecutorClass(threadExecutorClass)
.setConditionType(conditionType);
// 构建 chain
ParserHelper.buildChain(chainPropBean, chainBuilder);
}
}
/**
* 解析一个chain的过程
* <p>
@@ -364,6 +462,20 @@ public class ParserHelper {
}
}
/**
* 解析一个chain的过程
*
* @param chainNode chain 节点
*/
public static void parseOneChainEl(JsonNode chainNode) {
//构建chainBuilder
String chainName = chainNode.get(NAME).textValue();
String el = chainNode.get(VALUE).textValue();
LiteFlowChainELBuilder chainELBuilder = LiteFlowChainELBuilder.createChain().setChainName(chainName);
chainELBuilder.setEL(el).build();
}
/**
* 解析一个chain的过程
*

View File

@@ -0,0 +1,109 @@
package com.yomahub.liteflow.util;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yomahub.liteflow.exception.JsonProcessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* JSON 工具类
*
* @author zendwang
*/
public class JsonUtil {
private static final Logger LOG = LoggerFactory.getLogger(JsonUtil.class);
private static ObjectMapper objectMapper = new ObjectMapper();
private JsonUtil() {
}
public static String toJsonString(Object object) {
if (ObjectUtil.isNull(object)) {
return null;
}
try {
return objectMapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
String errMsg = StrUtil.format("Error while writing value as string[{}]",object.getClass().getName());
LOG.error(errMsg);
throw new JsonProcessException(errMsg);
}
}
public static JsonNode parseObject(String text) {
if (StrUtil.isEmpty(text)) {
return null;
}
try {
return objectMapper.readTree(text);
} catch (IOException e) {
String errMsg = StrUtil.format("Error while parsing text [{}]",text);
LOG.error(errMsg);
throw new JsonProcessException(errMsg);
}
}
public static <T> T parseObject(String text, Class<T> clazz) {
if (StrUtil.isEmpty(text)) {
return null;
}
try {
return objectMapper.readValue(text, clazz);
} catch (IOException e) {
String errMsg = StrUtil.format("Error while parsing text[{}] to object[{}]",text, clazz.getClass().getName());
LOG.error(errMsg);
throw new JsonProcessException(errMsg);
}
}
public static <T> T parseObject(String text, TypeReference<T> typeReference) {
if (StrUtil.isBlank(text)) {
return null;
}
try {
return objectMapper.readValue(text, typeReference);
} catch (IOException e) {
String errMsg = StrUtil.format("Error while parsing text[{}] to object[{}]",text, typeReference.getClass().getName());
LOG.error(errMsg);
throw new JsonProcessException(errMsg);
}
}
public static <T> Map<String, T> parseMap(String text) {
if (StrUtil.isBlank(text)) {
return null;
}
try {
return objectMapper.readValue(text, new TypeReference<Map<String, T>>() {
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> List<T> parseArray(String text, Class<T> clazz) {
if (StrUtil.isEmpty(text)) {
return new ArrayList<>();
}
try {
return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -47,6 +47,10 @@
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
<build>

View File

@@ -0,0 +1,30 @@
package com.yomahub.liteflow.test.util;
import com.fasterxml.jackson.databind.JsonNode;
import com.yomahub.liteflow.parser.helper.ParserHelper;
import com.yomahub.liteflow.util.JsonUtil;
import org.junit.Test;
import java.util.Iterator;
import static com.yomahub.liteflow.common.ChainConstant.NAME;
import static com.yomahub.liteflow.common.ChainConstant.VALUE;
public class ParserHelperTest {
private final static String FLOW_JSON = "{\"flow\":{\"nodes\":{\"node\":[{\"id\":\"a\",\"class\":\"com.yomahub.liteflow.test.parser.cmp.ACmp\"},{\"id\":\"b\",\"class\":\"com.yomahub.liteflow.test.parser.cmp.BCmp\"},{\"id\":\"c\",\"class\":\"com.yomahub.liteflow.test.parser.cmp.CCmp\"},{\"id\":\"d\",\"class\":\"com.yomahub.liteflow.test.parser.cmp.DCmp\"},{\"id\":\"e\",\"class\":\"com.yomahub.liteflow.test.parser.cmp.ECmp\"},{\"id\":\"f\",\"class\":\"com.yomahub.liteflow.test.parser.cmp.FCmp\"},{\"id\":\"g\",\"class\":\"com.yomahub.liteflow.test.parser.cmp.GCmp\"}]},\"chain\":[{\"name\":\"chain2\",\"value\":\"THEN(c,g,f);\"},{\"name\":\"chain1\",\"value\":\"THEN(a,c,WHEN(b,d,SWITCH(e).to(f,g)), chain2);\"}]}}";
@Test
public void testParseOneChainEl4JsonNode() {
JsonNode rootNode = JsonUtil.parseObject(FLOW_JSON);
Iterator<JsonNode> iterator = rootNode.path("flow").path("chain").iterator();
while (iterator.hasNext()) {
JsonNode chainNode = iterator.next();
String chainName = chainNode.get(NAME).textValue();
String el = chainNode.get(VALUE).textValue();
System.out.println(chainName + "-" + el);
}
}
}

View File

@@ -48,6 +48,7 @@
<spring.version>5.0.9.RELEASE</spring.version>
<org.slf4j.version>1.7.32</org.slf4j.version>
<fastjson.version>1.2.79</fastjson.version>
<jackson.version>2.9.6</jackson.version>
<snakeyaml.version>1.29</snakeyaml.version>
<dom4j.version>2.1.3</dom4j.version>
<curator.version>5.1.0</curator.version>
@@ -110,6 +111,11 @@
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>