SpringMVC @RequestBody屬性名大寫字母注入失敗的解決
@RequestBody屬性名大寫字母注入失敗
問題描述
我現(xiàn)在有一個接口通過一個實體去接收一系列的參數(shù),前端傳參為一個JSON字符串,但是當我的屬性名以大寫字母開頭,或者第二個字母是大寫字母的時候,我發(fā)現(xiàn)后端接收不到參數(shù)值。
User實體:
import lombok.Data;
@Data
public class User{
?? ?private Long id;
?? ?private Integer pId;
?? ?private String Name;
?? ?//getter,setter由lombok自動生成
?? ?//setId, setPId, setName
?? ?//getId, getPId, getName
}前端傳參:
{
? ? "id": 1,
? ? "pId": 70,
? ? "Name": "Jack"
}接口:
?? ?@PostMapping("/add")
?? ?public void add(@RequestBody User user) {
?? ??? ?System.out.println(user.getId()); // 1
?? ??? ?System.out.println(user.getName());//null
?? ??? ?System.out.println(user.getPId()); // null
?? ?}問題分析
Name接收不到的原因是JavaBean的規(guī)范不允許出現(xiàn)這樣的屬性名,即首字母為大寫的屬性名(如:Name, URL, SuV…),這種屬性名直接忽略不注入。
解決辦法是:在屬性上面添加注解@JsonProperty(value = “Name”)顯式指定名稱的對應關系;
pId接收不到的原因是JavaBean的規(guī)范說如果第一個字母是小寫,第二個字母大寫的情況(如:pId, sUV…),在生成setter/getter的時候直接在前面加上set/get,比如pId的setter/getter是setpId()/getpId(),所以 pId在注入的時候會尋找setpId()方法,而不是setPId()。
所以解決方案是:1.在屬性上面加注解@JsonProperty(value = “pId”),2.不使用lombok, 手動寫setter -> setpId()
總結:以上兩種類型名稱注入失敗的原因都是因為Jackson(Spring使用的JSON處理工具)遵守了JavaBean的規(guī)范導致的,Jackson給的方案就是通過@JsonProperty顯式指定名稱的對應關系。
解決方案
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonProperty;
@Data
public class User{
?? ?private Long id;
?? ?
?? ?@JsonProperty(value = "pId")
?? ?private Integer pId;
?? ?
?? ?@JsonProperty(value = "Name")
?? ?private String Name;
?? ?//getter,setter由lombok自動生成
?? ?//setId, setPId, setName
?? ?//getId, getPId, getName
}import com.fasterxml.jackson.annotation.JsonProperty;
public class User{
?? ?private Long id;
?? ?private Integer pId;
?? ?
?? ?@JsonProperty(value = "Name")
?? ?private String Name;
?? ?public void setpId(){
?? ??? ?//...
?? ?}
?? ?public Integer getpId(){
?? ??? ?//...
?? ?}
?? ?//other setters,getters
?? ?//...
}@RequestBody時第二個字母大寫,映射不到
記錄一下遇到的一個問題, 賊難受
controller
/**
* 添加
*
* @param requestNavigationTagVO
* @return
*/
@PostMapping("/add")
public JsonData add(@RequestBody RequestNavigationTagVO requestNavigationTagVO) {
navigationTagService.add(requestNavigationTagVO);
return JsonData.ok();
}
RequestNavigationTagVO
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class RequestNavigationTagVO {
/**
* id
*/
private Long id;
/**
* 所屬導航id
*/
@NotNull(groups = {AddNavigationTag.class, ModifyNavigationTag.class}, message = "所屬導航id不能為空")
private Long pId;
/**
* 標簽名稱
*/
@NotBlank(groups = {AddNavigationTag.class, ModifyNavigationTag.class}, message = "標簽名稱不能為空")
private String name;
/**
* 排序
*/
@NotNull(groups = {AddNavigationTag.class, ModifyNavigationTag.class}, message = "排序不能為空")
private Integer sort;
}
postman調接口
{
"pId": 654577072911111,
"name":"中餐",
"sort":1
}
這是日志拿到的數(shù)據(jù),

可以看到拿不到pId數(shù)據(jù)(p_id的駝峰寫法),
原因: 這里使用的@Data注解(省去了get和set方法)
public Long getPId() {
...
}
public void setPId(Long PId) {
...
}

而javaBean的規(guī)范導致json傳參首字母大寫將永遠獲取不到
解決辦法
1,不去使用首字目大寫或第二個字母大寫的參數(shù)
2,自己生成get和set方法

3,使用@JsonProperty注解
@JsonProperty("pId")
private Long pId;
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringBoot如何使用@Value取配置文件中的map配置
這篇文章主要介紹了SpringBoot如何使用@Value取配置文件中的map配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
Spring Cloud Gateway 如何修改HTTP響應信息
這篇文章主要介紹了Spring Cloud Gateway 修改HTTP響應信息的方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07

