如何通过 Java 使用通知中心How to use Notification Hubs from Java

本主题将向你介绍完全受支持的全新官方 Azure 通知中心 Java SDK 的主要功能。This topic describes the key features of the new fully supported official Azure Notification Hub Java SDK. 此项目为开源项目,可在 Java SDK 查看完整的 SDK 代码。This project is an open-source project and you can view the entire SDK code at Java SDK.

通常情况下,如 MSDN 主题 通知中心 REST API中所述,可以使用通知中心 REST 接口从 Java/PHP/Python/Ruby 后端访问所有通知中心功能。In general, you can access all Notification Hubs features from a Java/PHP/Python/Ruby back-end using the Notification Hub REST interface as described in the MSDN topic Notification Hubs REST APIs. 此 Java SDK 在以 Java 形式表示的 REST 接口上提供瘦包装器。This Java SDK provides a thin wrapper over these REST interfaces in Java.

SDK 目前支持以下内容:The SDK currently supports:

  • 通知中心上的 CRUDCRUD on Notification Hubs
  • 注册上的 CRUDCRUD on Registrations
  • 安装管理Installation Management
  • 导入/导出注册Import/Export Registrations
  • 常规发送Regular Sends
  • 计划发送Scheduled Sends
  • 通过 Java NIO 的异步操作Async operations via Java NIO
  • 支持的平台:APNS (iOS)、WNS(Windows 应用商店应用)、MPNS (Windows Phone)、ADM (Amazon Kindle Fire)、百度(没有 Google 服务的 Android)Supported platforms: APNS (iOS), WNS (Windows Store apps), MPNS(Windows Phone), ADM (Amazon Kindle Fire), Baidu (Android without Google services)

SDK 用法SDK Usage

编译和生成Compile and build

使用 MavenUse Maven

生成:To build:

mvn package

代码Code

通知中心 CRUDNotification Hub CRUDs

创建命名空间管理器:Create a NamespaceManager:

```java
NamespaceManager namespaceManager = new NamespaceManager("connection string")
```

创建通知中心:Create Notification Hub:

```java
NotificationHubDescription hub = new NotificationHubDescription("hubname");
hub.setWindowsCredential(new WindowsCredential("sid","key"));
hub = namespaceManager.createNotificationHub(hub);
```

或者OR

```java
hub = new NotificationHub("connection string", "hubname");
```

获取通知中心:Get Notification Hub:

```java
hub = namespaceManager.getNotificationHub("hubname");
```

更新通知中心:Update Notification Hub:

```java
hub.setMpnsCredential(new MpnsCredential("mpnscert", "mpnskey"));
hub = namespaceManager.updateNotificationHub(hub);
```

删除通知中心:Delete Notification Hub:

```java
namespaceManager.deleteNotificationHub("hubname");
```

注册 CRUDRegistration CRUDs

创建通知中心客户端:Create a Notification Hub client:

```java
hub = new NotificationHub("connection string", "hubname");
```

创建 Windows 注册:Create Windows registration:

```java
WindowsRegistration reg = new WindowsRegistration(new URI(CHANNELURI));
reg.getTags().add("myTag");
reg.getTags().add("myOtherTag");
hub.createRegistration(reg);
```

创建 iOS 注册:Create iOS registration:

```java
AppleRegistration reg = new AppleRegistration(DEVICETOKEN);
reg.getTags().add("myTag");
reg.getTags().add("myOtherTag");
hub.createRegistration(reg);
```

同样,可以为 Windows Phone (MPNS)、Android (Baidu) 和 Kindle Fire (ADM) 创建注册。Similarly you can create registrations for Windows Phone (MPNS), Android (Baidu) and Kindle Fire (ADM).

创建模板注册:Create template registrations:

```java
WindowsTemplateRegistration reg = new WindowsTemplateRegistration(new URI(CHANNELURI), WNSBODYTEMPLATE);
reg.getHeaders().put("X-WNS-Type", "wns/toast");
hub.createRegistration(reg);
```

采用“创建注册 ID + upsert”模式创建注册:Create registrations using create registration ID + upsert pattern:

如果在设备上存储注册 ID,请删除重复项以防出现任何响应丢失:Removes duplicates due to any lost responses if storing registration IDs on the device:

```java
String id = hub.createRegistrationId();
WindowsRegistration reg = new WindowsRegistration(id, new URI(CHANNELURI));
hub.upsertRegistration(reg);
```

更新注册:Update registrations:

```java
hub.updateRegistration(reg);
```

删除注册:Delete registrations:

```java
hub.deleteRegistration(regid);
```

查询注册:Query registrations:

  • 获取单个注册:Get single registration:

    hub.getRegistration(regid);
    
  • 获取中心的所有注册:Get all registrations in hub:

    hub.getRegistrations();
    
  • 获取具有标记的注册:Get registrations with tag:

    hub.getRegistrationsByTag("myTag");
    
  • 按渠道获取注册:Get registrations by channel:

    hub.getRegistrationsByChannel("devicetoken");
    

