SpEL表达式:集合处理操作

spEL表达式,常用于注解中,将多样的请求/响应对象转换为统一的对象。但是多样的请求/响应对象会存在集合,我们如何通过spEL表达式去读取集合的数据,或者是重写请求/响应对象?

@Slf4j
public class ListSpELTest {

    /**
     * 触发事件后,传递到aspect类的参数。
     * <p>
     * 格式:#{spEL}表达式
     * 例如:#{#requestVo.name} 获取请求对象requestVo中的name字段的值;
     * #{#root.name}  获取响应对象name字段的值
     * #{{name:#requestVo.name,age:#root.age,type:'字符串'}}  组装map对象
     */
    public static void main(String[] args) {
        spEL2FillList();
    }


    /**
     * spEL表达式去填充list集合。
     * 需要自定义一个规则
     */
    private static void spEL2FillList() {
        ExpressionParser parser
                = new SpelExpressionParser();
        EvaluationContext context = new StandardEvaluationContext();
        //解析模板#{}
        TemplateParserContext parserContext = new TemplateParserContext();
        User user = new User(1L, "tom",
                Lists.newArrayList(new Info("xxx"), new Info("yyy")));
        context.setVariable("user", user);

        String value = "#{#user.infos[%d].url}";
        String parseValue = StringUtils.substring(value, 0, value.indexOf("[%d]")) + "}";
        if (!parseValue.equals(value)) {
            List arrObj =
                    parser.parseExpression(parseValue, parserContext).getValue(context, List.class);
            if (!CollectionUtils.isEmpty(arrObj)) {
                for (int i = 0; i < arrObj.size(); i++) {
                    String format = String.format(value, i);
                    String oriVal = parser.parseExpression(format, parserContext)
                            .getValue(context, String.class);
                    log.info("原始集合的值:{}", oriVal);
                    //业务操作,重写数据
                    String tarVal = oriVal + "-目标值";
                    parser.parseExpression(format, parserContext).setValue(context, tarVal);
                }
            }
        }
        System.out.println(user);
    }


    private static void spEL2Map() {
        ExpressionParser parser
                = new SpelExpressionParser();
        EvaluationContext context = new StandardEvaluationContext();
        Account account = new Account("Deniro");
        //        User user = new User(1L, "tom",
        //                Lists.newArrayList(new Info("xxx"), new Info("yyy")));
        User user = new User(1L, "tom", null);
        //设置上下文对象
        context.setVariable("account", account);
        context.setVariable("user", user);
        //将上下文对象转换为Map对象,支持三目表达式#user?.infos
        Map<String, Object> objectMap =
                (Map) parser.parseExpression("{acName:#account.name,userUrls:#user.infos?.![#this]}")
                        .getValue(context);
        System.out.println(objectMap);
    }


    /**
     * 获取到集合的值
     */
    private static void getListValue() {
        Account account = new Account("Deniro");
        ExpressionParser parser
                = new SpelExpressionParser();
        EvaluationContext context = new StandardEvaluationContext(account);
        //将数据转换成集合
        List<Double> scores = new ArrayList<>();
        scores.addAll(Arrays.asList(23.1, 82.3, 55.9));

        context.setVariable("scores", scores);//在上下文中定义 scores 变量
        List<Double> scoresGreat80 = (List<Double>) parser.parseExpression("#scores.?[#this>80]")
                .getValue(context);
        System.out.println(scoresGreat80);
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Account {
        private String name;
    }

}

推荐阅读

Spring系列之强大的Spel表达式

推荐阅读更多精彩内容