我有以下代码来获取访问令牌,以便稍后用于对FCM的POST请求。以下代码在部署后立即工作,并在一段时间后失败。
FileInputStream serviceAccountCreds= new FileInputStream("path/to/serviceAccountKey.json");
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredential credential = GoogleCredential
.fromStream(serviceAccountCreds, httpTransport, jsonFactory)
.createScoped(Arrays.asList(FIREBASE_SCOPE));
credential.refreshToken();
return credential.getAccessToken();
堆栈跟踪如下:
java.net.UnknownHostException: accounts.google.com
at java.net.AbstractPlainSocketImpl.connect (AbstractPlainSocketImpl.java:184)
at java.net.SocksSocketImpl.connect (SocksSocketImpl.java:392)
at java.net.Socket.connect (Socket.java:589)
at sun.security.ssl.SSLSocketImpl.connect (SSLSocketImpl.java:668)
at sun.net.NetworkClient.doConnect (NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer (HttpClient.java:432)
at sun.net.www.http.HttpClient.openServer (HttpClient.java:527)
at sun.net.www.protocol.https.HttpsClient.<init> (HttpsClient.java:264)
at sun.net.www.protocol.https.HttpsClient.New (HttpsClient.java:367)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient (AbstractDelegateHttpsURLConnection.java:191)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0 (HttpURLConnection.java:1138)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect (HttpURLConnection.java:1032)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect (AbstractDelegateHttpsURLConnection.java:177)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0 (HttpURLConnection.java:1316)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream (HttpURLConnection.java:1291)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream (HttpsURLConnectionImpl.java:250)
at com.google.api.client.http.javanet.NetHttpRequest.execute (NetHttpRequest.java:77)
at com.google.api.client.http.HttpRequest.execute (HttpRequest.java:972)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed (TokenRequest.java:283)
at com.google.api.client.auth.oauth2.TokenRequest.execute (TokenRequest.java:307)
at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken (GoogleCredential.java:384)
。
代码是在Google App Engine应用程序中执行的,那么GoogleCredential是否有可能无法进行HTTPRequest?(我记得在 GAE 的文档中读过类似的内容(。如果是这样,在这里使用正确的HTTP传输是什么?
我的猜测是对的。GoogleCredential 进行的 Http 调用被 Google App Engine 阻止,因为它使用的是 Socket API。将此行添加到appengine-web中.xml会强制Http(s(请求使用urlfetch。
appengine-web.xml
<url-stream-handler>urlfetch</url-stream-handler>
参考: https://cloud.google.com/appengine/docs/standard/java/config/appref#url-stream-handler