腾讯Ai开放服务接入

https://blog.csdn.net/breeze048/article/details/79426819


1.接口调用通用形式

相关网址:https://ai.qq.com/doc/auth.shtml 
这里写图片描述

如腾讯Ai给出的示例,其中app_id, time_stamp, nonce_str, sign为发起对腾讯Ai各种Api都需要加入到post请求的数据。而key1,key2则根据不同Api会有不同。如下面的OCR通用文字识别Api

这里写图片描述
图中唯一不同于示例的是把key1,key2换成了image,即待识别图片的base64编码数据。 
实际上也是如此,对待不同的Api请求,只需要修改key1,key2成对应的键值对即可。

2.各字段数据生成

app_id

app_id为应用标识,到腾讯Ai平台申请项目就会得到app_id,和app_key。app_key在后续的鉴权生成时会用到。 
申请项目获得密钥的接入文档https://ai.qq.com/doc/index.shtml

time_stamp

秒级时间戳 
实际上就可以使用系统时间(毫秒)/1000得到需要的值。如:

String time_stamp = System.currentTimeMillis() / 1000 + "";
  • 1
nonce_str

随机字符串

public static String getRandomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";     
        Random random = new Random();     
        StringBuffer sb = new StringBuffer();     
        for (int i = 0; i < length; i++) {     
            int number = random.nextInt(base.length());     
            sb.append(base.charAt(number));     
        }     
        return sb.toString();     
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

利用随机数字去生成即可。

image的base64编码生成

base64的编码工具类在网上到处都能找得到,这里就不贴算法了,比较长 
这个部分的流程主要是将图片以字节数据读入,然后再进行base64编码

扫描二维码关注公众号,回复: 2217086 查看本文章
byte[] imageData = FileUtil.readFileByBytes(file);
String img64 = Base64Util.encode(imageData);
  • 1
  • 2
sign

先看腾讯给出的说明文档: 
这里写图片描述
1.字典升序排序而且还是键值对,可以想到使用java中的TreeMap去处理存储这些数据最为合适 
具体签名部分代码如下:

private String generateAppSign() throws UnsupportedEncodingException {
        Set<String> keySet = mParams.keySet();
        StringBuilder sb = new StringBuilder();
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = mParams.get(key);
            sb.append("&").append(key).append("=").append(URLEncoder.encode(value, "UTF-8"));
        }
        sb.deleteCharAt(0);
        sb.append("&app_key=").append(TencentAIConstants.APP_KEY_AI);
        String sign = MD5.getMD5(sb.toString());
        return sign;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

代码中的mParams参数就是一个TreeMap对象,存储着除sign之外的其他键值对,利用这些键值对计算生成sign字段。

3.发起请求

发起请求这里使用okhttp,不使用HttpClient原因是安卓现在不支持使用HttpClient了,使用okhttp使用范围更广一点而且也很方便实现。主要代码:

MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        Iterator<String> iterator = mParams.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = mParams.get(key);
            builder.addFormDataPart(key, value);
        }
        RequestBody requestBody = builder.build();
        Request request = new Request.Builder().header("Content-Type", "application/x-www-form-urlencoded")
                .url(url)
                .post(requestBody)
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();
        Response response = okHttpClient.newCall(request).execute();
        if (!response.isSuccessful()){
            return ERROR;
        }
        return response.body().string();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

4.使用Builder模式写一个发起请求的类

对于这种部分参数一致,部分参数不同,且逻辑一致的需求使用Builder模式很合适。将上述列出的代码使用builder模式写一个通用的类用于各类请求再合适不过了。代码如下:

public class AiRequestBean {

    public static final String ERROR = "error";
    private TreeMap<String, String> mParams;

    private AiRequestBean() {
        mParams = new TreeMap<>();
        //时间戳
        String time_stamp = System.currentTimeMillis() / 1000 + "";
        //随机字符串
        String nonce_str = TencentAIParamsHelper.getRandomString(10);
        //appId
        String app_id = String.valueOf(TencentAIConstants.APP_ID_AI);
        //将通用参数设置进map中
        mParams.put("app_id", app_id);
        mParams.put("nonce_str", nonce_str);
        mParams.put("time_stamp", time_stamp);
    }

    /**
     * TreeMap生成鉴权信息
     */
    private String generateAppSign() throws UnsupportedEncodingException {
        Set<String> keySet = mParams.keySet();
        StringBuilder sb = new StringBuilder();
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = mParams.get(key);
            sb.append("&").append(key).append("=").append(URLEncoder.encode(value, "UTF-8"));
        }
        sb.deleteCharAt(0);
        sb.append("&app_key=").append(TencentAIConstants.APP_KEY_AI);
        String sign = MD5.getMD5(sb.toString());
        return sign;
    }

    //发起请求
    public String request(String url) throws IOException {
        //生成签名加入到参数列表中
        String sign = generateAppSign();
        mParams.put("sign", sign);
        //使用okhttp发起请求
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        Iterator<String> iterator = mParams.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = mParams.get(key);
            builder.addFormDataPart(key, value);
        }
        RequestBody requestBody = builder.build();
        Request request = new Request.Builder().header("Content-Type", "application/x-www-form-urlencoded")
                .url(url)
                .post(requestBody)
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();
        Response response = okHttpClient.newCall(request).execute();
        if (!response.isSuccessful()){
            return ERROR;
        }
        return response.body().string();
    }

    public static class Builder {
        private AiRequestBean targetBean;

        public Builder() {
            targetBean = new AiRequestBean();
        }

        public AiRequestBean build() {
            return targetBean;
        }

        public Builder addParam(String key, String value) {
            targetBean.mParams.put(key, value);
            return this;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

使用方法也很简单,比如以通用ocr为例,通用ocr文字识别中不同的参数为image,对应的Api为”https://api.ai.qq.com/fcgi-bin/ocr/ocr_generalocr

    public static final String URL4GENERALOCR  = "https://api.ai.qq.com/fcgi-bin/ocr/ocr_generalocr";
//通用ocr文字识别请求
    public String getGeneralOcrResult(File file) throws Exception {
        byte[] imageData = FileUtil.readFileByBytes(file);
        //准备好图片base64数据
        String img64 = Base64Util.encode(imageData);
        String jsonResult = new AiRequestBean.Builder().addParam("image", img64).build().request(TencentAIConstants.URL4GENERALOCR);
        return jsonResult;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

可以看到还是很方便使用的。

Demo代码链接:http://download.csdn.net/download/breeze048/10267182


猜你喜欢

转载自blog.csdn.net/leansmall/article/details/80646942