implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
<uses-permission android:name="android.permission.INTERNET" />
登入之前须要先有帐号,所以要先注册
提供注册的网址是https://k88d02.ml/api/register
因爲後端的注册请求方法是POST,发request须要带BODY的资料
格式爲formdata如下
建立interface包含一个register funtion
还有使用@FormUrlEncoded搭配各栏位@Field的annotation
private const val BASE_URL = "https://k88d02.ml/api/"
interface ApiService {
@Headers("Content-type: application/json","Accept: application/json")
@POST("register")
@FormUrlEncoded
fun register(
@Field("name") name: String,
@Field("password") password: String,
@Field("email") email: String
): Call<RegisterResponse>
}
object Api {
private val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
val retrofitService: ApiService = retrofit.create(ApiService::class.java)
}
服务器送回的response是JSON
所以建立一个data class RegisterResponse
data class RegisterResponse(
@SerializedName("success")
var isSuccess: Boolean = true,
@SerializedName("message")
var message: String = "",
@SerializedName("data")
var data: Nothing? = null
)
建议先测试连线是否正常,使用postman这个软件
Send发送
可获得response,表示连线正常
{
"success": false,
"message": "email已使用",
"data": null
}
接着就做一个登入页面,在程序呼叫api
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
btn_register.setOnClickListener {
hideKeyboard(textView, textView)
Api.retrofitService
.register(
ed_account.text.toString(),
ed_password.text.toString(),
ed_email.text.toString()
)
.enqueue(object : retrofit2.Callback<RegisterResponse> {
override fun onFailure(call: Call<RegisterResponse>, t: Throwable) {
Log.e("Failed", t.toString())
}
override fun onResponse(call: Call<RegisterResponse>, response: Response<RegisterResponse>) {
if (response.isSuccessful) { //request 200,注册成功
Toast.makeText(requireActivity(), response.body()?.message, Toast.LENGTH_SHORT).show()
Log.d("Success!", response.body().toString())
}else{ //request 400,注册失败
Toast.makeText(requireActivity(), response.body()?.message, Toast.LENGTH_SHORT).show()
Log.d("Success!", response.body().toString())
Toast.makeText(requireActivity(), "注册失败", Toast.LENGTH_SHORT).show()
}
}
})
}
}
密码栏位可以加一个属性,让输入隐藏
android:inputType="textPassword"
可以看到第一次显示注册失败,因爲密码只输入了4个
而服务器要求6-12个,改爲8个後就显示注册成功了
logcat
D/Success!: RegisterResponse(isSuccess=true, message=register success , please login, data=null)
这边有点搞错,原来是用email加password登入
所以我的版面栏位稍微改一下
一样是POST,要带的资料是formdata
所以interface加一个login funtion
interface ApiService {
// @Headers("Content-type: application/json","Accept: application/json")
@POST("register")
@FormUrlEncoded
fun register(
@Field("name") name: String,
@Field("password") password: String,
@Field("email") email: String
): Call<RegisterResponse>
@POST("login")
@FormUrlEncoded
fun login(
@Field("email") name: String,
@Field("password") password: String
): Call<LoginResponse>
}
服务器login获得的response
再建立一个data class LoginResponse
里面的rememberToken是每次登入成功时,会取得的一组token
data class LoginResponse(
@SerializedName("data")
val `data`: Data = Data(),
@SerializedName("message")
val message: String = "",
@SerializedName("success")
val success: Boolean = false // true
) {
data class Data(
@SerializedName("remember_token")
val rememberToken: String = "", // TeR5GEi4ftp4BtKqM65Q7LYB1R0dbeY5n22ZVCulgokPigme2UFOH12VEVol
@SerializedName("token_expire_time")
val tokenExpireTime: String = "", // 2020/09/19 23:10:13
@SerializedName("user_id")
val userId: Int = 0 // 3
)
}
先注册一组帐号[email protected] / 密码asdfasdf
并确认注册成功
D/Success!: RegisterResponse(isSuccess=true, message=register success , please login, data=null)
再按下登入,可以看到显示login的Toast有取得token
Toast.makeText(requireActivity(), response.body()?.data?.rememberToken, Toast.LENGTH_SHORT).show()
多按几次登入,每次拿到的token都会不一样
D/Success!: RegisterResponse(isSuccess=true, message=register success , please login, data=null)
D/Success!: LoginResponse(data=Data(rememberToken=Zs5H2xrUh7ZYIW95urGJvY2G4rozZbvtfwIqNdZ6oz1TlmLM93pyILKZUVSt, tokenExpireTime=2020/10/05 15:40:45, userId=36), message=, success=true)
D/Success!: LoginResponse(data=Data(rememberToken=yec7MPpzKUELbBOwLYge7CmDSXnrKlXUdmQGI0VEL2z4gpg7mnhMqFZzWb6t, tokenExpireTime=2020/10/05 15:40:52, userId=36), message=, success=true)
D/Success!: LoginResponse(data=Data(rememberToken=gRA8pwe33OStUjG0XbQEFQvzTtZpECW0mAh1oXmhcgOcSpo2Xuz7tojSsN4W, tokenExpireTime=2020/10/05 15:41:28, userId=36), message=, success=true)
感谢工作室与铁人赛,虽然30天还只是一个起点
但让我有养成学习後要记录的习惯,感觉能够更帮助吸收
期望能持续下去!
<<: [今晚我想来点 Express 佐 MVC 分层架构] DAY 30 - 是结束,也是开始
前言 由於前几天讲了capsule network,attention的笔记我还在制作,因此先来讲讲...
今天正式进入Canvas的世界了! 老样子先看成品: 今天来做点科技感的画面,橘色是滑鼠的游标,这个...
如果按照之前的教学到这一步,最基本的游戏架构已经产生了,大部分游戏都是先制作出基本架构,之後再延伸出...
您是否希望提高您的竞争地位? 应对外部威胁?识别新的机会或风险? 扩大您在新市场的影响力? 战略分...
今天要来讲介面型别的使用范例。 通常我们会使用介面来定义函式型别,程序码如下, interface ...