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

SpEL类型转换异常:LinkedHashMap转String失败及自定义转换器无效

SpEL模板字符串评估时LinkedHashMap转String失败问题

问题场景

使用SpEL评估模板字符串,核心代码如下:

Expression exp = parser.parseExpression(templatedString, templateParserContext);
return exp.getValue(readOnlyEvalContext, contextRoot);

当模板字符串为"flow.config: ${flow.config}",且contextRoot中的flow.config是Jackson反序列化生成的LinkedHashMap<String, Object>时,抛出类型转换异常:

org.springframework.expression.spel.SpelEvaluationException: EL1001E: Type conversion problem, cannot convert from java.util.LinkedHashMap<?, ?> to java.lang.String

尝试的无效解决方案

为将LinkedHashMap序列化为JSON字符串,创建自定义转换器并通过WebMvcConfigurer注册:

Converter配置类

@Configuration
public class ConverterConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new ConverterLinkedHashMapToString());
    }
}

自定义转换器

@Component
public class ConverterLinkedHashMapToString implements Converter<LinkedHashMap<?, ?>, String> {

    @Override
    public String convert(LinkedHashMap<?, ?> source) {
        return objMapper.writeValueAsString(source);
    }

    @Override
    public <U> Converter<LinkedHashMap<?, ?>, U> andThen(Converter<? super String, ? extends U> after) {
        return Converter.super.andThen(after);
    }
}

无论如何调整,转换器均未生效,仍持续抛出相同异常。

完整异常栈

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1001E: Type conversion problem, cannot convert from java.util.LinkedHashMap<?, ?> to java.lang.String
    at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:87) ~[spring-expression-5.3.22.jar:5.3.22]
    at org.springframework.expression.common.ExpressionUtils.convertTypedValue(ExpressionUtils.java:57) ~[spring-expression-5.3.22.jar:5.3.22]
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:378) ~[spring-expression-5.3.22.jar:5.3.22]
    at org.springframework.expression.common.CompositeStringExpression.getValue(CompositeStringExpression.java:129) ~[spring-expression-5.3.22.jar:5.3.22]
    at org.springframework.expression.common.CompositeStringExpression.getValue(CompositeStringExpression.java:43) ~[spring-expression-5.3.22.jar:5.3.22]

[...] 

    ... 3 common frames omitted
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.util.LinkedHashMap<?, ?>] to type [java.lang.String]
    at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322) ~[spring-core-5.3.22.jar:5.3.22]
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195) ~[spring-core-5.3.22.jar:5.3.22]
    at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:82) ~[spring-expression-5.3.22.jar:5.3.22]
    ... 38 common frames omitted

问题原因及解决方案

原因

通过WebMvcConfigurer注册的转换器仅作用于Spring MVC的请求响应转换流程,SpEL的表达式求值上下文(EvaluationContext)使用独立的ConversionService,两者并不共用,因此自定义转换器无法被SpEL识别。

解决方案

需要将自定义转换器注册到SpEL使用的ConversionService中,具体步骤如下:

  1. 创建自定义ConversionService Bean
@Configuration
public class ConversionConfig {

    @Bean
    public ConversionService spelConversionService(ObjectMapper objMapper) {
        GenericConversionService conversionService = new GenericConversionService();
        conversionService.addConverter(new ConverterLinkedHashMapToString(objMapper));
        return conversionService;
    }
}
  1. 修改自定义转换器,注入ObjectMapper
public class ConverterLinkedHashMapToString implements Converter<LinkedHashMap<?, ?>, String> {

    private final ObjectMapper objMapper;

    public ConverterLinkedHashMapToString(ObjectMapper objMapper) {
        this.objMapper = objMapper;
    }

    @Override
    public String convert(LinkedHashMap<?, ?> source) {
        try {
            return objMapper.writeValueAsString(source);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("序列化LinkedHashMap为JSON失败", e);
        }
    }
}
  1. 将自定义ConversionService绑定到SpEL的EvaluationContext
    在构建readOnlyEvalContext时,设置自定义的ConversionService:
@Autowired
private ConversionService spelConversionService;

// ...

StandardEvaluationContext readOnlyEvalContext = new StandardEvaluationContext(contextRoot);
readOnlyEvalContext.setConversionService(spelConversionService);

Expression exp = parser.parseExpression(templatedString, templateParserContext);
return exp.getValue(readOnlyEvalContext);

如果你的readOnlyEvalContext是通过其他方式创建的,确保调用其setConversionService方法传入自定义的ConversionService即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:18:18