凌峰创科服务平台

Android客户端与服务器源码如何实现通信?

  • Android 客户端:

    Android客户端与服务器源码如何实现通信?-图1
    (图片来源网络,侵删)
    • 语言: 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 步:项目结构

我们需要创建两个独立的项目:

  1. android-client: Android Studio 项目
  2. java-server: Spring Boot 项目 (可以使用 Spring Initializr 在线生成)

第 2 步:Java 服务器端源码

服务器将提供两个 REST API 端点:

  • POST /api/register: 接收用户名和密码,注册用户。
  • POST /api/login: 接收用户名和密码,验证用户。

pom.xml (Maven 依赖文件)

确保你的 pom.xml 包含以下依赖:

Android客户端与服务器源码如何实现通信?-图2
(图片来源网络,侵删)
<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

Android客户端与服务器源码如何实现通信?-图3
(图片来源网络,侵删)
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!"));
        }
    }
}

启动并测试服务器

  1. 运行 DemoApplication.javamain 方法。

  2. 服务器将在 http://localhost:8080 启动。

  3. 使用 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
分享:
扫描分享到社交APP
上一篇
下一篇