所有集合查询都支持 $top 和继续标记。All collection queries support $top and continuation tokens.

安装 API 用法Installation API usage

安装 API 是一种注册管理的替代机制。Installation API is an alternative mechanism for registration management. 现在,可以使用“单个”安装对象,而不必维护多个注册,这些注册不但工作量大,而且执行起来可能容易出错或效率低下。Instead of maintaining multiple registrations, which are not trivial and may be easily done incorrectly or inefficiently, it is now possible to use a SINGLE Installation object.

安装包含你所需的一切:推送通道(设备标记)、标记、模板、辅助磁贴(用于 WNS 和 APNS)。Installation contains everything you need: push channel (device token), tags, templates, secondary tiles (for WNS and APNS). 无需再调用该服务即可获取 ID - 只需生成 GUID 或任何其他标识符,将其保存在设备上并连同推送通道(设备标记)一起发送到后端即可。You don't need to call the service to get ID anymore - just generate GUID or any other identifier, keep it on the device and send to your backend together with push channel (device token).

在后端,只能对 CreateOrUpdateInstallation 进行单个调用;该调用具有完全幂等性,因此,如果需要,可随时重试。On the backend, you should only do a single call to CreateOrUpdateInstallation; it is fully idempotent, so feel free to retry if needed.

针对 Amazon Kindle Fire 的示例如下:As example for Amazon Kindle Fire:

```java
Installation installation = new Installation("installation-id", NotificationPlatform.Adm, "adm-push-channel");
hub.createOrUpdateInstallation(installation);
```

如果希望进行更新:If you want to update it:

```java
installation.addTag("foo");
installation.addTemplate("template1", new InstallationTemplate("{\"data\":{\"key1\":\"$(value1)\"}}","tag-for-template1"));
installation.addTemplate("template2", new InstallationTemplate("{\"data\":{\"key2\":\"$(value2)\"}}","tag-for-template2"));
hub.createOrUpdateInstallation(installation);
```

对于高级方案,使用部分更新功能,允许仅修改安装对象的特定属性。For advanced scenarios, use the partial update capability, which allows to modify only particular properties of the installation object. 部分更新是可针对安装对象运行的 JSON Patch 操作的子集。Partial update is subset of JSON Patch operations you can run against Installation object.

```java
PartialUpdateOperation addChannel = new PartialUpdateOperation(UpdateOperationType.Add, "/pushChannel", "adm-push-channel2");
PartialUpdateOperation addTag = new PartialUpdateOperation(UpdateOperationType.Add, "/tags", "bar");
PartialUpdateOperation replaceTemplate = new PartialUpdateOperation(UpdateOperationType.Replace, "/templates/template1", new InstallationTemplate("{\"data\":{\"key3\":\"$(value3)\"}}","tag-for-template1")).toJson());
hub.patchInstallation("installation-id", addChannel, addTag, replaceTemplate);
```

删除安装:Delete Installation:

```java
hub.deleteInstallation(installation.getInstallationId());
```

CreateOrUpdatePatchDelete 最终与 Get 保持一致。CreateOrUpdate, Patch, and Delete are eventually consistent with Get. 请求的操作会在调用期间进入系统队列并在后台执行。Your requested operation just goes to the system queue during the call and is executed in background. Get 并不适用于主运行时方案,只适用于调试和故障排除,其会受到服务的严密限制。Get is not designed for main runtime scenario but just for debug and troubleshooting purposes, it is tightly throttled by the service.

安装的发送流与注册的一样。Send flow for Installations is the same as for Registrations. 将通知定向至特定安装 - 仅使用了标记“InstallationId:{desired-id}”。To target notification to the particular Installation - just use tag "InstallationId:{desired-id}". 在此事例中,代码为:For this case, the code is:

```java
Notification n = Notification.createWindowsNotification("WNS body");
hub.sendNotification(n, "InstallationId:{installation-id}");
```

为多个模板之一:For one of several templates:

```java
Map<String, String> prop =  new HashMap<String, String>();
prop.put("value3", "some value");
Notification n = Notification.createTemplateNotification(prop);
hub.sendNotification(n, "InstallationId:{installation-id} && tag-for-template1");
```

计划通知(适用于标准层)Schedule Notifications (available for STANDARD Tier)

与常规发送相同,但多了一个参数 - scheduledTime,表示通知应传递的时间。The same as regular send but with one additional parameter - scheduledTime, which says when notification should be delivered. 服务接受现在 + 5 分钟与现在 + 7 天之间的任何时间点。Service accepts any point of time between now + 5 minutes and now + 7 days.

计划 Windows 本机通知:Schedule a Windows native notification:

```java
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, 1);
Notification n = Notification.createWindowsNotification("WNS body");
hub.scheduleNotification(n, c.getTime());
```

导入/导出(可用于标准层)Import/Export (available for STANDARD Tier)

