REQ-2135: 提供更加强大的模版内容解析
This commit is contained in:
parent
c3042796a5
commit
8bfdc54d20
@ -93,6 +93,7 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -785,6 +786,9 @@ public class PendingMessageNewServiceImpl implements PendingMessageNewService {
|
||||
.orElse(null);
|
||||
// 解析并替换掉路由地址中的动态参数变量
|
||||
JSONObject routerParam = JSONObjectUtil.parseObject(adapter.getRouterParams());
|
||||
routerParam.put(MessageRouterUtil.CTX, ImmutableMap.of(
|
||||
"business", adapter.getTodoBusiness(),
|
||||
"todo", adapter.getTodo()));
|
||||
JSONObject authParam = new JSONObject();
|
||||
if (!routerParam.containsKey("ouId")) {
|
||||
authParam.put("ouId", adapter.getOuId());
|
||||
|
||||
@ -13,12 +13,14 @@ import cn.axzo.msg.center.service.enums.PendingMessageStateEnum;
|
||||
import cn.axzo.msg.center.service.enums.TodoType;
|
||||
import cn.axzo.msg.center.service.enums.YesOrNo;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
*/
|
||||
@Getter
|
||||
public class TodoRecordAdapter implements PendingRecordAdapter {
|
||||
|
||||
private final TodoBusiness business;
|
||||
@ -226,4 +228,9 @@ public class TodoRecordAdapter implements PendingRecordAdapter {
|
||||
public Boolean isRead() {
|
||||
return getState() == PendingMessageStateEnum.READ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TodoBusiness getTodoBusiness() {
|
||||
return business;
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +47,7 @@ import java.util.stream.Collectors;
|
||||
public final class MessageRouterUtil {
|
||||
|
||||
public static final String DETAIL_ROUTER_DESC = "详情";
|
||||
public static final String CTX = "ctx";
|
||||
|
||||
/**
|
||||
* 获取业务详情路由策略
|
||||
@ -227,11 +228,13 @@ public final class MessageRouterUtil {
|
||||
}
|
||||
|
||||
private static String concatRouterParam(String originalUrl, JSONObject routerParam) {
|
||||
if (routerParam.isEmpty()) {
|
||||
JSONObject copy = new JSONObject(routerParam);
|
||||
copy.remove(CTX);
|
||||
if (copy.isEmpty()) {
|
||||
return originalUrl;
|
||||
}
|
||||
StringBuilder paramBuilder = new StringBuilder();
|
||||
for (Map.Entry<String, Object> entry : routerParam.entrySet()) {
|
||||
for (Map.Entry<String, Object> entry : copy.entrySet()) {
|
||||
if (originalUrl.contains(entry.getKey() + "=")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -19,6 +19,10 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-auth-spring-boot-starter</artifactId>
|
||||
|
||||
@ -1,11 +1,18 @@
|
||||
package cn.axzo.msg.center.common.utils;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.ibatis.ognl.NullHandler;
|
||||
import org.apache.ibatis.ognl.OgnlRuntime;
|
||||
import org.apache.ibatis.parsing.GenericTokenParser;
|
||||
import org.apache.ibatis.parsing.TokenHandler;
|
||||
import org.apache.ibatis.scripting.xmltags.OgnlCache;
|
||||
import cn.axzo.basics.common.exception.ServiceException;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.builder.BuilderException;
|
||||
import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.common.TemplateParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -14,59 +21,53 @@ import java.util.Map;
|
||||
*
|
||||
* @author yanglin
|
||||
*/
|
||||
@Slf4j
|
||||
public class TemplateParser {
|
||||
|
||||
static {
|
||||
OgnlRuntime.setNullHandler(Map.class, new MapPropertyHandler());
|
||||
}
|
||||
|
||||
public static String parseNumberSign(String expression, Object root) {
|
||||
if (expression == null || root == null)
|
||||
return expression;
|
||||
GenericTokenParser parser = new GenericTokenParser("#{", "}", new OgnlTokenHandler(root));
|
||||
return parser.parse(expression);
|
||||
return parseImpl("#{", "}", expression, root);
|
||||
}
|
||||
|
||||
public static String parseDollarSign(String expression, Object root) {
|
||||
return parseImpl("${", "}", expression, root);
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private static String parseImpl(String openToken, String closeToken, String expression, Object root) {
|
||||
if (expression == null || root == null)
|
||||
return expression;
|
||||
GenericTokenParser parser = new GenericTokenParser("${", "}", new OgnlTokenHandler(root));
|
||||
return parser.parse(expression);
|
||||
try {
|
||||
StandardEvaluationContext evalContext = new StandardEvaluationContext(root);
|
||||
evalContext.addPropertyAccessor(new NullableMapAccessor());
|
||||
evalContext.addPropertyAccessor(new ReflectivePropertyAccessor());
|
||||
TemplateParserContext templateContext = new TemplateParserContext(openToken, closeToken);
|
||||
Expression exp = new SpelExpressionParser().parseExpression(expression, templateContext);
|
||||
return exp.getValue(evalContext, String.class);
|
||||
} catch (BuilderException e) {
|
||||
log.warn("无效的模版内容, 请检查格式是否正确. expression={}, value={}",
|
||||
expression, JSON.toJSONString(root), e);
|
||||
throw new ServiceException(String.format("无效的模版内容, 请检查格式是否正确. expression=%s, value=%s",
|
||||
expression, JSON.toJSONString(root)));
|
||||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class OgnlTokenHandler implements TokenHandler {
|
||||
|
||||
private final Object root;
|
||||
private static class NullableMapAccessor extends MapAccessor {
|
||||
|
||||
@Override
|
||||
public String handleToken(String content) {
|
||||
Object value = OgnlCache.getValue(content, root);
|
||||
return value == null ? "" : String.valueOf(value);
|
||||
public boolean canRead(@NonNull EvaluationContext context, Object target, @NonNull String name) {
|
||||
return target instanceof Map;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MapPropertyHandler implements NullHandler {
|
||||
|
||||
@Override
|
||||
public Object nullMethodResult(Map context, Object target, String methodName, Object[] args) {
|
||||
return null;
|
||||
@NonNull
|
||||
public TypedValue read(@NonNull EvaluationContext context, Object target, @NonNull String name) {
|
||||
Map<?, ?> map = (Map<?, ?>) target;
|
||||
Object value = map.get(name);
|
||||
if (value == null)
|
||||
return TypedValue.NULL;
|
||||
return new TypedValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持流程的 [_PENDING_VARIABLES] 的写法. 只支持顶层的这种写法, 不然词法解析不了
|
||||
*/
|
||||
@Override
|
||||
public Object nullPropertyValue(Map context, Object target, Object property) {
|
||||
if (target instanceof Map && property instanceof String) {
|
||||
String key = (String) property;
|
||||
String bracketsKey = String.format("[%s]", key.trim());
|
||||
if (((Map) target).containsKey(bracketsKey))
|
||||
return bracketsKey;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -102,4 +102,12 @@ public interface PendingRecordAdapter {
|
||||
default Long getPromoterOuId() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
default Todo getTodo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default TodoBusiness getTodoBusiness() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user