diff --git a/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/model/BaseDataDebugResult.java b/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/model/BaseDataDebugResult.java index f885854aabeb763ce4a37c3f06f2634fde70e909..d88ad8181752c43be520b6da53809192f141de90 100644 --- a/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/model/BaseDataDebugResult.java +++ b/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/model/BaseDataDebugResult.java @@ -9,22 +9,34 @@ import java.io.Serializable; * @since 1.0 Created in 2022/11/13 14:47 */ public class BaseDataDebugResult implements Serializable { + /** + * 是否执行成功 + */ + private boolean success; /** * 前端传入的执行结果类型 */ - private String reqResultType; + private String reqResultType; /** * 脚本类型 */ - private String scriptType; + private String scriptType; /** * 实际执行结果 */ - private String realResult; + private String realResult; /** * 执行过程中出现的异常 */ - private String exceptionMessage; + private String exceptionMessage; + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } public String getReqResultType() { return reqResultType; diff --git a/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/BaseDataServiceImpl.java b/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/BaseDataServiceImpl.java index edbf31156afa3a58778698bc15fa618b1cf3d475..92b110d8330268cffe5850f87a92a17aa9aed81a 100644 --- a/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/BaseDataServiceImpl.java +++ b/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/BaseDataServiceImpl.java @@ -1,21 +1,29 @@ package cn.icanci.rec.admin.biz.service.impl; +import cn.icanci.rec.admin.biz.event.log.LogEvent; import cn.icanci.rec.admin.biz.mapper.BaseDataMapper; import cn.icanci.rec.admin.biz.model.BaseDataDebugResult; import cn.icanci.rec.admin.biz.service.BaseDataService; import cn.icanci.rec.admin.dal.mongodb.common.PageList; import cn.icanci.rec.admin.dal.mongodb.daointerface.BaseDataDAO; import cn.icanci.rec.admin.dal.mongodb.dateobject.BaseDataDO; +import cn.icanci.rec.common.enums.LogOperatorTypeEnum; +import cn.icanci.rec.common.enums.ModuleTypeEnum; import cn.icanci.rec.common.enums.ResultTypeEnum; import cn.icanci.rec.common.model.TextValue; import cn.icanci.rec.common.model.config.BaseDataVO; +import cn.icanci.rec.common.utils.FastJsonUtils; import cn.icanci.rec.engine.script.RecScriptEngine; import cn.icanci.rec.engine.script.context.RecScriptEngineContext; import cn.icanci.rec.engine.script.enums.ResultTypeMapEnum; +import cn.icanci.rec.spi.event.EventDispatcher; import java.util.List; +import java.util.Map; import javax.annotation.Resource; +import javax.script.Bindings; +import javax.script.SimpleBindings; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -35,6 +43,8 @@ public class BaseDataServiceImpl implements BaseDataService { private BaseDataMapper baseDataMapper; @Resource private RecScriptEngine recScriptEngine; + @Resource + private EventDispatcher eventDispatcher; @Override public List queryAll() { @@ -44,9 +54,12 @@ public class BaseDataServiceImpl implements BaseDataService { @Override public void save(BaseDataVO baseData) { if (doInsert(baseData)) { - baseDataDAO.insert(baseDataMapper.vo2do(baseData)); + BaseDataDO insert = baseDataMapper.vo2do(baseData); + baseDataDAO.insert(insert); + eventDispatcher.fire(new LogEvent(insert.getUuid(), ModuleTypeEnum.REC_BASE_DATA, FastJsonUtils.toJSONString(insert), LogOperatorTypeEnum.CREATE)); } else { baseDataDAO.update(baseDataMapper.vo2do(baseData)); + eventDispatcher.fire(new LogEvent(baseData.getUuid(), ModuleTypeEnum.REC_BASE_DATA, FastJsonUtils.toJSONString(baseData), LogOperatorTypeEnum.CREATE)); } } @@ -90,17 +103,19 @@ public class BaseDataServiceImpl implements BaseDataService { public BaseDataDebugResult debug(BaseDataVO baseData, String scriptContentTest) { RecScriptEngineContext context; ResultTypeEnum resultType = baseData.getResultType(); + Bindings bindings = new SimpleBindings(FastJsonUtils.fromJSONString(scriptContentTest, Map.class)); if (resultType != null) { Class clazz = ResultTypeMapEnum.getClassByResultType(resultType); - context = recScriptEngine.eval(baseData.getScriptType(), scriptContentTest, clazz); + context = recScriptEngine.eval(baseData.getScriptType(), bindings, baseData.getScriptContent(), clazz); } else { - context = recScriptEngine.eval(baseData.getScriptType(), scriptContentTest); + context = recScriptEngine.eval(baseData.getScriptType(), bindings, baseData.getScriptContent()); } Object realRetVal = context.getRealRetVal(); BaseDataDebugResult result = new BaseDataDebugResult(); result.setReqResultType(baseData.getResultType() == null ? "无" : baseData.getResultType().getDesc()); result.setScriptType(baseData.getScriptType().getDesc()); + result.setSuccess(realRetVal != null); result.setRealResult(String.valueOf(realRetVal)); result.setExceptionMessage(context.getThrowable() == null ? StringUtils.EMPTY : context.getThrowable().getMessage()); return result; diff --git a/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/DomainServiceImpl.java b/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/DomainServiceImpl.java index 13a758128cc1e36454b7a3a2009aa917576520fb..76cd821262c13da80a89da2096888332e870a8dc 100644 --- a/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/DomainServiceImpl.java +++ b/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/DomainServiceImpl.java @@ -10,6 +10,7 @@ import cn.icanci.rec.common.enums.LogOperatorTypeEnum; import cn.icanci.rec.common.enums.ModuleTypeEnum; import cn.icanci.rec.common.model.TextValue; import cn.icanci.rec.common.model.config.DomainVO; +import cn.icanci.rec.common.utils.FastJsonUtils; import cn.icanci.rec.spi.event.EventDispatcher; import java.util.List; @@ -19,7 +20,6 @@ import javax.annotation.Resource; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; -import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; /** @@ -47,10 +47,10 @@ public class DomainServiceImpl implements DomainService { if (doInsert(domain)) { DomainDO insert = domainMapper.vo2do(domain); domainDAO.insert(insert); - eventDispatcher.fire(new LogEvent(insert.getUuid(), ModuleTypeEnum.REC_DOMAIN, JSON.toJSONString(insert), LogOperatorTypeEnum.CREATE)); + eventDispatcher.fire(new LogEvent(insert.getUuid(), ModuleTypeEnum.REC_DOMAIN, FastJsonUtils.toJSONString(insert), LogOperatorTypeEnum.CREATE)); } else { domainDAO.update(domainMapper.vo2do(domain)); - eventDispatcher.fire(new LogEvent(domain.getUuid(), ModuleTypeEnum.REC_DOMAIN, JSON.toJSONString(domain), LogOperatorTypeEnum.UPDATE)); + eventDispatcher.fire(new LogEvent(domain.getUuid(), ModuleTypeEnum.REC_DOMAIN, FastJsonUtils.toJSONString(domain), LogOperatorTypeEnum.UPDATE)); } } diff --git a/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/MetadataServiceImpl.java b/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/MetadataServiceImpl.java index a10683233b45656542ad70d0ececfaac58ffe9c9..55d09623372407f0d3ff1fc7beb0c48d73dd0be9 100644 --- a/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/MetadataServiceImpl.java +++ b/rec-admin/rec-admin-biz/src/main/java/cn/icanci/rec/admin/biz/service/impl/MetadataServiceImpl.java @@ -10,6 +10,7 @@ import cn.icanci.rec.common.enums.LogOperatorTypeEnum; import cn.icanci.rec.common.enums.ModuleTypeEnum; import cn.icanci.rec.common.model.TextValue; import cn.icanci.rec.common.model.config.MetadataVO; +import cn.icanci.rec.common.utils.FastJsonUtils; import cn.icanci.rec.spi.event.EventDispatcher; import java.util.List; @@ -19,7 +20,6 @@ import javax.annotation.Resource; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; -import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; /** @@ -45,10 +45,10 @@ public class MetadataServiceImpl implements MetadataService { if (doInsert(metadata)) { MetadataDO insert = metadataMapper.vo2do(metadata); metadataDAO.insert(insert); - eventDispatcher.fire(new LogEvent(insert.getUuid(), ModuleTypeEnum.REC_METADATA, JSON.toJSONString(insert), LogOperatorTypeEnum.CREATE)); + eventDispatcher.fire(new LogEvent(insert.getUuid(), ModuleTypeEnum.REC_METADATA, FastJsonUtils.toJSONString(insert), LogOperatorTypeEnum.CREATE)); } else { metadataDAO.update(metadataMapper.vo2do(metadata)); - eventDispatcher.fire(new LogEvent(metadata.getUuid(), ModuleTypeEnum.REC_METADATA, JSON.toJSONString(metadata), LogOperatorTypeEnum.UPDATE)); + eventDispatcher.fire(new LogEvent(metadata.getUuid(), ModuleTypeEnum.REC_METADATA, FastJsonUtils.toJSONString(metadata), LogOperatorTypeEnum.UPDATE)); } } diff --git a/rec-admin/rec-admin-views/src/main/resources/vueboot/src/views/ruleConfig/dialog/baseDataForm.vue b/rec-admin/rec-admin-views/src/main/resources/vueboot/src/views/ruleConfig/dialog/baseDataForm.vue index f63af1ca6bfaa4bff165dda9b6f340a12d08d22d..0645964db54aee38662bdfaa82e5819e7c273a5e 100644 --- a/rec-admin/rec-admin-views/src/main/resources/vueboot/src/views/ruleConfig/dialog/baseDataForm.vue +++ b/rec-admin/rec-admin-views/src/main/resources/vueboot/src/views/ruleConfig/dialog/baseDataForm.vue @@ -97,6 +97,15 @@ + +
+ 是否执行成功:{{ debugResult.success }}
+ 执行结果类型:{{ debugResult.reqResultType }}
+ 脚本类型:{{ debugResult.scriptType }}
+ 实际执行结果:{{ debugResult.realResult }}
+ 执行异常:{{ debugResult.exceptionMessage }} +
+
@@ -132,6 +141,7 @@ export default { dialogVisible: false, scriptContentTest: '', testPass: false, + debugResult: undefined, saveData: { domainCode: '', fieldName: '', @@ -213,6 +223,9 @@ export default { clearForm() { let vm = this try { + vm.debugResult = undefined + vm.testPass = false + vm.scriptContentTest = '' vm.$refs['ruleForm'].resetFields() } catch (e) { console.log(e) @@ -225,8 +238,17 @@ export default { debug() { this.$refs['ruleForm'].validate(async (valid) => { if (valid) { + if (!this.scriptContentTest || this.scriptContentTest.trim() === '') { + this.$message({type: 'error', message: '测试json不能为空'}); + return + } let ret = await baseDataDebug(this.saveData, this.scriptContentTest); - console.log(ret) + if (ret.ok) { + this.debugResult = ret.data.result + this.testPass = this.debugResult.success + } else { + this.$message({type: 'error', message: '测试失败:' + ret.message}); + } } }) } diff --git a/rec-admin/rec-admin-web/src/main/java/cn/icanci/rec/admin/web/controller/config/BaseDataController.java b/rec-admin/rec-admin-web/src/main/java/cn/icanci/rec/admin/web/controller/config/BaseDataController.java index 95f6e803a69f5665f50a263418f3a6d9be71b0b6..cbe2c6835cdf771d3a26861e9a15eb052874865d 100644 --- a/rec-admin/rec-admin-web/src/main/java/cn/icanci/rec/admin/web/controller/config/BaseDataController.java +++ b/rec-admin/rec-admin-web/src/main/java/cn/icanci/rec/admin/web/controller/config/BaseDataController.java @@ -56,7 +56,7 @@ public class BaseDataController { } // ================================ Debug ================================ - @GetMapping("debug") + @PostMapping("debug") public R debug(@RequestBody BaseDataDebugForm form) { BaseDataDebugResult result = baseDataService.debug(baseDataWebMapper.web2vo(form.getBaseData()), form.getScriptContentTest()); return R.builderOk().data("result", result).build(); diff --git a/rec-common/pom.xml b/rec-common/pom.xml index fb3e314bf9d79b87451f16023906f7b9d4979c09..ee0327e1b0084c57090b62f7ced2b0ede30c688d 100644 --- a/rec-common/pom.xml +++ b/rec-common/pom.xml @@ -16,4 +16,18 @@ 8 + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-collections4 + + + com.google.guava + guava + + \ No newline at end of file diff --git a/rec-common/src/main/java/cn/icanci/rec/common/utils/DateFormatDeserializer.java b/rec-common/src/main/java/cn/icanci/rec/common/utils/DateFormatDeserializer.java new file mode 100644 index 0000000000000000000000000000000000000000..5feaa0a605a702af626641f99812fc3ddd671e46 --- /dev/null +++ b/rec-common/src/main/java/cn/icanci/rec/common/utils/DateFormatDeserializer.java @@ -0,0 +1,76 @@ +package cn.icanci.rec.common.utils; + +import java.lang.reflect.Type; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.AbstractDateDeserializer; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/13 20:26 + */ +public class DateFormatDeserializer extends AbstractDateDeserializer { + /** 日期格式*/ + private String format; + + /** + * + * @param format + */ + public DateFormatDeserializer(String format) { + super(); + this.format = format; + } + + @Override + public int getFastMatchToken() { + return JSONToken.LITERAL_INT; + } + + /** + * @see com.alibaba.fastjson.parser.deserializer.DateFormatDeserializer#cast(com.alibaba.fastjson.parser.DefaultJSONParser, java.lang.reflect.Type, java.lang.Object, java.lang.Object) + */ + @SuppressWarnings("unchecked") + @Override + protected Date cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object val) { + if (format == null) { + format = "yyyy-MM-dd HH:mm:ss"; + } + if (val instanceof String) { + String strVal = (String) val; + if (strVal.length() == 0) { + return null; + } + + try { + return (Date) new SimpleDateFormat(format).parse((String) val); + } catch (ParseException e) { + throw new JSONException("parse error"); + } + } + throw new JSONException("parse error"); + } + + /** + * Getter method for property myFormat. + * + * @return property value of myFormat + */ + public String getMyFormat() { + return format; + } + + /** + * Setter method for property myFormat. + * + * @param myFormat value to be assigned to property myFormat + */ + public void setMyFormat(String myFormat) { + this.format = myFormat; + } + +} diff --git a/rec-common/src/main/java/cn/icanci/rec/common/utils/FastJsonUtils.java b/rec-common/src/main/java/cn/icanci/rec/common/utils/FastJsonUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..c21e505518ff7255826d07db7d784c3fce130e30 --- /dev/null +++ b/rec-common/src/main/java/cn/icanci/rec/common/utils/FastJsonUtils.java @@ -0,0 +1,257 @@ +package cn.icanci.rec.common.utils; + +import java.lang.reflect.Type; +import java.nio.charset.CharsetDecoder; +import java.util.Date; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/13 20:24 + */ +public class FastJsonUtils { + + /** 序列化属性 */ + private static final SerializerFeature[] SERIALIZER_FEATURES = { SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, + SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteNullBooleanAsFalse, + SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.SortField, + SerializerFeature.SkipTransientField }; + + /** 空值序列化属性 */ + private static final SerializerFeature[] SERIALIZER_FEATURES_NULL_VALUE = { SerializerFeature.WriteMapNullValue, SerializerFeature.SortField, + SerializerFeature.SkipTransientField }; + + /** 反序列化属性 */ + private static final Feature[] DE_SERIALIZER_FEATURES = { Feature.AllowUnQuotedFieldNames, Feature.AllowSingleQuotes, Feature.InternFieldNames, + Feature.AllowArbitraryCommas, Feature.IgnoreNotMatch }; + + /** 日期类型默认序列化格式 */ + private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; + + /** 序列化配置 */ + private static final SerializeConfig MAPPING = new SerializeConfig(); + + static { + MAPPING.put(Date.class, new SimpleDateFormatSerializer(DEFAULT_DATE_FORMAT)); + } + + /** + * 构造函数 + */ + private FastJsonUtils() { + } + + /** + * java对象序列化为字符串 + * + * @param obj 待序列化的java对象 + * @return + */ + public static String toJSONString(Object obj) { + return toJSONString(obj, null); + } + + /** + * Java对象转换为JSON字符串 + * + * @param obj Java对象 + * @param dateFormat 日期格式 + * @return 序列化后的JSON字符串 + */ + public static String toJSONString(Object obj, String dateFormat) { + if (StringUtils.isBlank(dateFormat)) { + return JSON.toJSONString(obj, MAPPING, SERIALIZER_FEATURES); + } + return JSON.toJSONStringWithDateFormat(obj, dateFormat, SERIALIZER_FEATURES); + } + + /** + * java对象序列化为字符串 + * + * @param obj 待序列化的java对象 + * @return + */ + public static String toJSONStringNullValue(Object obj) { + return toJSONStringNullValue(obj, null); + } + + /** + * Java对象转换为JSON字符串,空值输出,适用某些日志的原样输出的场景 + * + * @param obj obj + * @param dateFormat 日期格式 + * @return {@link String} + */ + public static String toJSONStringNullValue(Object obj, String dateFormat) { + if (StringUtils.isBlank(dateFormat)) { + return JSON.toJSONString(obj, MAPPING, SERIALIZER_FEATURES_NULL_VALUE); + } + return JSON.toJSONStringWithDateFormat(obj, dateFormat, SERIALIZER_FEATURES_NULL_VALUE); + } + + /** + * Java对象转换为二进制数据 + * + * @param obj Java对象 + * @return 序列化后的JSON二进制数据 + */ + public static byte[] toJSONStringBytes(Object obj) { + return toJSONStringBytes(obj, null); + } + + /** + * Java对象转换为二进制数据 + * + * @param obj Java对象 + * @param dateFormat 日期格式 + * @return 序列化后的JSON字符串 + */ + public static byte[] toJSONStringBytes(Object obj, String dateFormat) { + if (!StringUtils.isBlank(dateFormat)) { + MAPPING.put(Date.class, new SimpleDateFormatSerializer(dateFormat)); + } + return JSON.toJSONBytes(obj, MAPPING, SERIALIZER_FEATURES); + } + + /** + * JSON字符串反序列化为Java对象 + * + * @param json JSON字符串 + * @param clazz 反序列化对象类型 + * @return 反序列化对象 + */ + public static T fromJSONString(String json, Class clazz) { + return JSON.parseObject(json, clazz, DE_SERIALIZER_FEATURES); + } + + /** + * JSON字符串反序列化为Java对象 + * + * @param json JSON字符串 + * @param clazz 反序列化对象类型 + * @return 反序列化对象 + */ + public static List fromJSON2List(String json, Class clazz) { + return JSON.parseArray(json, clazz); + } + + /** + * JSON字符串反序列化为Java对象 + * + * @param json JSON字符串 + * @param type 反序列化对象类型 + * @return 反序列化对象 + */ + public static T fromJSONString(String json, Type type) { + return JSON.parseObject(json, type, DE_SERIALIZER_FEATURES); + } + + /** + * JSON字符串反序列化为Java对象 + * @param json JSON字符串 + * @param clazz 反序列化对象类型 + * @param dateFormat 日期格式 + * @return 反序列化对象 + */ + public static T fromJSONString(String json, Class clazz, String dateFormat) { + if (StringUtils.isNotBlank(dateFormat)) { + ParserConfig config = new ParserConfig(); + config.putDeserializer(Date.class, new DateFormatDeserializer(dateFormat)); + return JSON.parseObject(json, clazz, config, JSON.DEFAULT_PARSER_FEATURE, DE_SERIALIZER_FEATURES); + } + return JSON.parseObject(json, clazz, DE_SERIALIZER_FEATURES); + } + + /** + * JSON字符串反序列化为Java对象 + * + * @param json JSON字符串 + * @param ref 反序列化对象类型 + * @return 反序列化对象 + */ + public static T fromJSONString(String json, TypeReference ref) { + return JSON.parseObject(json, ref, DE_SERIALIZER_FEATURES); + } + + /** + * JSON字符串反序列化为Java对象 + * + * @param json JSON字符串 + * @param ref 反序列化对象类型 + * @param dateFormat 日期格式 + * @return 反序列化对象 + */ + public static T fromJSONString(String json, TypeReference ref, String dateFormat) { + if (StringUtils.isNotBlank(dateFormat)) { + ParserConfig config = new ParserConfig(); + config.putDeserializer(Date.class, new DateFormatDeserializer(dateFormat)); + return JSON.parseObject(json, ref.getType(), config, JSON.DEFAULT_PARSER_FEATURE, DE_SERIALIZER_FEATURES); + } + return JSON.parseObject(json, ref, DE_SERIALIZER_FEATURES); + } + + /** + * JSON二进制数据反序列化为Java对象 + * + * @param bytes JSON二进制数据 + * @param clazz 反序列化对象类型 + * @return 反序列化对象 + */ + public static T fromJSONString(byte[] bytes, Class clazz) { + return JSON. parseObject(bytes, clazz, DE_SERIALIZER_FEATURES); + } + + /** + * JSON二进制数据反序列化为Java对象 + * + * @param bytes JSON二进制数据 + * @param clazz 反序列化对象类型 + * @param dateFormat 日期格式 + * @return 反序列化对象 + */ + public static T fromJSONString(byte[] bytes, Class clazz, String dateFormat) { + return JSON.parseObject(bytes, clazz, DE_SERIALIZER_FEATURES); + } + + /** + * JSON二进制数据反序列化为Java对象 + * + * @param bytes JSON二进制数据 + * @param off 二进制数据起始字节数组下标 + * @param len 需要反序列化二进制数据的长度 + * @param charsetDecoder 反序列化数据的字符编码类型 + * @param clazz 反序列化对象类型 + * @return 反序列化对象 + */ + public static T fromJSONString(byte[] bytes, int off, int len, CharsetDecoder charsetDecoder, Class clazz) { + return JSON. parseObject(bytes, off, len, charsetDecoder, clazz, DE_SERIALIZER_FEATURES); + } + + /** + * JSON字符串简单添加Entry功能,只能再第一次数据添加key-value,不支持嵌套类型 + * @param json JSON字符串 + * @param key 添加的Entry key + * @param value 添加的Entry value + * @param addDelimiter 是否需要添加逗号分隔符 + * @return 添加Entry后的JSON字符串 + */ + public static String addEntry(String json, String key, String value, boolean addDelimiter) { + StringBuilder buff = new StringBuilder(); + buff.append("{").append("\"").append(key).append("\"").append(":").append("\"").append(value).append("\""); + if (addDelimiter) { + buff.append(","); + } + buff.append(json.substring(1)); + return buff.toString(); + } +}