Android中阿里云文本垃圾内容检测接口的实现

1.注册账号申请 accessKeyId 和 accessKeySecret

2.实现代码

3.注意事项:

1)参考官网的sdk发现,signString 方法中使用了 DatatypeConverter.printBase64Binary(signData) 方法,但是在Android平台中,DatatypeConverter 的 theConverter 为空

2)官网中待签名字符串的拼接方式与接口不一致,需要在如下箭头处增加 ";charset=utf-8"

 

 

public class TextScan {

    private static final String TAG = "TextScan";

    private static final String ENCODING = "UTF-8";
    private static final String ALGORITHM_NAME = "HmacSHA1";
    private static final String RFC822_DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss 'GMT'";

    private static String accessKeyId = "申请的accessKeyId";
    private static String accessKeySecret = "申请的accessKeySecret";
    private static String regionId = "cn-shanghai";
    private static String METHOD = "POST";

    private static byte[] calculateMd5(byte[] binaryData) {
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not found.");
        }
        messageDigest.update(binaryData);
        return messageDigest.digest();
    }

    private static String toBase64String(byte[] binaryData) {
        return new String(Base64.encode(binaryData,Base64.DEFAULT)).trim();
    }

    private static String calculateBase64Md5(byte[] binaryData) {
        return toBase64String(calculateMd5(binaryData));
    }

    private static String getGMTDateStr(Date date){
        SimpleDateFormat rfc822DateFormat = new SimpleDateFormat(RFC822_DATE_FORMAT, Locale.US);
        rfc822DateFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));
        return rfc822DateFormat.format(date);
    }

    private static String getDomain(){
        if("cn-shanghai".equals(regionId)){
            return "green.cn-shanghai.aliyuncs.com";
        }

        if ("cn-beijing".equals(regionId)) {
            return "green.cn-beijing.aliyuncs.com";
        }

        if ("ap-southeast-1".equals(regionId)) {
            return "green.ap-southeast-1.aliyuncs.com";
        }

        if ("us-west-1".equals(regionId)) {
            return "green.us-west-1.aliyuncs.com";
        }

        return "green.cn-shanghai.aliyuncs.com";
    }

    private static String getRequestBodyString(String content){
        JsonObject bodyJo = new JsonObject();

        JsonArray scenesJa = new JsonArray();
        scenesJa.add("antispam");
        bodyJo.add("scenes", scenesJa);

        JsonArray tasksJa = new JsonArray();
        JsonObject taskJo = new JsonObject();
        taskJo.addProperty("content", content);
        tasksJa.add(taskJo);
        bodyJo.add("tasks", tasksJa);

        return JsonUtils.gsonString(bodyJo);
    }

    private static String getContentMD5(String requestBodyString){
        try {
            return calculateBase64Md5(requestBodyString.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    private static String signString(String stringToSign) {
        try {
            Mac mac = Mac.getInstance(ALGORITHM_NAME);
            mac.init(new SecretKeySpec(accessKeySecret.getBytes(ENCODING), ALGORITHM_NAME));
            byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
            return toBase64String(signData);
            //return DatatypeConverter.printBase64Binary(signData);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static void scan(String content){
        String baseUrl = "http://" + getDomain() + "/green/text/scan";

        OkHttpClient okHttpClient = new OkHttpClient()
                .newBuilder()
                .readTimeout(10000, TimeUnit.MILLISECONDS)
                .connectTimeout(10000, TimeUnit.MILLISECONDS)
                .build();

        String requestBodyString = getRequestBodyString(content);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), requestBodyString);

        String contentMD5 = getContentMD5(requestBodyString);
        String date = getGMTDateStr(Calendar.getInstance().getTime());

        String xAcsVersion = "2018-05-09";
        String xAcsSignatureNonce = UUID.randomUUID().toString();
        String xAcsSignatureVersion = "1.0";
        String xAcsSignatureMethod = "HMAC-SHA1";

        /*抽取所有以x-acs-开头的HTTP头。
        对抽取出来的头按字典顺序排序。
        对每个HTTP头,按"HTTP头名称" + ":" + "HTTP头值" + "\n"拼接*/
        String serializedHttpHeaders = "x-acs-signature-method:" + xAcsSignatureMethod + "\n" +
                "x-acs-signature-nonce:" + xAcsSignatureNonce + "\n" +
                "x-acs-signature-version:" + xAcsSignatureVersion + "\n" +
                "x-acs-version:" + xAcsVersion + "\n";

        //按照 uri + "?clientInfo=" + "ClientInfo的JSON字符串"方式拼接URI和 clientInfo参数。
        String serializedUri = "/green/text/scan";

        //"POST\napplication/json\n" + "HTTP头Content-MD5的值" + "\n" + "application/json" + "\n" + "HTTP头Date的值" + "\n" + "序列化请求头" + "序列化uri和query参数"
        String preSignature = "POST\napplication/json\n" + contentMD5 + "\n"
                + "application/json; charset=utf-8" + "\n" + date + "\n" + serializedHttpHeaders + serializedUri;

        /*对步骤3中得到的字符串,使用AccessKeySecret进行HMAC-SHA1算法加密,并进行base64编码。然后将结果放到HTTP头Authorization中的signature:
        "acs" + " " + AccessKeyId + ":" + signature
        */
        String signature = signString(preSignature);
        String authorization = "acs" + " " + accessKeyId + ":" + signature;

        Log.w(TAG, "xAcsVersion = " + xAcsVersion);
        Log.w(TAG, "xAcsSignatureNonce = " + xAcsSignatureNonce);
        Log.w(TAG, "xAcsSignatureVersion = " + xAcsSignatureVersion);
        Log.w(TAG, "xAcsSignatureMethod = " + xAcsSignatureMethod);
        Log.w(TAG, "preSignature = " + preSignature);

        Request request = new Request.Builder()
                .post(requestBody)
                .url(baseUrl)
                .addHeader("Accept", "application/json")
                .addHeader("Content-Type", "application/json")
                .addHeader("Content-MD5", contentMD5)
                .addHeader("Date", date)
                .addHeader("x-acs-signature-method", xAcsSignatureMethod)
                .addHeader("x-acs-signature-nonce", xAcsSignatureNonce)
                .addHeader("x-acs-signature-version", xAcsSignatureVersion)
                .addHeader("x-acs-version", "2018-05-09")
                .addHeader("Authorization", authorization)
                .build();

        Observable
                .just(1)
                .doOnNext(integer -> {
                    try {
                        Response response = okHttpClient.newCall(request).execute();
                        String result = response.body().string();
                        Log.w(TAG, "result = " + result);
                        response.body().close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer integer) {

                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onComplete() {

                    }

                });
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值