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

Spring Boot结合Gson,请求参数@SerializedName映射失效问题求助

在Spring Boot中使用Gson时,如何让查询参数识别@SerializedName?

这个问题我之前也碰到过,核心原因其实是Spring处理URL查询参数的逻辑和Gson的反序列化是完全分开的——你用的@SerializedName注解只在Gson处理JSON请求体或者响应序列化时生效,而@GetMapping的查询参数绑定是由Spring自己的ServletRequestDataBinder完成的,它根本不认识Gson的这个注解。这就是为什么传uniqueId(和字段名一致)能正常填充,传unique_id就不行的原因。

下面给你几个可行的解决方案,根据你的场景选就行:

方案1:手动用@RequestParam映射(适合字段少的情况)

如果你的请求参数不多,可以直接在方法参数里用@RequestParam指定参数名,然后手动赋值给GenericRequest对象:

@GetMapping("/endpoint")
public ResponsePOJO getRequest(@RequestParam("unique_id") String uniqueId) {
    GenericRequest request = new GenericRequest();
    // 记得给GenericRequest加个setter方法,或者用构造器初始化
    request.setUniqueId(uniqueId);
    return new ResponsePOJO(request.id());
}

方案2:配置全局DataBinder,让Spring识别@SerializedName(适合多字段场景)

如果你的请求对象有很多字段,手动映射太麻烦,可以配置一个全局的@ControllerAdvice,让Spring在绑定参数时自动识别Gson的@SerializedName注解:

import com.google.gson.annotations.SerializedName;
import org.springframework.beans.BeansException;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GsonParamBindingConfig {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        if (binder.getTarget() == null) {
            return;
        }
        
        // 构建参数名(@SerializedName的值)到字段名的映射
        Map<String, String> paramFieldMap = new HashMap<>();
        Class<?> targetClass = binder.getTarget().getClass();
        for (Field field : targetClass.getDeclaredFields()) {
            SerializedName serializedName = field.getAnnotation(SerializedName.class);
            if (serializedName != null) {
                paramFieldMap.put(serializedName.value(), field.getName());
            }
        }

        // 重写属性访问器,让Spring优先用@SerializedName的名字匹配字段
        binder.setPropertyAccessor(new BeanWrapperImpl(binder.getTarget()) {
            @Override
            public Object getPropertyValue(String propertyName) throws BeansException {
                String actualField = paramFieldMap.getOrDefault(propertyName, propertyName);
                return super.getPropertyValue(actualField);
            }

            @Override
            public void setPropertyValue(String propertyName, Object value) throws BeansException {
                String actualField = paramFieldMap.getOrDefault(propertyName, propertyName);
                super.setPropertyValue(actualField, value);
            }
        });
    }
}

配置完这个之后,你原来的Controller代码不用改,传unique_id就能自动填充到uniqueId字段里了。

方案3:改用JSON请求体(如果场景允许)

如果你的请求可以改成POST请求,并且用JSON格式传递参数(Content-Type设为application/json),那Gson会直接处理请求体的反序列化,这时候@SerializedName就会正常生效:

@PostMapping("/endpoint")
public ResponsePOJO getRequest(@RequestBody GenericRequest request) {
    return new ResponsePOJO(request.id());
}

这种情况下,你发送JSON格式的请求体{"unique_id":"xxx"},uniqueId字段就能被正确填充。


内容的提问来源于stack exchange,提问作者pulkit-singhal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:20:59