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

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匹配。

  • 调整请求头配置

    1. 将Content-Type头改为标准的application/json(去掉; utf-8后缀);
    2. 手动添加Host请求头,确保请求被正确路由:
      conn.setRequestProperty("Host", "exp.host");
      
  • 验证请求体的实际发送内容
    如果上述方法无效,可以通过抓包工具(如Wireshark、Fiddler)查看Java代码发送的实际请求体,对比curl发送的内容,排查是否存在隐藏的格式差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:59:54