ajax-springboot前後臺通信驗錯

默認contenType下

在ajax中不寫contentType的情況下

contentType:“application/x-www-form-urlencoded;charset=UTF-8” (默認)

總結以下例證:

當ajax爲默認的application/x-www-form-urlencoded時,能夠處理簡單的JSON(單層),遇到複雜的嵌套JSON的情況就不能處理了(含數組情況);

這種情況下要處理嵌套JSON的內容,必須將其轉化成傳統的key=value的形式後放入ajax的data中。

相對而言,在簡單的JSON情況下,後臺的controller中直接在方法上寫形參即可,亦可用vo對象接收;而在複雜參數的情況下,必須使用vo對象來進行值接收,再寫在形參上是行不通的。

1.當爲簡單JSON時

以下傳輸的json中4個字段都爲字符串

ajax

// 例如:
// -----------------right-begin-----------------
var history = 'aaa';
var professionScale = 'bbb';
var constructionScale = 'ccc';
var award = 'ddd';
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data: {
        "history": history,
        "professionScale": professionScale,
        "constructionScale": constructionScale,
        "award": award},
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
       console.log('請求系統異常');
    }
});
// -----------------right-end-----------------

controller

// -----------------right-begin-----------------
// 以下1.2均可

// 1.用單獨的字段來接收
@PostMapping("/api/admin/about-JK/edit-JK-text")
// 順便補充,如果前臺json傳過來的名稱中有和參數名稱不對應的情況
// 例如:profession_scale,只需要在參數前加 
// @RequestParam("profession_scale") String professionScale
// 但是隻能是用單個參數接收的時候可以用,但是如果是vo對象接收,就沒有辦法了!
// 還是隻能修改ajax中data的key
public JsonData editAboutJKTextAdmin(
    String history, String professionScale,String constructionScale,
	String award) {
    JsonData json = aboutJKService.editAboutJKText(aboutJKVo);

    return json;
}

// 2.用vo對象來接受
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(AboutJKVo aboutJKVo) {
    JsonData json = aboutJKService.editAboutJKText(aboutJKVo);

    return json;
}

// -----------------right-end-----------------

vo

// -----------------right-begin-----------------
@Data //lombok
@AllArgsConstructor //lombok
@NoArgsConstructor //lombok
public class AboutJKVo implements Serializable {
    private String history;
    private String professionScale;
    private String constructionScale;
    private String award;
}
// -----------------right-end-----------------

2.當爲複雜JSON的時候

意爲多重嵌套的JSON,最典型的即含有數組的JSON

ajax

// 1.
// ------------------- error-begin -------------------
// 服務器直接 500
var carouselLink = new Array();
carouselLink.push('1.jpg');
carouselLink.push('2.jpg');
carouselLink.push('3.jpg');
var history = 'aaa';
var professionScale = 'bbb';
var constructionScale = 'ccc';
var award = 'ddd';
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data: {
        "carouselLink": carouselLink,
        "history": history,
        "professionScale": professionScale,
        "constructionScale": constructionScale,
        "award": award},
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
       console.log('請求系統異常');
    }
});
// ------------------- error-end -------------------
// 如果還要使用默認contentType爲application/x-www-form-urlencoded;charset=UTF-8
// 以上的ajax已經行不通了!
// 那應該怎麼寫?
// 使用application/x-www-form-urlencoded兼容度最高的key=value形式
// 2.
// ------------------- right-begin -------------------
var carouselLink = new Array();
carouselLink.push('1.jpg');
carouselLink.push('2.jpg');
carouselLink.push('3.jpg');
var history = 'aaa';
var professionScale = 'bbb';
var constructionScale = 'ccc';
var award = 'ddd';
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data:
    "carouselLink="+carouselLink+"&history=" + history+
    "&professionScale="+ professionScale +
    "&constructionScale="+ constructionScale +"&award=" + award,
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});
// ------------------- right-end -------------------


controller