可能需要对注册执行批量操作。You may need to perform bulk operation against registrations. 通常,这种方式适用于与其他系统的集成或为了更新标记而执行的大规模修复。Usually it is for integration with another system or a massive fix to update the tags. 如果涉及数以千计的注册,我们不建议使用 Get/Update 流。We don't recommend using the Get/Update flow if thousands of registrations are involved. 系统的“导入/导出”功能旨在应对这种情况。The system's Import/Export capability is designed to cover the scenario. 你将提供对存储帐户下作为传入数据的源和输出的位置的 Blob 容器的访问。You'll provide access to a blob container under your storage account as a source of incoming data and location for output.

提交导出作业:Submit an export job:

```java
NotificationHubJob job = new NotificationHubJob();
job.setJobType(NotificationHubJobType.ExportRegistrations);
job.setOutputContainerUri("container uri with SAS signature");
job = hub.submitNotificationHubJob(job);
```

提交导入作业:Submit an import job:

```java
NotificationHubJob job = new NotificationHubJob();
job.setJobType(NotificationHubJobType.ImportCreateRegistrations);
job.setImportFileUri("input file uri with SAS signature");
job.setOutputContainerUri("container uri with SAS signature");
job = hub.submitNotificationHubJob(job);
```

等到作业完成:Wait until a job is done:

```java
while(true){
    Thread.sleep(1000);
    job = hub.getNotificationHubJob(job.getJobId());
    if(job.getJobStatus() == NotificationHubJobStatus.Completed)
        break;
}
```

获取所有作业:Get all jobs:

```java
List<NotificationHubJob> jobs = hub.getAllNotificationHubJobs();
```

使用 SAS 签名的 URI:URI with SAS signature:

此 URL 是 Blob 文件或 Blob 容器的 URL 加上一组参数(例如权限和到期时间),再加上使用帐户的 SAS 密钥生成的所有这些内容的签名。This URL is the URL of a blob file or blob container plus a set of parameters like permissions and expiration time plus signature of all these things made using account's SAS key. Azure 存储 Java SDK 具有丰富的功能,包括创建这些 URI。Azure Storage Java SDK has rich capabilities including creation of these URIs. 作为简单的备选方案,可以考虑使用 ImportExportE2E 测试类(来自 GitHub 位置),该测试类具有基本、精简的签名算法实现。As simple alternative, take a look at the ImportExportE2E test class (from the GitHub location) which has basic and compact implementation of signing algorithm.

发送通知Send Notifications

通知对象只有带有标头的正文,一些实用工具方法可帮助你构建本机和模板通知对象。The Notification object is simply a body with headers, some utility methods help in building the native and template notifications objects.

  • Windows 应用商店和 Windows Phone 8.1(非 Silverlight) Windows Store and Windows Phone 8.1 (non-Silverlight)

    String toast = "<toast><visual><binding template=\"ToastText01\"><text id=\"1\">Hello from Java!</text></binding></visual></toast>";
    Notification n = Notification.createWindowsNotification(toast);
    hub.sendNotification(n);
    
  • iOSiOS

    String alert = "{\"aps\":{\"alert\":\"Hello from Java!\"}}";
    Notification n = Notification.createAppleNotification(alert);
    hub.sendNotification(n);
    
  • AndroidAndroid

    String message = "{\"data\":{\"msg\":\"Hello from Java!\"}}";
    Notification n = Notification.createBaiduNotification(message);
    hub.sendNotification(n);
    
  • Windows Phone 8.0 和 8.1 SilverlightWindows Phone 8.0 and 8.1 Silverlight

    String toast = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<wp:Notification xmlns:wp=\"WPNotification\">" +
                    "<wp:Toast>" +
                        "<wp:Text1>Hello from Java!</wp:Text1>" +
                    "</wp:Toast> " +
                "</wp:Notification>";
    Notification n = Notification.createMpnsNotification(toast);
    hub.sendNotification(n);
    
  • Kindle FireKindle Fire

    String message = "{\"data\":{\"msg\":\"Hello from Java!\"}}";
    Notification n = Notification.createAdmNotification(message);
    hub.sendNotification(n);
    
  • 发送到标记Send to Tags

    Set<String> tags = new HashSet<String>();
    tags.add("boo");
    tags.add("foo");
    hub.sendNotification(n, tags);
    
  • 发送到标记表达式Send to tag expression

    hub.sendNotification(n, "foo && ! bar");
    
  • 发送模板通知Send template notification

    Map<String, String> prop =  new HashMap<String, String>();
    prop.put("prop1", "v1");
    prop.put("prop2", "v2");
    Notification n = Notification.createTemplateNotification(prop);
    hub.sendNotification(n);
    

运行 Java 代码,现在应该生成显示在目标设备上的通知。Running your Java code should now produce a notification appearing on your target device.

后续步骤Next Steps

本主题介绍了如何为通知中心创建简单的 Java REST 客户端。This topic showed you how to create a simple Java REST client for Notification Hubs. 从这里可以:From here you can: