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

RestTemplate发送Enum枚举列表报参数类型转换异常如何解决?

错误核心原因

该异常由两点不匹配导致:

  1. @JsonValue注解仅对JSON格式的请求体/响应生效,Spring MVC默认的URL查询参数转换器不会识别该注解,默认使用枚举类的name()属性(即VALUE_1、VALUE_2)做匹配
  2. 你自定义的枚举toString()方法返回的是value字段值,拼接查询参数时传递的是value-1、value-2,和默认转换器的匹配规则不一致,导致转换失败

解决方案

方案1:全局配置枚举转换器(推荐,兼容所有带@JsonValue的枚举)

  1. 自定义通用枚举转换器工厂,读取枚举的@JsonValue值做匹配:
import com.fasterxml.jackson.annotation.JsonValue;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class EnumJsonValueConverterFactory implements ConverterFactory<String, Enum<?>> {

    @Override
    public <T extends Enum<?>> Converter<String, T> getConverter(Class<T> targetType) {
        return new EnumJsonValueConverter<>(targetType);
    }

    private static class EnumJsonValueConverter<T extends Enum<?>> implements Converter<String, T> {
        private final Map<String, T> valueMap = new HashMap<>();
        private final Class<T> enumType;

        public EnumJsonValueConverter(Class<T> enumType) {
            this.enumType = enumType;
            T[] enumConstants = enumType.getEnumConstants();
            for (T enumObj : enumConstants) {
                try {
                    for (Field field : enumType.getDeclaredFields()) {
                        if (field.isAnnotationPresent(JsonValue.class)) {
                            field.setAccessible(true);
                            Object value = field.get(enumObj);
                            if (value != null) {
                                valueMap.put(value.toString().trim(), enumObj);
                            }
                            break;
                        }
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("枚举@JsonValue值读取失败", e);
                }
            }
        }

        @Override
        public T convert(String source) {
            T result = valueMap.get(source.trim());
            if (result == null) {
                throw new IllegalArgumentException(String.format("枚举类型[%s]不存在匹配值[%s]", enumType.getName(), source));
            }
            return result;
        }
    }
}
  1. 将转换器注册到Spring MVC配置中:
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverterFactory(new EnumJsonValueConverterFactory());
    }
}

该方案无需修改发送端代码,接收端所有带@JsonValue注解的枚举参数都会自动按自定义value值转换。

方案2:修改发送端传参逻辑(无侵入接收端,快速验证)

如果不想修改全局配置,可直接在发送端传递枚举的name()属性,适配默认转换器规则:

// 把原来的.queryParam("taskNames", taskNames)替换为以下代码
.queryParam("taskNames", taskNames.stream().map(Enum::name).collect(Collectors.toList()))

该方案无需修改接收端代码,缺点是请求参数中的枚举值会变为VALUE_1、VALUE_2,而非自定义的value-1格式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 16:24:05