阿里云MNS Queue Rest API操作示例

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 阿里云消息服务(Message Service)是一种高效、可靠、安全、便捷、可弹性扩展的分布式消息服务。MNS能够帮助应用开发者在他们应用的分布式组件上自由的传递数据、通知消息,构建松耦合系统。本文主要介绍基于Java 语言实现Queue的创建、删除以及消息的发送及接受的Rest API操作。

作者:俏巴

签名验证工具

如果在使用过程中因为签名问题一直无法通过,建议直接使用签名验证工具进行快速的测试验证。

image.png

Code Sample

创建队列

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.StringEntity;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class CreateMNSQueue {

    public static void main(String[] args) {
        //参数设置
        String AccessKeySecret = "********";//Access Key Secret
        String AccessKeyId = "********";//AccessKey ID
        String AccountId = "********";//Account ID

        //获取GMT英文格式时间
        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(d);

        String body = "<?xml version=\"1.0\" encoding=\"UTF-8\"  ?>\n" +
                "    <Queue xmlns=\"http://mns.aliyuncs.com/doc/v1/\">\n" +
                "    <VisibilityTimeout >60</VisibilityTimeout>\n" +
                "    <MaximumMessageSize>1024</MaximumMessageSize>\n" +
                "    <MessageRetentionPeriod>120</MessageRetentionPeriod>\n" +
                "    <DelaySeconds>0</DelaySeconds>\n" +
                "    </Queue>";

        //构造签名String
        String SignString = "PUT\n" +
                "\n"+
                "application/xml"+
                "\n"+
                date + "\n"+
                "x-mns-version:2015-06-06" +"\n"+
                "/queues/TestQueue123";

        String sign = encode(AccessKeySecret,SignString);
        String Authorization = "MNS " + AccessKeyId + ":" + sign;
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("http://" + AccountId + ".mns.cn-hangzhou.aliyuncs.com/queues/TestQueue123");//在杭州区域
            URI uri = builder.build();
            HttpPut request = new HttpPut(uri);
            request.setHeader("Authorization", Authorization);
            request.setHeader("Date", date);
            request.setHeader("Host", AccountId + ".mns.cn-hangzhou.aliyuncs.com");
            request.setHeader("Content-Type","application/xml");
            request.setHeader("x-mns-version","2015-06-06");

            // Request body
            StringEntity reqEntity = new StringEntity(body,"UTF-8");
            request.setEntity(reqEntity);

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null)
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println("error");
            System.out.println(e.getMessage());
        }
    }

    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    //计算签名
    public static String encode(String accessKey, String data) {
        try {
            byte[] keyBytes = accessKey.getBytes("UTF-8");
            byte[] dataBytes = data.getBytes("UTF-8");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
            return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("Not supported encoding method UTF-8", var5);
        } catch (NoSuchAlgorithmException var6) {
            throw new RuntimeException("Not supported signature method hmac-sha1", var6);
        } catch (InvalidKeyException var7) {
            throw new RuntimeException("Failed to calculate the signature", var7);
        }
    }
}

删除队列

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class DeleteMNSQueue {

    public static void main(String[] args) {
        //参数设置
        String AccessKeySecret = "********";//Access Key Secret
        String AccessKeyId = "********";//AccessKey ID
        String AccountId = "********";

        //获取GMT英文格式时间
        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(d);

        //构造签名String
        String SignString = "DELETE\n" +
                "\n"+"\n"+
                date + "\n"+
                "x-mns-version:2015-06-06" +"\n"+
                "/queues/TestQueue123";

        String sign = encode(AccessKeySecret,SignString);
        String Authorization = "MNS " + AccessKeyId + ":" + sign;
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("http://" + AccountId + ".mns.cn-hangzhou.aliyuncs.com/queues/TestQueue123");//在青岛区域创建Project
            URI uri = builder.build();
            HttpDelete request = new HttpDelete(uri);
            request.setHeader("Authorization", Authorization);
            request.setHeader("Date", date);
            request.setHeader("Host", AccountId + ".mns.cn-hangzhou.aliyuncs.com");
            request.setHeader("x-mns-version","2015-06-06");

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null)
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println("error");
            System.out.println(e.getMessage());
        }
    }

    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    //计算签名
    public static String encode(String accessKey, String data) {
        try {
            byte[] keyBytes = accessKey.getBytes("UTF-8");
            byte[] dataBytes = data.getBytes("UTF-8");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
            return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("Not supported encoding method UTF-8", var5);
        } catch (NoSuchAlgorithmException var6) {
            throw new RuntimeException("Not supported signature method hmac-sha1", var6);
        } catch (InvalidKeyException var7) {
            throw new RuntimeException("Failed to calculate the signature", var7);
        }
    }
}

