Bukkit插件Java类未发送GET请求问题排查求助
问题排查与解决方案
核心问题排查与修复
1. 事件监听器未注册
你的InventorySync类实现了Listener接口,但未在插件启动时注册事件监听器——Bukkit不会自动识别并注册实现了Listener的类,必须手动完成注册。
修复代码:在InventorySync类中添加插件启用方法:
@Override public void onEnable() { getServer().getPluginManager().registerEvents(this, this); getLogger().info("InventorySync 插件已启用,事件监听器完成注册"); }
2. 主线程执行网络请求导致中断
Bukkit的PlayerQuitEvent事件在服务器主线程处理,同步网络请求会阻塞主线程,甚至被Bukkit的 watchdog 机制强制中断,导致请求未完成。
修复代码:改用异步任务执行网络请求:
修改onQuit方法:
@EventHandler public void onQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); UUID uuid = player.getUniqueId(); Object[] contents = Arrays.stream(player.getInventory().getContents()).toArray(); String inv = Base64.getEncoder().encodeToString(gson.toJson(contents).getBytes()); // 对Base64内容做URL编码,避免特殊字符解析错误 String encodedInv = URLEncoder.encode(inv, StandardCharsets.UTF_8); String requestUrl = saveInv + "?username=" + uuid.toString() + "&inventory=" + encodedInv; // 异步执行请求 new BukkitRunnable() { @Override public void run() { try { String response = InventoryGet.main(requestUrl); getLogger().info("物品栏保存请求响应:" + response); } catch (IOException e) { getLogger().severe("保存物品栏失败:" + e.getMessage()); e.printStackTrace(); } } }.runTaskAsynchronously(this); }
3. GET请求URL长度超限
物品栏转Base64后数据量可能很大,超过HTTP GET请求的URL长度限制(通常2KB-8KB),导致请求无法发送。
修复方案:改用POST请求传递数据
- 修改
InventoryGet类,添加POST请求方法:
public static String sendPost(String urlString, String postData) throws IOException { URL url = new URL(urlString); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); try (OutputStream os = connection.getOutputStream()) { byte[] input = postData.getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { Scanner scanner = new Scanner(connection.getInputStream()); String response = scanner.useDelimiter("\\A").next(); scanner.close(); return response; } else { return "POST请求失败,响应码:" + responseCode; } }
- 修改PHP保存脚本,兼容GET/POST参数:
<?php $username = isset($_REQUEST['username']) ? $_REQUEST['username'] : null; $inventory = isset($_REQUEST['inventory']) ? $_REQUEST['inventory'] : null; if (!$username || !$inventory) { die(); } $inventory = base64_decode($inventory); // 确保inventory目录存在且有写入权限 if (!is_dir('inventory')) { mkdir('inventory', 0755, true); } file_put_contents('inventory/' . $username . '.inv', $inventory);
- 在异步任务中调用POST方法:
String postData = "username=" + uuid.toString() + "&inventory=" + encodedInv; String response = InventoryGet.sendPost(saveInv, postData);
额外优化点
- 强制检查PHP的
inventory目录是否存在并拥有写入权限,避免脚本静默失败 - 添加日志输出,方便追踪请求执行状态和错误信息
内容的提问来源于stack exchange,提问作者Final Craft
相关产品推荐
相关产品推荐

