You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无框架Java实现接收Kotlin应用请求的Endpoint指导需求

无框架Java HTTP同步端点实现方案

核心说明

你提到的java.net.URL是用于发起HTTP请求的工具,要接收请求,推荐使用JDK内置的com.sun.net.httpserver.HttpServer(无需额外框架依赖),以下是完整实现步骤:


1. 搭建基础HTTP服务器

创建服务器实例,绑定端口并注册请求处理上下文:

import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

public class SyncEndpointServer {
    public static void main(String[] args) throws IOException {
        // 绑定8080端口,最大等待请求队列10
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 10);
        // 注册/sync路径的请求处理器
        server.createContext("/sync", new SyncRequestHandler());
        // 用线程池处理并发请求
        server.setExecutor(Executors.newFixedThreadPool(5));
        server.start();
        System.out.println("同步端点已启动,监听端口8080");
    }
}

2. 实现GET/POST请求处理器

编写SyncRequestHandler处理请求解析、业务逻辑和响应返回:

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class SyncRequestHandler implements HttpHandler {
    @Override
    public void handle(HttpExchange exchange) throws IOException {
        String method = exchange.getRequestMethod();
        String response = "";
        int statusCode = 200;

        try {
            switch (method.toUpperCase()) {
                case "GET":
                    // 处理拉取中心库最新数据的请求
                    Map<String, String> params = parseQueryParams(exchange.getRequestURI().getQuery());
                    String userId = params.get("userId");
                    if (userId == null || userId.isBlank()) {
                        statusCode = 400;
                        response = "{\"error\":\"缺少必要参数:userId\"}";
                    } else {
                        // 从中心库拉取用户最新数据
                        String latestData = CenterDBUtil.pullLatestUserData(userId);
                        response = latestData;
                    }
                    break;
                case "POST":
                    // 处理同步本地数据到中心库的请求
                    BufferedReader reader = new BufferedReader(
                            new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8)
                    );
                    StringBuilder requestBody = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) requestBody.append(line);
                    reader.close();

                    JSONObject requestJson = new JSONObject(requestBody.toString());
                    String postUserId = requestJson.getString("userId");
                    String userData = requestJson.getString("data");

                    // 同步到中心数据库
                    CenterDBUtil.syncToCenterDB(postUserId, userData);
                    // 返回中心库最新数据,供客户端更新本地SQLite
                    response = CenterDBUtil.pullLatestUserData(postUserId);
                    break;
                default:
                    statusCode = 405;
                    response = "{\"error\":\"不支持的请求方法:" + method + "\"}";
            }
        } catch (Exception e) {
            statusCode = 500;
            response = "{\"error\":\"服务器内部错误:" + e.getMessage() + "\"}";
            e.printStackTrace();
        }

        // 发送响应
        exchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8");
        exchange.sendResponseHeaders(statusCode, response.getBytes(StandardCharsets.UTF_8).length);
        OutputStream os = exchange.getResponseBody();
        os.write(response.getBytes(StandardCharsets.UTF_8));
        os.close();
    }

    // 解析GET请求的URL查询参数
    private Map<String, String> parseQueryParams(String query) {
        Map<String, String> params = new HashMap<>();
        if (query == null) return params;
        for (String pair : query.split("&")) {
            int idx = pair.indexOf("=");
            if (idx > 0) {
                params.put(pair.substring(0, idx), pair.substring(idx + 1));
            }
        }
        return params;
    }
}

3. 中心数据库同步逻辑

实现与Laravel所用中心数据库(以MySQL为例)的交互:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class CenterDBUtil {
    // 替换为你的Laravel数据库配置
    private static final String DB_URL = "jdbc:mysql://localhost:3306/laravel_db";
    private static final String DB_USER = "root";
    private static final String DB_PASS = "your_db_password";

    // 将客户端数据同步到中心库(存在则更新,不存在则插入)
    public static void syncToCenterDB(String userId, String userData) throws SQLException {
        String sql = "INSERT INTO user_data (user_id, data, updated_at) VALUES (?, ?, NOW()) " +
                     "ON DUPLICATE KEY UPDATE data = ?, updated_at = NOW()";
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, userId);
            pstmt.setString(2, userData);
            pstmt.setString(3, userData);
            pstmt.executeUpdate();
        }
    }

    // 从中心库拉取用户最新数据
    public static String pullLatestUserData(String userId) throws SQLException {
        String sql = "SELECT data FROM user_data WHERE user_id = ? ORDER BY updated_at DESC LIMIT 1";
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, userId);
            ResultSet rs = pstmt.executeQuery();
            return rs.next() ? rs.getString("data") : "{}";
        }
    }
}

关键注意事项

  • JSON解析依赖:上述代码使用org.json库解析JSON,若用Maven可添加依赖:
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20230618</version>
    </dependency>
    
    若不想引入依赖,可手动解析JSON字符串,或使用JDK内置的javax.json(部分JDK版本需额外依赖)。
  • 部署与端口:服务器部署时需确保绑定的端口(如8080)对外开放,防火墙允许外部访问。
  • 并发处理:使用线程池处理请求,避免单线程阻塞导致无法响应新请求。
  • Kotlin客户端适配:Kotlin端发送请求时,GET请求需携带userId查询参数,POST请求需发送JSON格式的请求体,示例Kotlin代码:
    // Kotlin发送POST同步请求
    val url = URL("http://your-server-ip:8080/sync")
    val conn = url.openConnection() as HttpURLConnection
    conn.requestMethod = "POST"
    conn.setRequestProperty("Content-Type", "application/json; charset=utf-8")
    conn.doOutput = true
    
    val jsonBody = """{"userId":"123","data":"{\"name\":\"John\",\"email\":\"john@example.com\"}"}"""
    conn.outputStream.write(jsonBody.toByteArray(Charsets.UTF_8))
    conn.outputStream.flush()
    
    // 读取响应并更新本地SQLite
    val response = BufferedReader(InputStreamReader(conn.inputStream)).readText()
    // 更新本地SQLite逻辑...
    

备选方案:原生ServerSocket实现

若无法使用HttpServer,可手动用ServerSocket监听端口,但需自行处理HTTP协议细节(不推荐):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class RawSyncServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true) {
            Socket clientSocket = serverSocket.accept();
            new Thread(() -> handleClient(clientSocket)).start();
        }
    }

    private static void handleClient(Socket clientSocket) {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
             OutputStream out = clientSocket.getOutputStream()) {
            // 读取请求行
            String requestLine = in.readLine();
            if (requestLine == null) return;
            String[] parts = requestLine.split(" ");
            String method = parts[0];
            String path = parts[1];

            // 自行解析请求头、请求体,处理业务逻辑...

            // 发送响应
            String response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\"status\":\"success\"}";
            out.write(response.getBytes());
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者daviserraalonso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:40:33