// 3.
// ------------------- error-begin -------------------
// 1.用單獨的字段來接收
// 服務器也是直接 500
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(
    List<String> carouselLink,
    String history, String professionScale,String constructionScale,
    String award) {
    System.out.println(carouselLink + history + 
                       professionScale + constructionScale + award);

    return null;
}
// ------------------- error-end -------------------
// 當key=value中有了list之後,controller內便不能直接用參數接收了!
// 只能通過vo對象來接收
// 4.
// -----------------right-begin-----------------
// 2.用vo對象來接受
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);

    return null;
}
// -----------------right-end-----------------

vo

// -----------------right-begin-----------------
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AboutJKVo implements Serializable {
    private List<String> carouselLink;
    private String history;
    private String professionScale;
    private String constructionScale;
    private String award;
}
// -----------------right-end-----------------

結果

1 和 3 組合 500 NoSuchMethodException

1 和 4 組合 500 java.lang.NumberFormatException: For input string: “”

2 和 3 組合 500 NoSuchMethodException

2 和 4 組合 success!

contentType爲application/json時

在ajax中聲明 contentType的類型:

contentType: “application/json”

總結以下例證

1.當ajax聲明contentType: "application/json"之後,與之對應,不能再像默認contentType爲application/x-www-form-urlencoded的時候一樣,直接傳遞json對象了,必須傳遞json字符串!

通過JSON.stringify() 去將json對象轉化成json字符串。

2.與之對應,controller需要注意的是:

  • controller中,跟在@RequestBody後的參數,和ajax傳遞過來的json字符串,必須是嚴格的json層級對應情況!

    • 情況一:假如ajax傳輸的json字符串爲’[1, 2, 3]’ 與之對應,controller的形參中,就必須有一個List<Integer> list 去接收它。

    • 情況二:假如ajax傳輸的json字符串爲’{“names”:[“aaa”, “bbb”, “ccc”]}’,那麼controller的形參中,就必須是一個vo對象,並且對象中有一個叫做names的List<String>。

    • 總:只要外部有{},則controller應該用vo對象接收,直接是’aaa’字符串,或者[‘aaa’, ‘bbb’]數組,則必須用一個對應的String 類型,或者List<string>類型來接收。

  • @RequestBody在一個controller層方法中,只能出現一次。

    • 如果一個方法形參中出現多個@RequestBody,將會注入失敗。
    • 如果只有一個String類型的參數,但是ajax傳輸過來的是一個複雜json,那麼這個複雜json將以字符串的形式被全部注入到那個String類型的參數中,這是一種極端情況。

3.補充,建議:可能是jquery的版本問題,在我原來使用3.x版本的jquery時,出現過複雜json無法注入vo對象的情況,原因是jquery默認會調用jQuery.param深度序列化參數,以適應如PHP和Ruby on Rails框架,但servelt api無法處理。但這裏我使用的jquery-2.1.1並未出現此狀況。

但穩妥起見,建議在ajax中加上參數traditional:true,來保障json的解析正常!

1.restful風格下傳遞複雜json

ajax

// 1.
// ------------------- error-begin -------------------
var carouselLink = new Array();
carouselLink.push('1.jpg');
carouselLink.push('2.jpg');
carouselLink.push('3.jpg');
var history = 'aaa';
var professionScale = 'bbb';
var constructionScale = 'ccc';
var award = 'ddd';
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data:{
        "carouselLink": carouselLink,
        "history": history,
        "professionScale": professionScale,
        "constructionScale": constructionScale,
        "award": award},
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});
// ------------------- right-end -------------------


// 2.
// -----------------right-begin-----------------
var carouselLink = new Array();
carouselLink.push('1.jpg');
carouselLink.push('2.jpg');
carouselLink.push('3.jpg');
var history = 'aaa';
var professionScale = 'bbb';
var constructionScale = 'ccc';
var award = 'ddd';

var dataJSON = {
    "carouselLink": carouselLink,
    "history": history,
    "professionScale": professionScale,
    "constructionScale": constructionScale,
    "award": award}

var dataJSONStr = JSON.stringify(dataJSON);
console.log(dataJSON)
console.log(dataJSONStr)
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    data: dataJSONStr,
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});
// -----------------right-end-----------------

controller

