一、問題描述:
使用postman傳參時(shí),接口參數(shù)中有部分參數(shù)被傳遞進(jìn)了接口內(nèi)部,還有部分參數(shù)沒有接收到,如下圖:第一張圖是postman接口參數(shù),第二張圖是接收到的參數(shù)
圖一:
圖二:
二、問題解決:
這個(gè)問題其實(shí)解決很簡(jiǎn)單,就是json數(shù)據(jù)轉(zhuǎn)化為實(shí)體的過程,找尋get、set方法失敗,導(dǎo)致數(shù)據(jù)無法正常從json映射到實(shí)體,從而出現(xiàn)的問題。解決起來兩個(gè)方法,第一種就是改變量名,這種不建議使用,改動(dòng)量較大,需要將DTO、VO等都需要更改,有的甚至還需要?jiǎng)觭ql,第二種就是加個(gè)注解即可,告訴實(shí)體把某個(gè)json值就給當(dāng)前的屬性就行,比如上面例子我們可以給pOrgCode這個(gè)屬性加如下的注解:
@JsonProperty(value = "pOrgCode")
String pOrgCode;
這里的注解是com.fasterxml.jackson.annotation.JsonProperty這個(gè)包下面的注解。
三、問題原因
變量名的前兩個(gè)字母出現(xiàn)了大寫
下面一起探討下,這個(gè)過程是如何失敗的,失敗的具體點(diǎn)又是什么
其實(shí)根本原因還是在get、set方法和屬性的命名上,下面pojo的代碼
@RequiredArgsConstructor
@Data
class DataDTO{
String pOrgCode;
String name;
String uName;
String isTrue;
String Lname;
String NAme;
}
可以看到代碼沒有什么特別的,上面的@Data是lombok的注解,可以省去我們寫get、set、toString等方法。
下面再看下真正編譯后的文件是什么樣吧,如下:
class DataDTO {
String pOrgCode;
String name;
String uName;
String isTrue;
String Lname;
String HOme;
public DataDTO() {
}
public String getPOrgCode() {
return this.pOrgCode;
}
public String getName() {
return this.name;
}
public String getUName() {
return this.uName;
}
public String getIsTrue() {
return this.isTrue;
}
public String getLname() {
return this.Lname;
}
public String getHOme() {
return this.HOme;
}
public void setPOrgCode(String pOrgCode) {
this.pOrgCode = pOrgCode;
}
public void setName(String name) {
this.name = name;
}
public void setUName(String uName) {
this.uName = uName;
}
public void setIsTrue(String isTrue) {
this.isTrue = isTrue;
}
public void setLname(String Lname) {
this.Lname = Lname;
}
public void setHOme(String HOme) {
this.HOme = HOme;
}
//此處省略無關(guān)方法若干
}
從上面的編輯結(jié)果我們可以看到兩種情況:
1.首字母小寫就是將首字母進(jìn)行大寫其然后前面拼接get、set
2.首字母大寫則保持不變前面拼接get、set
下面看下這種場(chǎng)景下后臺(tái)接收到的參數(shù)展示:
通過上面圖片可以看出,只要前兩個(gè)字母出現(xiàn)了大寫字母,那么lombok生產(chǎn)的get、set方法是找尋不到真正的屬性的,所以json轉(zhuǎn)化實(shí)體就出了過程。
下面筆者又嘗試了使用idea自動(dòng)生成get、set方法,經(jīng)實(shí)現(xiàn),產(chǎn)生的get、set等如下:
class DataDTO {
String pOrgCode;
String name;
String uName;
String isTrue;
String Lname;
String HOme;
public String getpOrgCode() {
return this.pOrgCode;
}
public void setpOrgCode(String pOrgCode) {
this.pOrgCode = pOrgCode;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getuName() {
return this.uName;
}
public void setuName(String uName) {
this.uName = uName;
}
public String getIsTrue() {
return this.isTrue;
}
public void setIsTrue(String isTrue) {
this.isTrue = isTrue;
}
public String getLname() {
return this.Lname;
}
public void setLname(String lname) {
this.Lname = lname;
}
public String getHOme() {
return this.HOme;
}
public void setHOme(String HOme) {
this.HOme = HOme;
}
public DataDTO() {
}
//此處省略無關(guān)方法
}
從生產(chǎn)的get、set方法上看,這兩種生產(chǎn)略有差別,但是值得注意的是使用idea生成的get、set一樣也接收不到數(shù)據(jù),如下圖
比對(duì)發(fā)現(xiàn),其實(shí)并不是lombok多不好用,這種場(chǎng)景下我們使用idea其實(shí)也是一樣的結(jié)果。
四、使用postman請(qǐng)求接口會(huì)出這種問題,那接口和接口之前的調(diào)用會(huì)不會(huì)有這種問題?
上面這個(gè)問題是需要分場(chǎng)景的
1.http調(diào)用場(chǎng)景
答案是:部分是部分否,也就是說http調(diào)用就會(huì)有上述我們碰到的問題,但是只要一部分字段有這總問題,postman其實(shí)就是模仿http客戶端發(fā)出請(qǐng)求調(diào)用接口的。
@RestController
@RequestMapping("/org")
public class TestController {
@PostMapping("/test2")
public void testJson(@RequestBody DataDTO dataDTO){
System.out.println(dataDTO.toString());
System.out.println(dataDTO.toString());
}
@PostMapping("/test")
public void testJson2(@RequestBody DataDTO dataDTO){
HttpClientUtil httpClientUtil = new HttpClientUtil();
dataDTO = new DataDTO();
dataDTO.setpOrgCode("666");
dataDTO.setHOme("555");
dataDTO.setIsTrue("444");
dataDTO.setLname("333");
dataDTO.setName("222");
dataDTO.setuName("111");
Map<String,String> headMap = new HashMap<>();
headMap.put("Content-type","application/json;charset=UTF-8");
String s = httpClientUtil.doPost("http://localhost:8888/org/test2", headMap, JSONObject.toJSON(dataDTO).toString());
System.out.println("調(diào)用結(jié)束");
}
}
如上代碼,從新包了一個(gè)接口用于調(diào)用原接口,接口調(diào)用使用http方式來調(diào)用,這樣原接口的輸出結(jié)果如下所示:
然后我們發(fā)現(xiàn)除了前兩個(gè)字母都是大寫的場(chǎng)景下會(huì)出問題,其他都是ok的,所以這種問題其實(shí)也算是工具的問題。
2.RPC調(diào)用場(chǎng)景
若是RPC調(diào)用傳遞還是JSON結(jié)論則和HttpClient調(diào)用沒啥區(qū)別了,若是傳遞實(shí)體則不用有這種問題了。文章來源:http://www.zghlxwxcb.cn/news/detail-409913.html
五、總結(jié)
出現(xiàn)這個(gè)問題的原因是使用postman調(diào)用接口傳遞json解析失敗造成的,后面使用httpclient驗(yàn)證,只有在前兩個(gè)字母均是大寫的場(chǎng)景下,使用httpclient才會(huì)出問題,正常情況下postman會(huì)出問題的場(chǎng)景,httpclient并沒有,所以平時(shí)代碼還是放心寫就是,當(dāng)然為了以防萬一我們一定不要寫這種代碼(屬性前兩個(gè)字母出現(xiàn)大寫),若是非要這么寫也要加個(gè)注釋:JsonPropertity(value=“filedName”)。文章來源地址http://www.zghlxwxcb.cn/news/detail-409913.html
到了這里,關(guān)于json傳參到j(luò)ava接口部分參數(shù)接收不到的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!