How to pass user context object to the response callback of async Jetty HTTP client?

拜拜、爱过 提交于 2019-12-25 09:22:17

问题


When sending notifications to single recipients over Google Firebase Cloud Messaging, sometimes a response comes back (200 + error:MissingRegistration, 200 + error:InvalidRegistration, 200 + error:NotRegistered), which requires deleting the token of that recipient (because she for example reinstalled the Android app and the token has changed).

My question is:

How to pass that string (the FCM token) back to the response callback of the non-blocking Jetty HTTP client?

Currently my workaround is to add a custom HTTP header to my request:

X-token: APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...

and then I retrieve it in the response callback. But this is a hack, because FCM does not specify such a header and also I need to pass more custom data (the internal user id in my app) back.

Here is my current source code with the custom HTTP header, how to change it please?

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

回答1:


You want to set the token as a request attribute and the retrieve it back:

httpClient.POST(url)
        .attribute(key, token)
        ...
        .send(new BufferingResponseListener() {
            @Override
            public void onComplete(Result result) {
                Object token = result.getRequest().getAttribute(key);
                ...
            }
        });


来源:https://stackoverflow.com/questions/44870396/how-to-pass-user-context-object-to-the-response-callback-of-async-jetty-http-cli

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!