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
相关产品推荐
相关产品推荐

