Java服务端调用Expo Push Notification API报错:缺少to字段
Expo Push Notification Java请求400错误("to" is required)解决建议
问题背景
为React Native(iOS/Android双端)应用集成Expo Push Notification功能时,使用Expo推送工具及curl命令均可正常发送并接收远程推送,但通过Java Web应用发送时返回400错误,提示"to" is required。
正常工作的curl命令
curl -X POST https://exp.host/--/api/v2/push/send \ -H "Content-Type: application/json" \ -d '{ "to": "ExponentPushToken[**********************]", "sound": "default", "title": "Title", "body": "Body" }'
出现问题的Java代码
try { for(DevicePushNotification devicePushNotification : expoList) { URL url = new URL("https://exp.host/--/api/v2/push/send"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json; utf-8"); conn.setRequestProperty("Accept", "application/json"); conn.setDoOutput(true); String jsonInputString = "{" + "\"to\": \"" + devicePushNotification.getToken() + "\"," + "\"sound\": \"default\"," + "\"title\": \"EasyTeleMed HOME\"," + "\"body\": \"Test\"" + "}"; logger.info("Request --> " + jsonInputString); try (OutputStream os = conn.getOutputStream()) { byte[] input = jsonInputString.getBytes("utf-8"); os.write(input, 0, input.length); } int responseCode = conn.getResponseCode(); logger.info("Response Code --> " + responseCode); BufferedReader in; if (responseCode >= 200 && responseCode < 300) { in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); } else { in = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "utf-8")); } String inputLine; StringBuilder resp = new StringBuilder(); while ((inputLine = in.readLine()) != null) { resp.append(inputLine); } in.close(); // Mostra il messaggio di risposta logger.info("Response Message --> " + resp.toString()); conn.disconnect(); } } catch (Exception e) { logger.error("Error during sending Expo push notification --> " + e.getMessage()); }
服务器日志
Request --> {"to": "ExponentPushToken[**********************]","sound": "default","title": "EasyTeleMed HOME","body": "Test"}
Response Code --> 400 Response Message --> {"errors":[{"code":"VALIDATION_ERROR","message":"\"to\" is required.","isTransient":false,"requestId":"ff054b5c-d0d6-4bbd-9742-c8bd3a299e2d"}]}
解决建议
避免手动拼接JSON,改用JSON库生成
手动拼接字符串极易出现格式错误(比如多余空格、特殊字符未转义),推荐使用Jackson或Gson等JSON库构建请求体,确保格式绝对正确。示例代码(Jackson):ObjectMapper mapper = new ObjectMapper(); Map<String, Object> pushPayload = new HashMap<>(); pushPayload.put("to", devicePushNotification.getToken()); pushPayload.put("sound", "default"); pushPayload.put("title", "EasyTeleMed HOME"); pushPayload.put("body", "Test"); String jsonInputString = mapper.writeValueAsString(pushPayload);检查Token的有效性与格式
确认devicePushNotification.getToken()返回的字符串和curl中使用的Token完全一致,无多余空格、换行或截断。可以在日志中打印Token的原始值(不带JSON包裹),对比是否与curl中的Token匹配。调整请求头配置
- 将
Content-Type头改为标准的application/json(去掉; utf-8后缀); - 手动添加
Host请求头,确保请求被正确路由:conn.setRequestProperty("Host", "exp.host");
- 将
验证请求体的实际发送内容
如果上述方法无效,可以通过抓包工具(如Wireshark、Fiddler)查看Java代码发送的实际请求体,对比curl发送的内容,排查是否存在隐藏的格式差异。
内容的提问来源于stack exchange,提问作者Lubron
相关产品推荐
相关产品推荐

