結合此篇參考 "Spring框架學習筆記(9)——API介面設計相關知識及具體編碼實現" 在使用Spring Boot進行接收參數的時候,發現了許多問題,之前一直都很忙,最近才稍微有空研究一下此問題。 網上的大多數文章,只講Spring Boot如何實現接受參數,卻不講如何在客戶端調用, 本篇使用J ...
結合此篇參考Spring框架學習筆記(9)——API介面設計相關知識及具體編碼實現
在使用Spring Boot進行接收參數的時候,發現了許多問題,之前一直都很忙,最近才稍微有空研究一下此問題。
網上的大多數文章,只講Spring Boot如何實現接受參數,卻不講如何在客戶端調用,本篇使用Jsoup、okhttp3和postwoman測試工具進行截圖,講解如何在伺服器實現介面,同時在客戶端如何發起請求並傳參
四種請求方式介紹
可能剛入門Web開發的大家會有疑惑?不是只有get和post這兩種?
最近幾年好像流行restful風格的介面,裡面有多種方式,按照功能進行區分
不過,目前常用的就只有下麵這四個方式get、post、put、delete
本質上除了get,其他凡是都是post方式衍生出來的版本,調用的時候只需要修改方法名即可(具體可查看post方式中的代碼例子)
get方式
介紹
如下圖,我寫了一個介面
由於是本地部署,ip為localhost
,contextpath名為requestdemo
,埠預設為8080
,所以訪問的url就為http://localhost:8080/requestdemo/api/user/users
由於我們使用了@RequestMapping
註解,所以,不過使用什麼方式都可以訪問到數據,如下圖,切換為post方式訪問
如果想要指定get方式,可以使用@GetMapping
註解,GetMapping註解其實是相當於這樣的寫法@RequestMapping("users",method = [(RequestMethod.GET)])
,註解中method屬性接收的是數組參數
指定了get方式,使用其他的post方式、put方式等都是返回不了數據的,報405錯誤代碼,如下圖
接收數據
@GetMapping("select")
fun selectByPk(@RequestParam("id") ids:Int):User {
println(ids)
return User("zhangsan",19)
}
@GetMapping("select1")
fun selectByPk1(ids:Int) {
println(ids)
}
第一種方式客戶端應該這樣調用,輸入網址即可
http://localhost:8080/requestdemo/api/user/select?id=1
第二種參數沒有註解,所以spring boot預設以變數名作為參數,所以應該是這樣調用
http://localhost:8080/requestdemo/api/user/select1?ids=1
下麵報錯的截圖也是充分說明瞭這一點
客戶端代碼發起get請求
客戶端發起get請求用代碼寫就比較簡單,只要我們把url拼接好即可
Jsoup:
Jsoup中的get方法是返回一個Document(網頁對象,之後可進行css篩選來找到指定節點,從而獲取內容)
//需要ignoreContentType,忽略content-type,否則會報錯,拿不到伺服器返回的數據
val doc= Jsoup.connect("http://localhost:8080/requestdemo/api/user/select?id=1")
.ignoreContentType(true)
.get()
//輸出伺服器返回json數據
println(doc.body().text())
Okhttp3:
val client = OkHttpClient()
val request = Request.Builder()
.url("http://localhost:8080/requestdemo/api/user/select?id=1")
.get()
.build()
val call = client.newCall(request)
call.enqueue(object :Callback{
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
println(response.body()?.string())
}
})
post方式
@RequestParam註解
@RequestParam用來處理Content-Type: 為 application/x-www-form-urlencoded編碼的內容,提交方式GET、POST。
有如下的介面:
@PostMapping("update")
fun update(@RequestParam map: HashMap<String,String>) {
//輸出傳入的key和value
for (mutableEntry in map) {
println(mutableEntry.key + "=" + mutableEntry.value)
}
}
PS:不能省略RequestParam註解,否則伺服器後端接收不到數據
使用postwoman測試介面:
註意,這種方式的數據格式是表單數據application/x-www-form-urlencoded
Jsoup:
val dataMap = hashMapOf("name" to "zhangsag","age" to 11.toString())
val doc= Jsoup.connect("http://localhost:8080/requestdemo/api/user/update")
.ignoreContentType(true)
.data(dataMap)
.post()
//輸出結果
println(doc.body().text())
Jsoup中的data方法可以接受Map<String,String>,或者鍵值對,上面的例子可以改成下麵的代碼
val doc= Jsoup.connect("http://localhost:8080/requestdemo/api/user/update")
.ignoreContentType(true)
.data("name","zhangsan")
.data("age",12.toString())
.post()
//輸出結果
println(doc.body().text())
Okhttp3:
fun sendPostRequest(){
val url ="http://localhost:8080/requestdemo/api/user/update"
val client = OkHttpClient()
val formBodyBuilder = FormBody.Builder()
formBodyBuilder.add("names", "zhangsxx")
formBodyBuilder.add("ages", "19")
val request = Request.Builder()
.url(url)
.post(formBodyBuilder.build())
.build()
val call = client.newCall(request)
call.enqueue(object : Callback{
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
}
} )
}
這裡有個小問題沒搞明白,如果介面是下麵這樣,客戶端應該如何傳遞數據?我試了幾種方法,都是報錯,說是無法把String類型轉為User類型,是不是這種方法是不能傳遞的?
有路過的大神希望可以幫忙解答一下
@PostMapping("update2")
fun update2(@RequestParam user: User) {
println(user.toString())
}
@RequestBody註解
有時候,我們需要傳遞一個json字元串,就需要用到此註解
@RequestBody接受的是一個json對象的字元串,而不是Json對象
有下麵的一個介面:
@PostMapping("update1")
fun update1(@RequestBody user:User) {
println(user.toString())
}
我們在客戶端傳遞了json數據,之後spring boot就會自動調用jackson框架,把json字元串數據轉為實體類
Jsoup:
val json = "{\"name\":\"zhangs\",\"age\":18}"
val doc= Jsoup.connect("http://localhost:8080/requestdemo/api/user/update1")
.requestBody(json)
.header("content-type","application/json")
.post()
jsoup中需要添加請求頭來聲明傳遞json字元串數據,舉一反三,傳遞其他形式只需要更改content-type的值為其他形式即可
OkHttp3:
val json = "{\"name\":\"zhangs\",\"age\":18}"
val client = OkHttpClient()
val request = Request.Builder()
.url("http://localhost:8080/requestdemo/api/user/update1")
.post(RequestBody.create(MediaType.parse("application/json"),json))
.build()
val call = client.newCall(request)
call.enqueue(object :Callback{
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
println(response.body()?.string())
}
})
這裡與上面的okhttp有所類似,就是post方法裡面的參數的數據不一樣
@RequestParam -> application/x-www-form-urlencoded -> FormBody
@RequestBody -> application/json -> RequestBody
舉一反三,如果是xml格式或者是二進位格式,應該使用RequestBody來進行構建數據,具體可以自行操作一下,這裡就不再演示了
put、delete方式如何寫
Jsoup:
val json = "{\"name\":\"zhangs\",\"age\":18}"
val doc= Jsoup.connect("http://localhost:8080/requestdemo/api/user/update1")
.requestBody(json)
.header("content-type","application/json")
.method(xx)
.post()
在method方法添加即可,下圖是可選的數值:
Okhttp3中,只需要把post方法更改為put或者delete方法即可
val json = "{\"name\":\"zhangs\",\"age\":18}"
val client = OkHttpClient()
val request = Request.Builder()
.url("http://localhost:8080/requestdemo/api/user/update1")
//put或delete
.put(RequestBody.create(MediaType.parse("application/json"),json))
.build()
val call = client.newCall(request)
call.enqueue(object :Callback{
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
println(response.body()?.string())
}
})
ajax請求轉代碼(補充)
如有下麵的ajax代碼:
var sg = 'UDZRb1loVWQFDAI9BTVcYFc6ADRTNQo8UWBQY1I5ASYBdVU_aXTEAYQdpBGEGagI2Vj4HO1Q7VmI_c';
$.ajax({
type : 'post',
url : '/ajaxm.php',
data : { 'action':'downprocess','sign':sg,'ves':1 },
dataType : 'json',
success:function(msg){
var date = msg;
...
在postwoman應該這樣進行請求:
Jsoup代碼:
//我這裡不加頭部,也可以獲取到數據
val postUrl = "https://www.lanzous.com/ajaxm.php"
val params = LinkedHashMap<String, String>()
params["action"] = "downprocess"
params["sign"] = sign
params["ves"] = "1"
val result = Jsoup.connect(postUrl)
.data(params)
.post()
.html()
參考
post frombody
SpringBoot 出現 Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
OKHTTP3 簡單使用(三) POST方法