1

Lorsque vous essayez d'utiliser Firebase Cloud Messaging by Google avec l'aide de non-blocking Jetty HTTP client à a simple test case que j'ai préparé à GitHub -NPE lorsque vous essayez d'utiliser la jetée async HTTP client

private static final HttpClient sHttpClient = new HttpClient(); 
private static final Response.ContentListener sFcmListener = new Response.ContentListener() { 
    @Override 
    public void onContent(Response response, ByteBuffer content) { 
     if (response.getStatus() != 200) { 
      return; 
     } 

     String body = StandardCharsets.UTF_8.decode(content).toString(); 
     System.out.printf("onContent: %s\n", body); 
     Map<String, Object> resp = (Map<String, Object>) JSON.parse(body); 

     try { 
      Object[] results = (Object[]) resp.get(FCM_RESULTS); 
      Map result = (Map) results[0]; 
      String error = (String) result.get(FCM_ERROR); 
      if (FCM_NOT_REGISTERED.equals(error)) { 
       // TODO delete invalid FCM token from the database 
      } 
     } catch (Exception ignore) { 
     } 
    } 
}; 

public static void main(String[] args) throws Exception { 
    sHttpClient.start(); 
    sHttpClient.POST(FCM_URL) 
     .header(HttpHeader.AUTHORIZATION, FCM_KEY) 
     .header(HttpHeader.CONTENT_TYPE, "application/json") 
     .content(new StringContentProvider(JSON.toString(REQUEST))) 
     .onResponseContent(sFcmListener) 
     .send(); 
} 

mais malheureusement, l'exécution échoue immédiatement avec NPE:

2017-06-30 10:46:41.312:INFO::main: Logging initialized @168ms to org.eclipse.jetty.util.log.StdErrLog 
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NullPointerException 
    at org.eclipse.jetty.client.util.FutureResponseListener.getResult(FutureResponseListener.java:118) 
    at org.eclipse.jetty.client.util.FutureResponseListener.get(FutureResponseListener.java:101) 
    at org.eclipse.jetty.client.HttpRequest.send(HttpRequest.java:682) 
    at de.afarber.fcmnotregistered.Main.main(Main.java:68) 
Caused by: java.lang.NullPointerException 
    at org.eclipse.jetty.io.ssl.SslClientConnectionFactory.newConnection(SslClientConnectionFactory.java:59) 
    at org.eclipse.jetty.client.AbstractHttpClientTransport$ClientSelectorManager.newConnection(AbstractHttpClientTransport.java:191) 
    at org.eclipse.jetty.io.ManagedSelector.createEndPoint(ManagedSelector.java:420) 
    at org.eclipse.jetty.io.ManagedSelector.access$1600(ManagedSelector.java:61) 
    at org.eclipse.jetty.io.ManagedSelector$CreateEndPoint.run(ManagedSelector.java:599) 
    at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128) 
    at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222) 
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294) 
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:199) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590) 
    at java.lang.Thread.run(Thread.java:745) 

Pourquoi cela arrive-t-il s'il vous plaît?

MISE À JOUR:

je commencé à utiliser BufferingResponseListener et NPE disparu, mais maintenant le programme imprime java.net.NoRouteToHostException: No route to host même si the Google FCM endpoint est un hôte bien connu:

private static final HttpClient sHttpClient = new HttpClient(); 
private static final BufferingResponseListener sFcmListener = new BufferingResponseListener() { 
    @Override 
    public void onComplete(Result result) { 
     if (!result.isSucceeded()) { 
      System.err.println(result.getFailure()); // No route to host 
      return; 
     } 

     String body = getContentAsString(StandardCharsets.UTF_8); 
     System.out.printf("onContent: %s\n", body); 
     Map<String, Object> resp = (Map<String, Object>) JSON.parse(body); 

     try { 
      Object[] results = (Object[]) resp.get(FCM_RESULTS); 
      Map map = (Map) results[0]; 
      String error = (String) map.get(FCM_ERROR); 
      if (FCM_NOT_REGISTERED.equals(error)) { 
       // TODO delete invalid FCM token from the database 
      } 
     } catch (Exception ex) { 
      System.err.println(ex); 
     } 
    } 
}; 

public static void main(String[] args) throws Exception { 
    sHttpClient.start(); 
    sHttpClient.POST(FCM_URL) 
     .header(HttpHeader.AUTHORIZATION, FCM_KEY) 
     .header(HttpHeader.CONTENT_TYPE, "application/json") 
     .content(new StringContentProvider(JSON.toString(REQUEST))) 
     .send(sFcmListener); 
} 

Je reçois la No route to host pour toute valeur FCM_URL que j'essaie, pourquoi?

Répondre

0

Ajout SslContextFactory m'a aidé:

private static final SslContextFactory sFactory = new SslContextFactory(); 
private static final HttpClient sHttpClient = new HttpClient(sFactory); 
private static final BufferingResponseListener sFcmListener = new BufferingResponseListener() { 
    @Override 
    public void onComplete(Result result) { 
     if (!result.isSucceeded()) { 
      System.err.println(result.getFailure()); 
      return; 
     } 

     String body = getContentAsString(StandardCharsets.UTF_8); 
     System.out.printf("onComplete: %s\n", body); 

     try { 
      Map<String, Object> resp = (Map<String, Object>) JSON.parse(body); 
      Object[] results = (Object[]) resp.get(FCM_RESULTS); 
      Map map = (Map) results[0]; 
      String error = (String) map.get(FCM_ERROR); 
      System.out.printf("error: %s\n", error); 
      if (FCM_NOT_REGISTERED.equals(error) || 
       FCM_MISSING_REGISTRATION.equals(error) || 
       FCM_INVALID_REGISTRATION.equals(error)) { 
       // TODO delete invalid FCM token from the database 
      } 
     } catch (Exception ex) { 
      System.err.println(ex); 
     } 
    } 
}; 

public static void main(String[] args) throws Exception { 
    sHttpClient.start(); 
    sHttpClient.POST(FCM_URL) 
     .header(HttpHeader.AUTHORIZATION, FCM_KEY) 
     .header(HttpHeader.CONTENT_TYPE, "application/json") 
     .content(new StringContentProvider(JSON.toString(REQUEST))) 
     .send(sFcmListener); 
} 

La question reste ouverte est je how to retrieve the invalid FCM token that I have used in the Jetty HTTP client request, pour que je puisse le supprimer de ma base de données sur la réponse ...

+0

Pourquoi avez-vous besoin d'ajouter un 'SslContextFactory'? 'HttpClient' en fournit un par défaut, n'est-ce pas? – Gili