-
Android 客户端:
(图片来源网络,侵删)- 语言: Kotlin (这是目前 Android 开发的首选语言)
- 网络库: Retrofit 2 + OkHttp (非常流行且强大的网络请求库)
- JSON 解析: Gson (Retrofit 内置支持)
- 架构: MVVM (Model-View-ViewModel) + Kotlin Coroutines (用于处理异步网络请求)
-
Java 服务器:
- 语言: Java
- 框架: Spring Boot (极大地简化了 Java Web 应用的开发)
- 网络: 内嵌 Tomcat
- JSON 解析: Jackson (Spring Boot 默认使用)
- 数据库: H2 内存数据库 (无需安装,方便演示)
第 1 步:项目结构
我们需要创建两个独立的项目:
android-client: Android Studio 项目java-server: Spring Boot 项目 (可以使用 Spring Initializr 在线生成)
第 2 步:Java 服务器端源码
服务器将提供两个 REST API 端点:
POST /api/register: 接收用户名和密码,注册用户。POST /api/login: 接收用户名和密码,验证用户。
pom.xml (Maven 依赖文件)
确保你的 pom.xml 包含以下依赖:

<dependencies>
<!-- Spring Boot Starter Web: 提供了构建 Web 应用(包括 RESTful 应用)的一切 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA: 用于简化数据库访问 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database: 一个内存数据库,非常适合开发和测试 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok: 减少样板代码 (getters, setters, constructors) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
主应用类
src/main/java/com/example/demo/DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
数据模型
src/main/java/com/example/demo/model/User.java
package com.example.demo.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity // 告诉 JPA 这是一个需要映射到数据库的实体
@Data // Lombok: 自动生成 getter, setter, toString 等
@NoArgsConstructor // Lombok: 自动生成无参构造函数
public class User {
@Id // 主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键
private Long id;
private String username;
private String password; // 实际项目中密码必须加密存储!
}
数据访问层
src/main/java/com/example/demo/repository/UserRepository.java
package com.example.demo.repository;
import com.example.demo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Spring Data JPA 会根据方法名自动实现查询
Optional<User> findByUsername(String username);
}
请求/响应 DTO (Data Transfer Object)
src/main/java/com/example/demo/dto/RegisterRequest.java

package com.example.demo.dto;
import lombok.Data;
@Data
public class RegisterRequest {
private String username;
private String password;
}
src/main/java/com/example/demo/dto/LoginRequest.java
package com.example.demo.dto;
import lombok.Data;
@Data
public class LoginRequest {
private String username;
private String password;
}
src/main/java/com/example/demo/dto/ApiResponse.java
package com.example.demo.dto;
import lombok.Data;
@Data
public class ApiResponse {
private boolean success;
private String message;
public ApiResponse(boolean success, String message) {
this.success = success;
this.message = message;
}
}
控制器
src/main/java/com/example/demo/controller/AuthController.java
package com.example.demo.controller;
import com.example.demo.dto.ApiResponse;
import com.example.demo.dto.LoginRequest;
import com.example.demo.dto.RegisterRequest;
import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class AuthController {
@Autowired
private UserRepository userRepository;
@PostMapping("/register")
public ResponseEntity<ApiResponse> register(@RequestBody RegisterRequest request) {
// 检查用户名是否已存在
if (userRepository.findByUsername(request.getUsername()).isPresent()) {
return ResponseEntity.badRequest().body(new ApiResponse(false, "Username is already taken!"));
}
// 创建新用户
User user = new User();
user.setUsername(request.getUsername());
user.setPassword(request.getPassword()); // 实际项目应加密!
userRepository.save(user);
return ResponseEntity.ok(new ApiResponse(true, "User registered successfully!"));
}
@PostMapping("/login")
public ResponseEntity<ApiResponse> login(@RequestBody LoginRequest request) {
// 查找用户
userRepository.findByUsername(request.getUsername()).ifPresentOrElse(
user -> {
// 验证密码 (实际项目应比较加密后的密码)
if (user.getPassword().equals(request.getPassword())) {
System.out.println("Login successful for user: " + user.getUsername());
} else {
System.out.println("Login failed: Incorrect password for user: " + user.getUsername());
}
},
() -> {
System.out.println("Login failed: User not found: " + request.getUsername());
}
);
// 为了简化,这里只返回一个通用成功/失败消息
// 实际项目中,登录成功后应该生成并返回一个 Token (如 JWT)
if (userRepository.findByUsername(request.getUsername()).isPresent() &&
userRepository.findByUsername(request.getUsername()).get().getPassword().equals(request.getPassword())) {
return ResponseEntity.ok(new ApiResponse(true, "Login successful!"));
} else {
return ResponseEntity.badRequest().body(new ApiResponse(false, "Invalid username or password!"));
}
}
}
启动并测试服务器
-
运行
DemoApplication.java的main方法。 -
服务器将在
http://localhost:8080启动。 -
使用 Postman 或 curl 测试 API:
-
注册:
curl -X POST http://localhost:8080/api/register \ -H "Content-Type: application/json" \ -d '{"username": "testuser", "password": "password123"}'预期响应:
{"success":true,"message":"User registered successfully!"} -
登录:
curl -X POST http://localhost:8080/api/login \ -H "Content-Type: application/json" \ -d '{"username": "testuser", "password": "password123"}'预期响应:
{"success":true,"message":"Login successful!"}
-
第 3 步:Android 客户端源码
添加依赖
在 app/build.gradle.kts (或 app/build.gradle) 文件中添加:
// build.gradle.kts
dependencies {
// ... 其他依赖
// Retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0") // JSON 转换器
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0") // OkHttp 日志拦截器
// ViewModel & LiveData
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.activity:activity-ktx:1.8.1") // by viewModels
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1 