// 3.
// ------------------- error-begin -------------------
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(List<String> carouselLink, String history, 
                                     String professionScale, String constructionScale,
                                     String award) {
    System.out.println(carouselLink + 
                       history + 
                       professionScale + 
                       constructionScale + award);
    return null;
}
// ------------------- error-end -------------------

// 4.
// ------------------- error-begin -------------------
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(@RequestBody List<String> carouselLink, 
                                     @RequestBody String history, 
                                     @RequestBody String professionScale, 
                                     @RequestBody String constructionScale,
                                     @RequestBody String award) {
    System.out.println(carouselLink + 
                       history + 
                       professionScale + 
                       constructionScale + award);
    return null;
}
// ------------------- error-end -------------------

// 5.
// ------------------- error-begin -------------------
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);
    
    return null;
}
// ------------------- error-end -------------------

// 6.
// -----------------right-begin-----------------
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(@RequestBody AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);
    
    return null;
}
// -----------------right-end-----------------

vo

// -----------------right-begin-----------------
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AboutJKVo implements Serializable {
    private List<String> carouselLink;
    private String history;
    private String professionScale;
    private String constructionScale;
    private String award;
}
// -----------------right-end-----------------

結果

1 和 3 組合 500 NoSuchMethodException

1 和 4 組合 400 JSON parse error: Unrecognized token ‘carouselLink’

1 和 5 組合 無報錯,但

AboutJKVo(carouselLink=null, history=null, professionScale=null, constructionScale=null, award=null)

1 和 6 組合 400 badRequest!

2 和 3 組合 500 NoSuchMethodException

2 和 4 組合 400 JSON parse error

2 和 5 組合 無報錯,但

AboutJKVo(carouselLink=null, history=null, professionScale=null, constructionScale=null, award=null)

2 和 6 組合 success!

2.restful風格下傳遞簡單json

ajax

// 1.
// ------------------- error-begin -------------------
var history = 'aaa';
var professionScale = 'bbb';
var constructionScale = 'ccc';
var award = 'ddd';
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data:{
        "history": history,
        "professionScale": professionScale,
        "constructionScale": constructionScale,
        "award": award},
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});
// ------------------- error-end -------------------


// 2.
// -----------------right-begin-----------------
var history = 'aaa';
var professionScale = 'bbb';
var constructionScale = 'ccc';
var award = 'ddd';

var dataJSON = {
    "history": history,
    "professionScale": professionScale,
    "constructionScale": constructionScale,
    "award": award}

var dataJSONStr = JSON.stringify(dataJSON);
console.log(dataJSON)
console.log(dataJSONStr)
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    data: dataJSONStr,
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});
// -----------------right-end-----------------

controller

// 3.
// ------------------- error-begin -------------------
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(String history, String professionScale, 
                                     String constructionScale,
                                     String award) {
    System.out.println(history + 
                       professionScale + 
                       constructionScale + award);
    return null;
}
// ------------------- error-end -------------------

// 4.
// ------------------- error-begin -------------------
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(@RequestBody String history, 
                                     @RequestBody String professionScale, 
                                     @RequestBody String constructionScale,
                                     @RequestBody String award) {
    System.out.println(history + 
                       professionScale + 
                       constructionScale + award);
    return null;
}
// ------------------- error-end -------------------

// 5.
// ------------------- error-begin -------------------
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);
    
    return null;
}
// ------------------- error-end -------------------

// 6.
// -----------------right-begin-----------------
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(@RequestBody AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);
    
    return null;
}
// -----------------right-end-----------------

vo

// -----------------right-begin-----------------
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AboutJKVo implements Serializable {
    private String history;
    private String professionScale;
    private String constructionScale;
    private String award;
}
// -----------------right-end-----------------

結果

1 和 3 組合 無報錯,但 4個參數全爲null

1 和 4 組合 400 badRequest @RequestBody需要的參數無法注入

1 和 5 組合 無報錯,但 4個參數全爲null

1 和 6 組合 JSON parse error

2 和 3 組合 無報錯,但4個參數全爲null

