3.19
本文将基于前两篇的后端接口,开发 Android 客户端界面,并通过 Retrofit 实现与 Spring Boot 后端的通信。
一、定义数据模型
在 Android 项目中创建User.java类,与后端实体类对应:
java
package com.demo.model;
import com.google.gson.annotations.SerializedName;
public class User {
private Long id;
private String username;
@SerializedName("email")
private String email;
// 省略密码字段(客户端通常不存储密码)
private String createTime;
// 构造方法、getter和setter省略
public User() {}
// ...
}
二、配置 Retrofit 网络请求
创建ApiService.java接口定义 API:
java
package com.demo.api;
import com.demo.model.User;
import com.demo.response.ApiResponse;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;
public interface ApiService {
@POST("api/user/register")
Call<ApiResponse
@POST("api/user/login")
Call<ApiResponse<User>> login(
@Query("username") String username,
@Query("password") String password
);
@GET("api/user/{id}")
Call<ApiResponse<User>> getUser(@Path("id") Long id);
// 其他接口省略
// ...
}
创建RetrofitClient.java初始化 Retrofit:
java
package com.demo.util;
import com.demo.api.ApiService;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static final String BASE_URL = "http://192.168.1.100:8080/"; // 替换为实际IP
private static Retrofit retrofit;
private static ApiService apiService;
public static ApiService getApiService() {
if (apiService == null) {
apiService = getRetrofitInstance().create(ApiService.class);
}
return apiService;
}
private static Retrofit getRetrofitInstance() {
if (retrofit == null) {
// 日志拦截器
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
// OkHttpClient配置
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.addInterceptor(interceptor)
.build();
// 初始化Retrofit
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
三、开发登录界面
登录界面布局activity_login.xml:
xml
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名"
android:padding="10dp"
android:layout_marginBottom="15dp"/>
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:inputType="textPassword"
android:padding="10dp"
android:layout_marginBottom="30dp"/>
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"
android:padding="15dp"
android:background="@android:color/holo_blue_dark"/>
登录界面逻辑LoginActivity.java:
java
package com.demo.activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.demo.api.ApiService;
import com.demo.model.User;
import com.demo.util.RetrofitClient;
import com.demo.response.ApiResponse;
import com.example.demoapp.R;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class LoginActivity extends AppCompatActivity {
private EditText etUsername, etPassword;
private Button btnLogin;
private ApiService apiService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initViews();
initApi();
setupListener();
}
private void initViews() {
etUsername = findViewById(R.id.et_username);
etPassword = findViewById(R.id.et_password);
btnLogin = findViewById(R.id.btn_login);
}
private void initApi() {
apiService = RetrofitClient.getApiService();
}
private void setupListener() {
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = etUsername.getText().toString().trim();
String password = etPassword.getText().toString().trim();
if (username.isEmpty() || password.isEmpty()) {
Toast.makeText(LoginActivity.this, "请输入用户名和密码", Toast.LENGTH_SHORT).show();
return;
}
// 调用登录API
apiService.login(username, password).enqueue(new Callback<ApiResponse<User>>() {
@Override
public void onResponse(Call<ApiResponse<User>> call, Response<ApiResponse<User>> response) {
if (response.isSuccessful() && response.body() != null && response.body().isSuccess()) {
User user = response.body().getData();
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
// 跳转到主页
// startActivity(new Intent(LoginActivity.this, MainActivity.class));
} else {
Toast.makeText(LoginActivity.this, "登录失败,请检查账号密码", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ApiResponse<User>> call, Throwable t) {
Toast.makeText(LoginActivity.this, "网络错误:" + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
总结
Android 客户端已实现与 Spring Boot 后端的通信,下一篇将介绍项目的部署、测试及优化方案。

浙公网安备 33010602011771号