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> register(@Body User user);

@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 后端的通信,下一篇将介绍项目的部署、测试及优化方案。

posted @ 2025-03-19 21:52  李蕊lr  阅读(7)  评论(0)    收藏  举报