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

Feign Client请求参数编码异常求助:Long类型参数解析错误

解决Feign Client中Map参数Long类型序列化问题

问题根源

Feign默认的SpringFormEncoder处理@RequestParam修饰的Map<String, Object>参数时,会对Map内的Object值直接调用toString()方法。对于Long类型来说,toString()会返回带L后缀的字符串(比如1234567893L),导致服务端解析时将其识别为字符串类型,而非预期的数字类型。

解决方案

1. 配置Jackson ObjectMapper,让Long序列化输出纯数字

先定义自定义ObjectMapper,配置Long类型的序列化规则,避免输出L后缀:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper customObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        // 配置Long及基本类型long序列化为纯数字格式
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(module);
        return objectMapper;
    }
}

2. 自定义Feign Encoder,结合ObjectMapper处理Map参数

默认的SpringFormEncoder不会用Jackson处理Map参数,需要自定义Encoder,利用上面的ObjectMapper序列化Map中的值:

import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.support.SpringFormEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.MultiValueMap;

import java.lang.reflect.Type;
import java.util.Map;

@Configuration
public class FeignConfig {
    @Autowired
    private ObjectMapper objectMapper;

    @Bean
    public Encoder feignEncoder() {
        return new SpringFormEncoder() {
            @Override
            public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
                if (object instanceof Map) {
                    Map<String, Object> map = (Map<String, Object>) object;
                    MultiValueMap<String, String> multiValueMap = new org.springframework.util.LinkedMultiValueMap<>();
                    map.forEach((key, value) -> {
                        try {
                            // 用自定义ObjectMapper序列化值,避免Long带L后缀
                            String serializedValue = objectMapper.writeValueAsString(value);
                            // 移除Jackson序列化基本类型时添加的引号
                            serializedValue = serializedValue.replace("\"", "");
                            multiValueMap.add(key, serializedValue);
                        } catch (Exception e) {
                            throw new EncodeException("序列化Map值失败", e);
                        }
                    });
                    super.encode(multiValueMap, bodyType, template);
                } else {
                    super.encode(object, bodyType, template);
                }
            }
        };
    }
}

3. 给Feign Client指定配置类

在Feign Client接口上通过@FeignClient注解关联上述配置类:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;

@FeignClient(name = "your-service-name", configuration = FeignConfig.class)
public interface YourFeignClient {
    @GetMapping("/api/getResult")
    Result getResult(@RequestParam String id, @RequestParam Map<String, Object> params);
}

补充说明

  • 服务端基于Spring MVC接收参数时,纯数字格式的字符串会自动转换为对应数字类型(如Long),符合预期需求。
  • 该方案对Map中包含的自定义对象同样生效,ObjectMapper会正确序列化对象字段,同时处理数字类型的输出格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:54:33