從後端使用 REST API

 

中所述 註冊管理, ,應用程式後端通常會傳送通知和可能執行註冊管理。 因為已經有 Node.js 的 Azure SDK for Node 中的 REST 包裝函式,這一個區段會顯示在 Java 中的範例。

傳送通知

傳送通知的 REST API 是 /yourHub/messages 上的簡單 POST,具有特殊的標頭。 以平台原生的格式傳送通知時,內文為要傳送的平台特定內文。 其他的標頭為:

  • Servicebusnotification-format:指定要傳送範本通知的平台 (若傳送原生通知) 或「範本」。

  • Servicebusnotification-tags (選擇性):指定定義鎖定註冊集的標籤 (或標籤運算式)。 如果並未顯示此標頭,通知中心會廣播至所有註冊。

支援其他標頭中所指定的平台特定功能的 通知中心 REST API 文件集。

下列 Java 程式碼會傳送原生通知至 Windows 市集應用程式 (使用 Apache HttpClient):

public Notification createWindowsNotification(String body) { Notification n = new Notification(); n.body = body; n.headers.put("ServiceBusNotification-Format", "windows"); if (body.contains("<toast>")) n.headers.put("X-WNS-Type", "wns/toast"); if (body.contains("<tile>")) n.headers.put("X-WNS-Type", "wns/tile"); if (body.contains("<badge>")) n.headers.put("X-WNS-Type", "wns/badge"); if (body.startsWith("<")) { n.contentType = ContentType.APPLICATION_XML; } return n; } public void sendNotification(Notification notification, String tagExpression) { HttpPost post = null; try { URI uri = new URI(endpoint + hubPath + "/messages"+APIVERSION); post = new HttpPost(uri); post.setHeader("Authorization", generateSasToken(uri)); if (tagExpression != null && !"".equals(tagExpression)) { post.setHeader("ServiceBusNotification-Tags", tagExpression); } for (String header: notification.getHeaders().keySet()) { post.setHeader(header, notification.getHeaders().get(header)); } post.setEntity(new StringEntity(notification.getBody())); HttpResponse response = httpClient.execute(post); if (response.getStatusLine().getStatusCode() != 201) { String msg = ""; if (response.getEntity() != null && response.getEntity().getContent() != null) { msg = IOUtils.toString(response.getEntity().getContent()); } throw new RuntimeException("Error: " + response.getStatusLine() + " body: "+msg); } } catch (Exception e) { throw new RuntimeException(e); } finally { if (post != null) post.releaseConnection(); } }  

同樣地,下列程式碼會傳送範本通知:

public Notification createTemplateNotification(Map<String, String> properties) { Notification n = new Notification(); StringBuffer buf = new StringBuffer(); buf.append("{"); for (Iterator<String> iterator = properties.keySet().iterator(); iterator.hasNext();) { String key = iterator.next(); buf.append("\""+ key + "\":\""+properties.get(key)+"\""); if (iterator.hasNext()) buf.append(","); } buf.append("}"); n.body = buf.toString(); n.contentType = ContentType.APPLICATION_JSON; n.headers.put("ServiceBusNotification-Format", "template"); return n; }  

如需以下內容的詳細資訊 將通知傳送至其他平台,請參閱 通知中心 REST API

建立和更新註冊

建立和更新註冊需要註冊 XML 格式的序列化和還原序列化。建立註冊 API 主題說明建立不同種類註冊 (原生和每個平台的範本) 的 XML 格式。

重要

XML 元素的順序必須完全如下所示。

下列是範例的 Java 使用簡單的字串串連來建立註冊 XML 內容中建立註冊和 Apache Digester 剖析結果。 如先前提到的,XML 序列化或還原序列化方式成功運作。

public Registration createRegistration(Registration registration) { HttpPost post = null; try { URI uri = new URI(endpoint + hubPath + "/registrations"+APIVERSION); post = new HttpPost(uri); post.setHeader("Authorization", generateSasToken(uri)); StringEntity entity = new StringEntity(registration.getXml(),ContentType.APPLICATION_ATOM_XML); entity.setContentEncoding("utf-8"); post.setEntity(entity); HttpResponse response = httpClient.execute(post); if (response.getStatusLine().getStatusCode() != 200) throw new RuntimeException("Error: " + response.getStatusLine()); return Registration.parse(response.getEntity().getContent()); } catch (Exception e) { throw new RuntimeException(e); } finally { if (post != null) post.releaseConnection(); } }  

getXml() 原生 Windows 註冊的方法如下:

private static final String WNS_NATIVE_REGISTRATION = "<?xml version=\"1.0\" encoding=\"utf-8\"?><entry xmlns=\"http://www.w3.org/2005/Atom\"><content type=\"application/xml\"><WindowsRegistrationDescription xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"https://schemas.microsoft.com/netservices/2010/10/servicebus/connect\">{0}<ChannelUri>{1}</ChannelUri>
</WindowsRegistrationDescription>
</content>
</entry>"; public String getXml() { String xml = WNS_NATIVE_REGISTRATION.replaceFirst("\\{1\\}", channelUri.toString()); xml = xml.replaceFirst("\\{0\\}", getTagsXml()); return xml.toString(); }

