2

Google App Engine (1.9.30) で Google Http クライアント ライブラリ (1.20) を使用して、POST リクエストを Google Cloud Messaging (GCM) サーバーに送信しています。コードは次のとおりです。

public static HttpRequestFactory getGcmRequestFactory() {
    if (null == gcmFactory) {
        gcmFactory = (new UrlFetchTransport())
                .createRequestFactory(new HttpRequestInitializer() {
                    @Override
                    public void initialize(HttpRequest request) throws IOException {
                        request.getHeaders().setAuthorization(
                                "key=" + Config.get(Config.Keys.GCM_SERVER_API_KEY).orNull());
                        request.getHeaders().setContentType("application/json");
                        request.getHeaders().setAcceptEncoding(null);
                    }
                });
    }
    return gcmFactory;
}

public static JsonFactory getJsonFactory() {
    return jacksonFactory;
}

public static String sendGcmMessage(GcmDownstreamDto message) {
    HttpRequestFactory factory = getGcmRequestFactory();
    JsonHttpContent content = new JsonHttpContent(getJsonFactory(), message);
    String response = EMPTY;
    try {
        HttpRequest req = factory.buildPostRequest(gcmDownstreamUrl, content);
        log.info("req headers = " + req.getHeaders());
        System.out.print("req content = ");
        content.writeTo(System.out); // prints out "{}"
        System.out.println(EMPTY);
        HttpResponse res = req.execute(); // IOException here
        response = IOUtils.toString(res.getContent());
    } catch (IOException e) {
        log.log(Level.WARNING, "IOException...", e);
    }
    return response;
}

これで、content.writeTo()常に空の JSON が出力されます。何故ですか?私は何を間違っていますか?GcmDownstreamDtoクラス (Lombok を使用してゲッターとセッターを生成) :

@Data
@Accessors(chain = true)
public class GcmDownstreamDto {

    private String to;

    private Object data;

    private List<String> registration_ids;

    private GcmNotificationDto notification;

    public GcmDownstreamDto addRegistrationId(String regId) {
        if (null == this.registration_ids) {
            this.registration_ids = new ArrayList<>();
        }
        if (isNotBlank(regId)) {
            this.registration_ids.add(regId);
        }
        return this;
    }
}

当面の目標は、( API キーの有効性を確認するから) と同じ応答を生成することです。

api_key=YOUR_API_KEY

curl --header "Authorization: key=$api_key" \
       --header Content-Type:"application/json" \
       https://gcm-http.googleapis.com/gcm/send \
       -d "{\"registration_ids\":[\"ABC\"]}"

{"multicast_id":6782339717028231855,"success":0,"failure":1,
"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}

私はすでに使用してテストしcurlたので、API キーが有効であることはわかっています。基本クラスを構築するために Java コードで同じことをしたいだけです。

sendGcmMessage()次のように呼び出されます。

@Test
public void testGcmDownstreamMessage() {
    GcmDownstreamDto message = new GcmDownstreamDto().addRegistrationId("ABC");
    System.out.println("message = " + message);
    String response = NetCall.sendGcmMessage(message);
    System.out.println("Response: " + response);
}

すべての助けに感謝します。

4

2 に答える 2

4

@KeyPOJO フィールドに次の注釈を付ける必要があります。

import com.google.api.client.util.Key;

// ...

@Key private String to;
@Key private Object data;
@Key private List<String> registration_ids;

// ...
于 2016-08-16T13:51:02.640 に答える
3

問題が見つかりました:それは機能する方法JacksonFactory().createJsonGenerator().searialize()です(シリアル化する方法でシリアル化することを期待していましたObjectMapper)。これは( google-http-java-client の JsonHttpContent.javaJsonHttpContent.writeTo()から) のコードです。

public void writeTo(OutputStream out) throws IOException {
    JsonGenerator generator = jsonFactory.createJsonGenerator(out, getCharset());
    generator.serialize(data);
    generator.flush();
}

Jacksonは、コンストラクターのコンストラクター シグネチャからは明らかでないJsonGeneratorキーと値のペアリング (Java では として表される) を想定しています: 。MapJsonHttpContentJsonHttpContent(JsonFactory, Object)

したがって、GcmDownstreamDto(質問で定義されているように、これはで機能するものですObjectMapper)を渡す代わりに、次のことを行う必要がありました。

Map<String, Object> map = new HashMap<>();
List<String> idList = Arrays.asList("ABC");
map.put("registration_ids", idList);

すべてが期待どおりに機能し、出力は次のようになります。

{"registration_ids":["ABC"]}

JsonHttpContent(JsonFactory, Object)したがって、コンストラクター aを 2 番目のパラメーターとして渡すことを忘れないでMap<String, Object>ください。そうすれば、すべてが期待どおりに機能します。

于 2016-01-19T09:49:00.617 に答える