2 和 4 組合 400 badRequest @RequestBody需要的參數無法注入

2 和 5 組合 無報錯,但 4個參數全爲null

2 和 6 組合 success!

3.restful風格下傳遞list

ajax

// 1.
var list = new Array();
list.push('1.jpg');
list.push('2.jpg');
list.push('3.jpg');

$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data:list,
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});

// 2.
var list = new Array();
list.push('1.jpg');
list.push('2.jpg');
list.push('3.jpg');

$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data:{'list':list},
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});

// 2.+
var list = new Array();
list.push('1.jpg');
list.push('2.jpg');
list.push('3.jpg');
var dataJSON = {'list':list}
var dataJSONStr = JSON.stringify(dataJSON);
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data: dataJSONStr,
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});

// 3.
var carouselLink = new Array();
carouselLink.push('1.jpg');
carouselLink.push('2.jpg');
carouselLink.push('3.jpg');

var list = JSON.stringify(carouselLink);
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data:list,
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});

controller

// 4.
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(List<String> list) {
    System.out.println(list);

    return null;
}

// 5.
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(@RequestBody List<String> list) {
    System.out.println(list);

    return null;
}

// 6.
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);

    return null;
}

// 7.
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(@RequestBody AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);

    return null;
}

vo

@Data
@AllArgsConstructor
@NoArgsConstructor
public class AboutJKVo implements Serializable {
    private List<String> list;
}

結果

1 和 4 500 NoSuchMethodException

1 和 5 400 JSON parse error

1 和 6 無報錯,但爲null

1 和 7 400 JSON parse error

2 和 4 500 NoSuchMethodException

2 和 5 400 JSON parse error

2 和 6 無報錯,但爲null

2 和 7 400 JSON parse error

3 和 4 500 NoSuchMethodException

3 和 5 success!

3 和 6 無報錯,但爲null

3 和 7 400 JSON parse error

2+ 和 4 500 NoSuchMethodException

2+ 和 5 400 JSON parse error

2+ 和 6 無報錯,但爲null

2+ 和 7 success!

4.restful下傳遞單參

ajax

// 1.
var professionScale = 'aaa'

$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data: professionScale,
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});

// 2.
var professionScale = 'aaa'

$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data:{'professionScale':professionScale},
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});

// 3.
var professionScale = 'aaa'

var dataJSON = {'professionScale':professionScale}
var dataJSONStr = JSON.stringify(dataJSON);
$.ajax({
    url:"/api/admin/about-JK/edit-JK-text",
    contentType:'application/json',
    type: "POST",
    // 期待服務器返回的類型:json、jsonp、text ... 此參數加上最好
    dataType: "json",
    data: dataJSONStr,
    dataType: "json",
    success: function (res) {
        if (res.code == 0) {
            console.log(res);
        } else {
            console.log(res);
        }
    },
    error: function () {
        console.log('請求系統異常');
    }
});

controller

// 4.
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(String professionScale) {
    System.out.println(professionScale);

    return null;
}

// 5.
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(@RequestBody String professionScale) {
    System.out.println(professionScale);

    return null;
}

// 6.
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);

    return null;
}

// 7.
@PostMapping("/api/admin/about-JK/edit-JK-text")
public JsonData editAboutJKTextAdmin(@RequestBody AboutJKVo aboutJKVo) {
    System.out.println(aboutJKVo);

    return null;
}

vo

@Data
@AllArgsConstructor
@NoArgsConstructor
public class AboutJKVo implements Serializable {
    private String professionScale;
}

結果

1 和 4 無報錯,但爲null

1 和 5 success!

1 和 6 無報錯,但爲null

1 和 7 JSON parse error: Unrecognized token ‘aaa’

2 和 4 無報錯,但爲null

2 和 5 錯誤的值 professionScale = “professionScale=aaa”

2 和 6 無報錯,但爲null

2 和 7 JSON parse error: Unrecognized token ‘professionScale’

3 和 4 無報錯,但爲null

3 和 5 錯誤的值 professionScale = “{“professionScale”:“aaa”}”

3 和 6 無報錯,但爲null

3 和 7 success!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章