您可以輕鬆地從其中其他註冊類型方法中的範例 建立註冊 API 主題。

回應包含結果的建立,包括唯讀屬性,例如 RegistrationId, ,ETag, ,和 ExpirationTime。 下列程式碼範例會剖析結果使用 Apache Digester:

public static Registration parse(InputStream content) throws IOException, SAXException { Digester digester = new Digester(); digester.addObjectCreate("*/WindowsRegistrationDescription", WindowsRegistration.class); digester.addCallMethod("*/RegistrationId", "setRegistrationId", 1); digester.addCallParam("*/RegistrationId", 0); digester.addCallMethod("*/ETag", "setEtag", 1); digester.addCallParam("*/ETag", 0); digester.addCallMethod("*/ChannelUri", "setChannelUri", 1); digester.addCallParam("*/ChannelUri", 0); digester.addCallMethod("*/Tags", "setTagsFromString", 1); digester.addCallParam("*/Tags", 0); digester.addCallMethod("*/BodyTemplate", "setBodyTemplate", 1); digester.addCallParam("*/BodyTemplate", 0); digester.addCallMethod("*/WnsHeader", "addHeader", 2); digester.addCallParam("*/WnsHeader/Header", 0); digester.addCallParam("*/WnsHeader/Value", 1); return digester.parse(content); }  

請注意 Create 呼叫會傳回 registrationId, ,這用來擷取、 更新或刪除註冊。

注意

上述程式碼片段會假設是子類別的 Registration 呼叫 WindowsRegistrationDescription

您可以藉由發出更新註冊 上呼叫 /yourhub/註冊 / {registrationId}If-match 標頭用來提供 ETag (支援主動並行) 或簡單的"*"以進行覆寫。 如果 If-match 標頭不存在,作業會執行"upsert"(一律覆寫目前的註冊,或建立一個在提供 registrationId 如果不存在)。 例如:

public Registration updateRegistration(Registration registration) { HttpPut put = null; try { URI uri = new URI(endpoint + hubPath + "/registrations/"+registration.getRegistrationId()+APIVERSION); put = new HttpPut(uri); put.setHeader("Authorization", generateSasToken(uri)); put.setHeader("If-Match", registration.getEtag()==null?"*":"W/\""+registration.getEtag()+"\""); put.setEntity(new StringEntity(registration.getXml(),ContentType.APPLICATION_ATOM_XML)); HttpResponse response = httpClient.execute(put); if (response.getStatusLine().getStatusCode() != 200) throw new RuntimeException("Error: " + response.getStatusLine()); return Registration.parse(response.getEntity().getContent()); } catch (Exception e) { throw new RuntimeException(e); } finally { if (put != null) put.releaseConnection(); } }  

刪除註冊 是類似的作業。

擷取註冊

擷取註冊時, 上發出 GET 呼叫 /registrations/{registrationId}。 如同下列 REST API 中所指定,您擷取了註冊集合:

您接著可以選擇指定 $top 限制的註冊數目的參數傳回。 如果多個註冊都出現該查詢,則需要 X-MS-ContinuationToken 傳回標頭,您可以傳送至後續的呼叫以繼續擷取剩下的註冊。 也請注意內容格式目前為 XML Atom 摘要,如先前提到的 API 主題中所示。

下列 Java 程式碼會擷取所有包括標籤的註冊;

private CollectionResult retrieveRegistrationByTag() { String queryUri = endpoint + hubPath + "/tags/"+tag+"/registrations"+APIVERSION; HttpGet get = null; try { URI uri = new URI(queryUri); get = new HttpGet(uri); get.setHeader("Authorization", generateSasToken(uri)); HttpResponse response = httpClient.execute(get); if (response.getStatusLine().getStatusCode() != 200) throw new RuntimeException("Error: " + response.getStatusLine()); CollectionResult result = Registration.parseRegistrations(response.getEntity().getContent()); Header contTokenHeader = response.getFirstHeader("X-MS-ContinuationToken"); if (contTokenHeader !=null) { result.setContinuationToken(contTokenHeader.getValue()); } return result; } catch (Exception e) { throw new RuntimeException(e); } finally { if (get != null) get.releaseConnection(); } }  

在此程式碼, CollectionResult 會封裝一組註冊以及選擇性的接續權杖。

下列程式碼會使用 Apache Digester:

public static CollectionResult parseRegistrations(InputStream content) throws IOException, SAXException { Digester digester = new Digester(); // add all rules for parsing single registrations digester.addObjectCreate("feed", CollectionResult.class); digester.addSetNext("*/WindowsRegistrationDescription", "addRegistration"); // add rules for other types of registrations (if required) return digester.parse(content); }