You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何验证Groovy文本是简单值而非Groovy脚本并实现类型转换?

安全解析Groovy风格的基本类型与数组

不用GroovyShell.evaluate()执行代码,我们可以通过解析Groovy抽象语法树(AST)的方式,安全提取基本类型及基本类型数组的值,完全避免代码执行风险。以下是具体实现方案:

核心思路

利用Groovy的AstBuilder将输入的字符串解析为语法树节点,然后只允许处理数字字面量、字符串字面量、仅包含上述类型的数组字面量,拒绝任何可执行的代码节点(比如表达式、方法调用等),从而安全转换为对应类型。

实现代码

import org.codehaus.groovy.ast.expr.*
import org.codehaus.groovy.control.CompilerConfiguration

def safeParseParam(String param) {
    def config = new CompilerConfiguration()
    config.scriptBaseClass = groovy.lang.Script.name

    try {
        // 解析输入为AST节点,仅做语法分析不执行代码
        def ast = new AstBuilder().parse(script: param, compilerConfiguration: config)
        if (ast.size() != 1 || !(ast[0] instanceof Expression)) {
            throw new IllegalArgumentException("输入不是合法的单个字面量表达式")
        }

        return parseExpression(ast[0])
    } catch (Exception e) {
        throw new IllegalArgumentException("不支持的输入类型或语法错误", e)
    }
}

def parseExpression(Expression expr) {
    switch (expr) {
        case IntLiteral:
            return expr.value
        case LongLiteral:
            return expr.value
        case StringLiteral:
            return expr.value
        case ListExpression:
            // 递归解析数组元素,确保仅包含基本类型
            return expr.expressions.collect { elemExpr ->
                parseExpression(elemExpr)
            }
        default:
            throw new IllegalArgumentException("不支持的表达式类型: ${expr.class.simpleName}")
    }
}

// 测试示例
def testInputs = [
    "[56, 23, 56]",
    '["asdf", "qwer"]',
    '"aswqer"',
    "89"
]

testInputs.each { input ->
    try {
        def result = safeParseParam(input)
        println "输入: $input → 解析结果: $result (类型: ${result.class.simpleName})"
    } catch (Exception e) {
        println "输入: $input → 错误: ${e.message}"
    }
}

说明

  1. 安全性:AstBuilder仅做语法解析,不会执行任何代码,通过限制允许的节点类型,彻底杜绝代码注入风险。
  2. 支持类型:自动识别并转换int、long、String,以及由这些类型组成的数组。
  3. 错误处理:如果输入是Groovy可执行代码(如1+2、println('test'))或非法语法,会直接抛出异常。

如果需要支持更多基本类型(如float、boolean),只需在parseExpression方法中添加对应的字面量节点判断即可。

内容的提问来源于stack exchange,提问作者Dean Hiller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:55:46