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

Android调用ejabberd REST API发消息报错:POSTMAN正常OKHTTP异常

问题诊断与解决方案

我帮你分析了下你的ejabberd配置和Android代码,发现几个关键问题导致调用失败,逐个给你说清楚怎么解决:

1. 协议不匹配:HTTP vs HTTPS

你的ejabberd配置里,5443端口明确开启了tls: true,这意味着这个端口只接受HTTPS请求,但你的Android代码里用的是http://192.168.1.24:5443/api/send_message,直接用HTTP访问HTTPS端口肯定会触发连接异常——Postman能正常工作应该是你手动改成了HTTPS但没注意到。

解决方法:把请求URL改成https://192.168.1.24:5443/api/send_message

2. 请求体格式与Content-Type不匹配

你代码里设置了content-type: application/json,但用的是FormBody(这对应application/x-www-form-urlencoded格式),ejabberd的REST API要求JSON格式的请求体,服务器无法解析这种不匹配的请求,会直接断开连接。

解决方法:改用JSON字符串作为请求体,示例代码如下:

String jsonBody = "{\n" +
        "  \"type\": \"normal\",\n" +
        "  \"from\": \"admin@faiqkhan-VirtualBox\",\n" +
        "  \"to\": \"faiq@faiqkhan-VirtualBox\",\n" +
        "  \"subject\": \"\",\n" +
        "  \"body\": \"In 5 minutes\"\n" +
        "}";

RequestBody requestBody = RequestBody.create(
        jsonBody,
        MediaType.parse("application/json; charset=utf-8")
);

3. 缺少API认证信息

ejabberd的mod_http_api需要认证才能调用,Postman里你应该是配置了Basic Auth或者OAuth凭证,但Android代码里完全没加认证头,服务器会直接拒绝请求,导致连接异常。

解决方法:添加Basic认证头,替换成你的管理员账号和密码:

String credentials = "admin@faiqkhan-VirtualBox:你的管理员密码";
String base64Credentials = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
String authHeader = "Basic " + base64Credentials;

// 在Request.Builder中添加这个头
.addHeader("Authorization", authHeader)

4. 忽略自签名证书(测试环境专属)

因为你用的是自己生成的server.pem证书,Android默认会不信任这类自签名证书,导致SSL握手失败。测试环境下可以临时忽略证书验证(生产环境绝对不要这么做,应该导入合法证书):

// 构建OkHttpClient时添加证书忽略逻辑
OkHttpClient client = new OkHttpClient.Builder()
        .sslSocketFactory(createInsecureSSLSocketFactory(), createTrustAllManager())
        .hostnameVerifier((hostname, session) -> true)
        .build();

// 辅助方法:创建不安全的SSL工厂
private SSLSocketFactory createInsecureSSLSocketFactory() {
    try {
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, new TrustManager[]{createTrustAllManager()}, new SecureRandom());
        return sslContext.getSocketFactory();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

// 辅助方法:信任所有证书的管理器
private X509TrustManager createTrustAllManager() {
    return new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {}
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {}
        @Override
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
    };
}

整理后的完整代码片段

OkHttpClient client = new OkHttpClient.Builder()
        .sslSocketFactory(createInsecureSSLSocketFactory(), createTrustAllManager())
        .hostnameVerifier((hostname, session) -> true)
        .build();

String jsonBody = "{\n" +
        "  \"type\": \"normal\",\n" +
        "  \"from\": \"admin@faiqkhan-VirtualBox\",\n" +
        "  \"to\": \"faiq@faiqkhan-VirtualBox\",\n" +
        "  \"subject\": \"\",\n" +
        "  \"body\": \"In 5 minutes\"\n" +
        "}";

RequestBody requestBody = RequestBody.create(
        jsonBody,
        MediaType.parse("application/json; charset=utf-8")
);

String credentials = "admin@faiqkhan-VirtualBox:你的管理员密码";
String base64Credentials = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
String authHeader = "Basic " + base64Credentials;

Request request = new Request.Builder()
        .url("https://192.168.1.24:5443/api/send_message")
        .addHeader("content-type", "application/json")
        .addHeader("Authorization", authHeader)
        .post(requestBody)
        .build();

try {
    Response response = client.newCall(request).execute();
    // 这里可以添加响应处理逻辑,比如打印response.body().string()
} catch (IOException e) {
    e.printStackTrace();
}

// 别忘了添加这两个辅助方法
private SSLSocketFactory createInsecureSSLSocketFactory() {
    try {
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, new TrustManager[]{createTrustAllManager()}, new SecureRandom());
        return sslContext.getSocketFactory();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private X509TrustManager createTrustAllManager() {
    return new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {}
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {}
        @Override
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
    };
}

另外补充一下:你的api_permissions配置已经允许管理员和本地环回地址调用所有API,只要认证信息正确,权限方面是没问题的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:18:12