Java使用HttpsURLConnection调用FCM接口返回401错误如何解决?
FCM Java请求401错误排查方案
核心问题定位
你遇到的401错误和代码逻辑本身无关,是两个隐性问题导致的:
- 多余请求头干扰:你抓取的请求报文中存在非FCM标准的
token_access自定义头,该头是你项目全局HTTP拦截器自动注入的,FCM服务端会拒绝携带非标准鉴权头的请求,Postman请求未携带该头因此可以正常执行。 - 请求执行顺序错误:
HttpsURLConnection的connect()方法调用时机错误,你在写完请求体之后才调用connect()建立连接,会导致部分请求头参数未被正确发送到服务端。 - 隐性拼接问题:部分开发者会在
key=和Server Key之间不小心加入空格,导致鉴权信息格式错误,你可以额外检查这一点。
修复后代码参考
String url = "https://fcm.googleapis.com/fcm/send"; URL obj = new URL(url); HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); // 先配置所有请求参数和头 con.setRequestMethod("POST"); // 确保key和ServerKey之间没有多余空格 con.setRequestProperty("Authorization", "key=" + "<Server-Key>".trim()); con.setRequestProperty("Content-Type", "application/json"); con.setRequestProperty("Accept", "application/json"); con.setAllowUserInteraction(false); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); // 提前建立连接 con.connect(); // 构造请求JSON JSONObject infoJson = new JSONObject(); infoJson.put("title", title); infoJson.put("body", notificationMsg); JSONObject infoJson2 = new JSONObject(); infoJson2.put("userId", userId); infoJson2.put("title",title); infoJson2.put("body", notificationMsg); infoJson2.put("notificationType", notificationType); infoJson2.put("badge", String.valueOf(unreadNotificationCount)); JSONObject json = new JSONObject(); json.put("to",clientDeviceToken.trim()); json.put("priority","high"); json.put("content_available",true); json.put("notification", infoJson); json.put("data", infoJson2); // 发送请求体 OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream()); wr.write(json.toString()); wr.flush(); wr.close(); int status = con.getResponseCode(); if( status == 200 ){ BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream())); System.out.println("Android Notification Response : " + reader.readLine()); reader.close(); }else if(status == 401){ System.out.println("Notification Response : TokenId : " + clientDeviceToken + " Error occurred :"); }else if(status == 501){ System.out.println("Notification Response : [ errorCode=ServerError ] TokenId : " + clientDeviceToken); }else if( status == 503){ System.out.println("Notification Response : FCM Service is Unavailable TokenId : " + clientDeviceToken); } con.disconnect();
额外验证步骤
你可以在调用con.connect()之前,加一行代码移除多余的token_access头,避免全局拦截器的干扰:
con.setRequestProperty("token_access", null);
如果还是有问题,可以直接打印con.getRequestProperties(),确认最终发送的请求头里没有多余字段,且Authorization头格式完全正确。
内容的提问来源于stack exchange,提问作者hanish basheer
相关产品推荐
相关产品推荐

