2016-01-19 4 views
0

Я использую библиотеку Google Http Client (1.20) в Google App Engine (1.9.30), чтобы отправить запрос POST на серверы облачных сообщений (GCM) Google. Вот код:Почему вывод JsonHttpContent пуст?

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 класс (с использованием Ломбок для создания методов получения и установки):

@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; 
    } 
} 

Непосредственная цель состоит в том, чтобы создать тот же ответ, как (от Checking the validity of an API key):

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); 
} 

Все оцененная помощь.

ответ

2

Обнаружена проблема: это способ JacksonFactory().createJsonGenerator().searialize() работает (я ожидал, что он сериализует путь ObjectMapper сериализует). Это код для JsonHttpContent.writeTo() (от JsonHttpContent.java in google-http-java-client):

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

Джексон JsonGenerator ожидает ключ-значение спаривания (представленное в Java, как Map), который не является очевидным из конструктора подписи JsonHttpContent конструктора: JsonHttpContent(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) конструктор Map<String, Object> в качестве второго параметра, и все будет работать, как вы ожидаете.

2

Вы должны аннотировать поля POJO с @Key:

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

// ... 

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

// ... 

 Смежные вопросы

  • Нет связанных вопросов^_^