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

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请求传递数据

  1. 修改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;
    }
}
  1. 修改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);
  1. 在异步任务中调用POST方法:
String postData = "username=" + uuid.toString() + "&inventory=" + encodedInv;
String response = InventoryGet.sendPost(saveInv, postData);

额外优化点

  • 强制检查PHP的inventory目录是否存在并拥有写入权限,避免脚本静默失败
  • 添加日志输出,方便追踪请求执行状态和错误信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:11:05