陈昶聿
2 天以前 80d51272bfcc9a832ca5fe5110cc543c98fffc23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package com.ruoyi.common.utils;
 
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
 
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class TemplateUtils {
    private static final Pattern PATTERN = Pattern.compile("\\$\\{([^}]+)\\}");
    private static final ObjectMapper OM = new ObjectMapper();
 
    public static String render(String template, Object bean) {
        if (template == null || bean == null) {
            return template;
        }
        Matcher matcher = PATTERN.matcher(template);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String exp = matcher.group(1);
            Object val = getValueByExp(bean, exp);
            String strVal = val == null ? "" : val.toString();
            matcher.appendReplacement(sb, Matcher.quoteReplacement(strVal));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
 
    private static Object getValueByExp(Object root, String exp) {
        try {
            Object curr = root;
            if (exp.contains("#json.")) {
                String[] parts = exp.split("#json\\.", 2);
                String beanField = parts[0];
                String jsonPath = parts[1];
 
                Object jsonStrObj = getBeanField(curr, beanField);
                // ========== Java8 兼容修改点 ==========
                if (!(jsonStrObj instanceof String)) {
                    return null;
                }
                String jsonStr = (String) jsonStrObj;
                if (jsonStr.trim().isEmpty()) {
                    return null;
                }
                JsonNode node = OM.readTree(jsonStr);
                return getJsonNode(node, jsonPath);
            }
 
            String[] props = exp.split("\\.");
            for (String p : props) {
                curr = getBeanField(curr, p);
                if (curr == null) {
                    break;
                }
            }
            return curr;
        } catch (Exception e) {
            return null;
        }
    }
 
    private static Object getBeanField(Object bean, String fieldName)
            throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        if (bean == null) {
            return null;
        }
        PropertyDescriptor pd = new PropertyDescriptor(fieldName, bean.getClass());
        Method getter = pd.getReadMethod();
        return getter.invoke(bean);
    }
 
    private static Object getJsonNode(JsonNode node, String path) {
        String[] arr = path.split("\\.");
        JsonNode curr = node;
        for (String k : arr) {
            curr = curr.get(k);
            if (curr == null) {
                return null;
            }
        }
        return curr.isValueNode() ? curr.asText() : curr.toString();
    }
 
    // 测试
    public static void main(String[] args) {
        class User {
            private String name = "张三";
            private Integer age = 25;
            private String ext = "{\"phone\":\"13800138000\",\"addr\":{\"city\":\"杭州\"}}";
 
            public String getName() { return name; }
            public Integer getAge() { return age; }
            public String getExt() { return ext; }
        }
        User u = new User();
        String tpl = "姓名:${name},年龄:${age},手机号:${ext#json.phone},城市:${ext#json.addr.city}";
        System.out.println(render(tpl, u));
    }
}