发送消息

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class SendMessageToMNSQueue {

    public static void main(String[] args) {
        //参数设置
        String AccessKeySecret = "******";//Access Key Secret
        String AccessKeyId = "******";//AccessKey ID
        String AccountId = "********";

        //获取GMT英文格式时间
        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(d);

        //延迟消息
        String body = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "    <Message xmlns=\"http://mns.aliyuncs.com/doc/v1/\">\n" +
                "        <MessageBody>The Test Message!</MessageBody>\n" +
                "        <DelaySeconds>0</DelaySeconds>\n" +
                "        <Priority>1</Priority>\n" +
                "    </Message>";

        //构造签名String
        String SignString = "POST\n" +
                 "\n"+
                "text/xml;charset=utf-8"+
                "\n"+
                date + "\n"+
                "x-mns-version:2015-06-06" +"\n"+
                "/queues/TestQueue123/messages";

        String sign = encode(AccessKeySecret,SignString);
        String Authorization = "MNS " + AccessKeyId + ":" + sign;
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("http://" + AccountId + ".mns.cn-hangzhou.aliyuncs.com/queues/TestQueue123/messages");
            URI uri = builder.build();
            HttpPost request = new HttpPost(uri);
            request.setHeader("Authorization", Authorization);
            request.setHeader("Date", date);
            request.setHeader("Host", AccountId + ".mns.cn-hangzhou.aliyuncs.com");
            request.setHeader("Content-Type","text/xml;charset=utf-8");
            request.setHeader("x-mns-version","2015-06-06");

            // Request body
            StringEntity reqEntity = new StringEntity(body,"UTF-8");
            request.setEntity(reqEntity);

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null)
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println("error");
            System.out.println(e.getMessage());
        }
    }

    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    //计算签名
    public static String encode(String accessKey, String data) {
        try {
            byte[] keyBytes = accessKey.getBytes("UTF-8");
            byte[] dataBytes = data.getBytes("UTF-8");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
            return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("Not supported encoding method UTF-8", var5);
        } catch (NoSuchAlgorithmException var6) {
            throw new RuntimeException("Not supported signature method hmac-sha1", var6);
        } catch (InvalidKeyException var7) {
            throw new RuntimeException("Failed to calculate the signature", var7);
        }
    }
}

消费消息

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class GetMessageFromMNSQueue {

    public static void main(String[] args) {
        //参数设置
        String AccessKeySecret = "********";//Access Key Secret
        String AccessKeyId = "********";//AccessKey ID
        String AccountId = "********";

        //获取GMT英文格式时间
        Date d=new Date();
        DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(d);

        //构造签名String
        String SignString = "GET\n" +
                 "\n"+
                "\n"+
                date + "\n"+
                "x-mns-version:2015-06-06" +"\n"+
                "/queues/TestQueue123/messages?waitseconds=30";

        String sign = encode(AccessKeySecret,SignString);
        String Authorization = "MNS " + AccessKeyId + ":" + sign;
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("http://" + AccountId + ".mns.cn-hangzhou.aliyuncs.com/queues/TestQueue123/messages?waitseconds=30");
            URI uri = builder.build();
            HttpGet request = new HttpGet(uri);
            request.setHeader("Authorization", Authorization);
            request.setHeader("Date", date);
            request.setHeader("Host", AccountId + ".mns.cn-hangzhou.aliyuncs.com");
            request.setHeader("x-mns-version","2015-06-06");

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null)
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println("error");
            System.out.println(e.getMessage());
        }
    }

    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    //计算签名
    public static String encode(String accessKey, String data) {
        try {
            byte[] keyBytes = accessKey.getBytes("UTF-8");
            byte[] dataBytes = data.getBytes("UTF-8");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
            return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
        } catch (UnsupportedEncodingException var5) {
            throw new RuntimeException("Not supported encoding method UTF-8", var5);
        } catch (NoSuchAlgorithmException var6) {
            throw new RuntimeException("Not supported signature method hmac-sha1", var6);
        } catch (InvalidKeyException var7) {
            throw new RuntimeException("Failed to calculate the signature", var7);
        }
    }
}

更多参考
签名验证工具
RESTfulAPI概述

备注: 示例代码仅供快速测试使用,未做冗余处理。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
30天前
|
存储 人工智能 自然语言处理
Elasticsearch Inference API增加对阿里云AI的支持
本文将介绍如何在 Elasticsearch 中设置和使用阿里云的文本生成、重排序、稀疏向量和稠密向量服务,提升搜索相关性。
67 14
Elasticsearch Inference API增加对阿里云AI的支持
|
14天前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 云原生 API 网关 2024 年 10 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要
|
25天前
|
缓存 API 网络架构
掌握现代API开发:GraphQL vs REST
【10月更文挑战第24天】本文深入探讨了现代API开发中两种主流技术——GraphQL和REST的设计理念、技术特点及实际开发中的对比分析。GraphQL通过声明式数据请求和强类型系统提供更高的灵活性和性能,而REST则以其无状态特性和成熟的生态系统见长。文章还讨论了两者在客户端-服务器交互、安全性和工具支持方面的优劣,帮助开发者根据项目需求做出明智选择。
|
28天前
|
弹性计算 负载均衡 监控
阿里云slb的slb-api介绍
【10月更文挑战第17天】
59 1
|
1月前
|
API
阿里云短信平台API错误码提示错误天级流控显示小时级错误码
阿里云短信平台API错误码提示错误天级流控显示小时级错误码
|
4月前
|
JSON API 网络架构
gRPC 与 REST 的比较分析:哪种 API 适合您的开发需求?
gRPC, 由 Google 推出的开源远程过程调用(RPC)框架, 使两个应用程序间的方法调用变得简单,支持结构化数据的交换。通过采用 Protocol Buffers (Protobuf) ——一种与语言无关的接口定义语言,gRPC 体现了许多现代网络通信技术的优势
gRPC 与 REST 的比较分析:哪种 API 适合您的开发需求?
|
4月前
|
开发框架 Java API
Java中的REST API开发详解
Java中的REST API开发详解
|
4月前
|
开发框架 Java API
Java中的REST API开发详解
Java中的REST API开发详解
|
XML 安全 API
Rest API 开发分享
Rest API 开发分享
|
Prometheus 安全 JavaScript
一种不错的 BFF Microservice GraphQL/REST API 层的开发方式
一种不错的 BFF Microservice GraphQL/REST API 层的开发方式
351 0
一种不错的 BFF Microservice GraphQL/REST API 层的开发方式

热门文章

最新文章

下一篇
无影云桌面