无框架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可添加依赖:
若不想引入依赖,可手动解析JSON字符串,或使用JDK内置的<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20230618</version> </dependency>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
相关产品推荐
相关产品推荐

