如何将用户上下文 object 传递给异步 Jetty HTTP 客户端的响应回调?
How to pass user context object to the response callback of async Jetty HTTP client?
通过 Google Firebase Cloud Messaging 向单个收件人发送通知时,有时会返回一个响应(200 + error:MissingRegistration
、200 + error:InvalidRegistration
、200 + error:NotRegistered
),这需要删除该消息的令牌收件人(因为她重新安装了 Android 应用程序并且令牌已更改)。
我的问题是:
如何将该字符串(FCM 令牌)传递回 non-blocking Jetty HTTP client 的响应回调?
目前我的解决方法是将自定义 HTTP header 添加到我的请求中:
X-token: APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...
然后我在响应回调中检索它。但这是一个 hack,因为 FCM 没有指定这样的 header 而且我还需要传递更多自定义数据(我的应用程序中的内部用户 ID)。
这里是 my current source code 和自定义 HTTP header,请问如何更改?
private static final String FCM_URL = "https://fcm.googleapis.com/fcm/send";
private static final String FCM_KEY = "key=REPLACE_BY_YOUR_KEY";
private static final String FCM_RESULTS = "results";
private static final String FCM_ERROR = "error";
private static final String FCM_NOT_REGISTERED = "NotRegistered";
private static final String FCM_MISSING_REGISTRATION = "MissingRegistration";
private static final String FCM_INVALID_REGISTRATION = "InvalidRegistration";
private static final String FCM_X_TOKEN = "X-token";
private static final String TOKEN = "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...";
private static final Map<String, Object> REQUEST = new HashMap<>();
private static final Map<String, Object> NOTIFICATION = new HashMap<>();
private static final Map<String, Object> DATA = new HashMap<>();
static {
REQUEST.put("to", TOKEN);
REQUEST.put("notification", NOTIFICATION);
REQUEST.put("data", DATA);
NOTIFICATION.put("body", "great match!");
NOTIFICATION.put("title", "Portugal vs. Denmark");
NOTIFICATION.put("icon", "myicon");
DATA.put("Nick", "Mario");
DATA.put("Room", "PortugalVSDenmark");
}
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);
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)) {
String token = result.getRequest().getHeaders().get(FCM_X_TOKEN);
System.out.printf("TODO delete invalid FCM token from the database: %s\n", token);
}
} 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")
.header(FCM_X_TOKEN, TOKEN) // Workaround, how to improve?
.content(new StringContentProvider(JSON.toString(REQUEST)))
.send(sFcmListener);
}
您想将令牌设置为请求 属性 并取回它:
httpClient.POST(url)
.attribute(key, token)
...
.send(new BufferingResponseListener() {
@Override
public void onComplete(Result result) {
Object token = result.getRequest().getAttribute(key);
...
}
});
通过 Google Firebase Cloud Messaging 向单个收件人发送通知时,有时会返回一个响应(200 + error:MissingRegistration
、200 + error:InvalidRegistration
、200 + error:NotRegistered
),这需要删除该消息的令牌收件人(因为她重新安装了 Android 应用程序并且令牌已更改)。
我的问题是:
如何将该字符串(FCM 令牌)传递回 non-blocking Jetty HTTP client 的响应回调?
目前我的解决方法是将自定义 HTTP header 添加到我的请求中:
X-token: APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...
然后我在响应回调中检索它。但这是一个 hack,因为 FCM 没有指定这样的 header 而且我还需要传递更多自定义数据(我的应用程序中的内部用户 ID)。
这里是 my current source code 和自定义 HTTP header,请问如何更改?
private static final String FCM_URL = "https://fcm.googleapis.com/fcm/send";
private static final String FCM_KEY = "key=REPLACE_BY_YOUR_KEY";
private static final String FCM_RESULTS = "results";
private static final String FCM_ERROR = "error";
private static final String FCM_NOT_REGISTERED = "NotRegistered";
private static final String FCM_MISSING_REGISTRATION = "MissingRegistration";
private static final String FCM_INVALID_REGISTRATION = "InvalidRegistration";
private static final String FCM_X_TOKEN = "X-token";
private static final String TOKEN = "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...";
private static final Map<String, Object> REQUEST = new HashMap<>();
private static final Map<String, Object> NOTIFICATION = new HashMap<>();
private static final Map<String, Object> DATA = new HashMap<>();
static {
REQUEST.put("to", TOKEN);
REQUEST.put("notification", NOTIFICATION);
REQUEST.put("data", DATA);
NOTIFICATION.put("body", "great match!");
NOTIFICATION.put("title", "Portugal vs. Denmark");
NOTIFICATION.put("icon", "myicon");
DATA.put("Nick", "Mario");
DATA.put("Room", "PortugalVSDenmark");
}
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);
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)) {
String token = result.getRequest().getHeaders().get(FCM_X_TOKEN);
System.out.printf("TODO delete invalid FCM token from the database: %s\n", token);
}
} 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")
.header(FCM_X_TOKEN, TOKEN) // Workaround, how to improve?
.content(new StringContentProvider(JSON.toString(REQUEST)))
.send(sFcmListener);
}
您想将令牌设置为请求 属性 并取回它:
httpClient.POST(url)
.attribute(key, token)
...
.send(new BufferingResponseListener() {
@Override
public void onComplete(Result result) {
Object token = result.getRequest().getAttribute(key);
...
}
});