阿里云智能客服机器人集成

导读:本篇文章讲解 阿里云智能客服机器人集成,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

阿里云智能客服机器人集成
说明:也是没有段子的一天…在没有段子的日子里…我们继续探讨阿里云的客服机器人…

一、集成方式

官网上提供了两种接入方式,今天楼主就以这两种接入方式进行完整的代码示例。当然还会展示一种“偷懒”的快捷生成代码形式…

友情链接:SDK、API地址:https://help.aliyun.com/document_detail/60757.html

1.1、API形式

在这里插入图片描述

1.2、SDK形式

在这里插入图片描述

二、集成示例

2.1、SDK接入方式

害,就从创建一个新的SpringBoot项目开始“举栗子”吧。wshanshi手把手教学,手把手带你入坑哈哈哈啊啊哈…
在这里插入图片描述

2.1.1、新建一个SpringBoot项目

想尝试Demo,方便偷懒的兄弟们,往这里看了…
【插图-敲黑板了】
直接在Spring官网生成SpringBoot项目,点点填填就行了,So Easy~。

友情链接:【在线快速创建SpringBoot项目

嘶…泪目了啊…楼主先操作为敬!(主要是想偷懒,哈哈哈哈…)

2.1.2、引入Pom依赖

IDEA中打开项目,pom.xml中引入阿里云aliyun-java-sdk-chatbot依赖、aliyun-java-sdk-core依赖。

<dependency>
   <groupId>com.aliyun</groupId>
   <artifactId>aliyun-java-sdk-chatbot</artifactId>
   <version>1.0.0</version>
</dependency>
	
<dependency>
   <groupId>com.aliyun</groupId>
   <artifactId>aliyun-java-sdk-core</artifactId>
   <version>4.5.2</version>
</dependency>	
2.1.3、定义接口

定义问答调用接口,此处示例为SDK形式调用。

/**
 * 问答 SDK形式调用
 *
 * @param utterance
 * @param sessionId
 * @return
 */
Map<String, Object> chatAnswer(String utterance, String sessionId);
2.1.4、接口实现方法

问答调用接口,实现方法如下。

@Override
public Map<String, Object> chatAnswer(String utterance, String sessionId) {
    DefaultProfile.addEndpoint(popRegion, popProduct, popDomain);
    IClientProfile profile = DefaultProfile.getProfile(popRegion, accessKeyId, accessKeySecret);
    DefaultAcsClient client = new DefaultAcsClient(profile);
    //固定入参
    CommonRequest commonRequest = new CommonRequest();
    commonRequest.setSysProduct(popProduct);
    commonRequest.setSysMethod(MethodType.GET);
    //根据API会有变化
    commonRequest.setSysAction("Chat");
    commonRequest.setSysVersion("2017-10-11");
    commonRequest.putQueryParameter("Utterance", utterance);
    //机器人id
    commonRequest.putQueryParameter("InstanceId", instanceId);
    try {
        CommonResponse commonResponse = client.getCommonResponse(commonRequest);
        return parsingRes(commonResponse.getData());
    } catch (Exception e) {
        e.getMessage();
    }
    return null;
}

方法所需常量定义

/**
 * 阿里云颁发给用户的访问服务所用的密钥ID(此处换为你的密钥)
 */
private final String accessKeyId = "xxxxxxx";
/**
 * 阿里云颁发给用户的访问服务所用的KeySecret(此处换为你的密钥)
 */
private final String accessKeySecret = "xxxxxxx";
/**
 * 机器人id(此处换为你的机器人实例)
 */
private final String instanceId = "xxxxxxxx";
/**
 * 云小蜜 API 的服务接入地址(上海、杭州)
 */
private final String url = "http://chatbot.cn-shanghai.aliyuncs.com";
/**
 * api版本号
 */
private final String version = "2017-10-11";
/**
 * 产品区域(上海、杭州)
 */
private final String popRegion = "cn-shanghai";
/**
 * 产品类型
 */
private final String popProduct = "Chatbot";
/**
 * domain 
 */
private final String popDomain = "chatbot.cn-shanghai.aliyuncs.com";

阿里云响应数据解析方法

/**
 * 响应数据解析
 *
 * @param res
 * @return
 */
private Map<String, Object> parsingRes(String res) {
    if (JSONUtil.isJson(res)) {
        Map<String, Object> resultMap = new HashMap<>();
        JSONObject jo = JSONUtil.parseObj(res);
        resultMap.put("SessionId", jo.getStr("SessionId"));
        JSONArray ja = JSONUtil.parseArray(jo.getStr("Messages"));
        JSONObject messageJo = JSONUtil.parseObj(ja.get(0));
        String type = messageJo.getStr("Type");
        resultMap.put("Type", type);
        switch (type) {
            case "Knowledge":
                JSONObject knowledgeJo = JSONUtil.parseObj(messageJo.getStr("Knowledge"));
                resultMap.put("Content", knowledgeJo.getStr("Content"));
                break;
            case "Text":
                JSONObject textJo = JSONUtil.parseObj(messageJo.getStr("Text"));
                resultMap.put("Content", textJo.getStr("Content"));
                break;
            case "Recommend":
                List<String> content = new ArrayList<>();
                JSONArray recommendJa = JSONUtil.parseArray(messageJo.getStr("Recommends"));
                for (Object o : recommendJa) {
                    JSONObject recommendJo = JSONUtil.parseObj(o);
                    content.add(recommendJo.getStr("Title"));
                }
                resultMap.put("Content", content);
                break;
            default:
                break;
        }
        return resultMap;
    }
    return null;
}
2.1.5、Controller中定义
/**
 * 机器人对话 SDK形式
 *
 * @param utterance 用户输入的信息
 * @param sessionId
 * @return
 */
@GetMapping("/chatAnswer")
public Map<String, Object> chatAnswer(@RequestParam(name = "utterance") String utterance, @RequestParam(name = "sessionId", required = false) String sessionId) {
    return chatbotService.chatAnswer(utterance, sessionId);
}
2.1.6、代码运行效果

如上步骤所示,代码都OK了。那就尝试用PostMan测试一下吧!
在这里插入图片描述
Nice,可以看到基本会话是已经可以了(如果配置了对应的会话工厂,该会话接口也是支持的哦)。复杂点一的会话工厂配置及调用,可参照wshanshi上一篇文章哦!
【插图-你懂得】
友情链接:【阿里云智能客服机器人,自定义函数调用配置

2.1.7、SDK代码自动生成

有人就问了:“wshanshi你是不是看官网上例子写的!!!官网上SDK调用就只有那一个例子,我想查询别的怎么搞呢?”

在这里插入图片描述

比如,我想实现搜索框输入,根据用户输入的关键字匹配阿里云指定的FAQ库,进行推荐提示,SDK调用怎么操作?像腾讯云这种。

嘿,你别说。还真行,办法嘛还是有的,你叫我靓女我就告诉你…
【插图--坏笑】
不知道大家发现没,其实阿里云可以在线调试的。代码都能直接生成,直接粘过来改改,不香嘛。哈哈哈哈哈…

看这里,没错就是API这里。不要疑惑,就是API这里,没跑偏。
在这里插入图片描述
就拿FAQ库模糊匹配举例子吧。点击这个API可以看到右侧有调试框,可以在线调试的。
在这里插入图片描述
点击调试后,可以根据个人需求填写相关请求参数。这是个分页接口,不传分页信息默认取10条。尝试发现,每次请求最大限制为10000条。
在这里插入图片描述
可以看到返回的结果、响应码之类的。
图片: https://uploader.shimo.im/f/kgS9aBPSn8QhMmpM.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2Mzg5NTY4OTMsImciOiJ0M1BUS1IzVjljRGtHV1Z2IiwiaWF0IjoxNjM4OTU2NTkzLCJ1c2VySWQiOjY1NTk2MjQ5fQ.zAJbCsDQyj8sE-00I0yrO67ESmshJgz4HGxWeklaYrU
重点来了,点击SDK示例可以看到调用的代码生成。
图片: https://uploader.shimo.im/f/52MayJ49icGV5hfy.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2Mzg5NTY4OTMsImciOiJ0M1BUS1IzVjljRGtHV1Z2IiwiaWF0IjoxNjM4OTU2NTkzLCJ1c2VySWQiOjY1NTk2MjQ5fQ.zAJbCsDQyj8sE-00I0yrO67ESmshJgz4HGxWeklaYrU
如果使用这里生成的代码,需要引入pom依赖。点击右上角的:SDK依赖信息
在这里插入图片描述
pom.xml中引入该依赖就可以使用啦。是不是超级方便,哈哈哈哈…
【插图-棒】
建议使用升级版SDK吧,功能比较完善。感兴趣的可以看下两者的区别。
图片: https://uploader.shimo.im/f/oPoWmyb3kQPFuAcL.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2Mzg5NTY4OTMsImciOiJ0M1BUS1IzVjljRGtHV1Z2IiwiaWF0IjoxNjM4OTU2NTkzLCJ1c2VySWQiOjY1NTk2MjQ5fQ.zAJbCsDQyj8sE-00I0yrO67ESmshJgz4HGxWeklaYrU
好了,好了。SDK调用的示例就展示这么多啦!
在这里插入图片描述

2.2、API接入方式

API接入方式较为繁琐,需要验签之类的。大家都懂得,也不多说啦,直接上代码。

2.2.1、定义接口

定义问答调用接口,此处示例为API形式调用。

/**
 * 问答 API形式调用
 *
 * @param utterance
 * @param sessionId
 * @return
 */
Map<String, Object> chat(String utterance, String sessionId);
2.2.2、接口实现方法

问答调用接口,实现方法如下。(方法所需常量定义,同SDK示例中一致)

@Override
public Map<String, Object> chat(String utterance, String sessionId) {
    if (StrUtil.isBlank(utterance)) {
        return null;
    }
    try {
        String timeStamp = AliETSignUtil.getSolrDate(new Date());
        String nonce_str = UUID.randomUUID().toString();
        //全部参数
        HashMap<String, Object> hashMap = AliETSignUtil.transBean2Map(new BeeBotRequest("JSON", version, accessKeyId, "", " HMAC-SHA1", timeStamp, "1.0", nonce_str, "Chat", instanceId, utterance));
        if (StrUtil.isNotBlank(sessionId)) {
            hashMap.put("SessionId", sessionId);
        }
        String sign = AliETSignUtil.getSignature("GET", hashMap, accessKeySecret);
        hashMap.put("Signature", sign);
        String param = AliETSignUtil.getParams(hashMap);
        String result = AliYunHttpUtils.sendGet(url, param);
        return parsingRes(result);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}
2.2.3、Controller中定义
/**
 * 机器人对话 API形式
 *
 * @param utterance 用户输入的信息
 * @param sessionId
 * @return
 */
@GetMapping("/chat")
public Map<String, Object> chat(@RequestParam(name = "utterance") String utterance, @RequestParam(name = "sessionId", required = false) String sessionId) {
    return chatbotService.chat(utterance, sessionId);
}
2.2.4、工具类

所需工具类:AESDecode

package com.wshanshi.chatbot.util.aly;
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
public class AESDecode {
    /*
     * 计算MD5+BASE64
     */
    public static String MD5Base64(byte[] s) throws UnsupportedEncodingException {
        if (s == null){
            return null;
        }
        String encodeStr = "";
        //string 编码必须为utf-8
        MessageDigest mdTemp;
        try {
            mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(s);
            byte[] md5Bytes = mdTemp.digest();
            BASE64Encoder b64Encoder = new BASE64Encoder();
            encodeStr = b64Encoder.encode(md5Bytes);
            /* java 1.8以上版本支持
            Encoder encoder = Base64.getEncoder();
            encodeStr = encoder.encodeToString(md5Bytes);
            */
        } catch (Exception e) {
            throw new Error("Failed to generate MD5 : " + e.getMessage());
        }
        return encodeStr;
    }
    /*
     * 计算MD5+BASE64
     */
    public static String MD5Base64(String s) throws Exception {
        if (s == null)
            return null;
        String encodeStr = "";
        //编码为utf-8
        byte[] utfBytes = s.getBytes("UTF-8");
        MessageDigest mdTemp;
        try {
            mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(utfBytes);
            byte[] md5Bytes = mdTemp.digest();
            BASE64Encoder b64Encoder = new BASE64Encoder();
            encodeStr = b64Encoder.encode(md5Bytes);
        } catch (Exception e) {
            throw new Error("Failed to generate MD5 : " + e.getMessage());
        }
        return encodeStr;
    }
    /*
     * 计算 HMAC-SHA1
     */
    public static String HMACSha1(String data, String key) {
        String result;
        try {
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(data.getBytes());
            result = (new BASE64Encoder()).encode(rawHmac);
        } catch (Exception e) {
            throw new Error("Failed to generate HMAC : " + e.getMessage());
        }
        return result;
    }
}

所需工具类:AliETHttpUtil

package com.wshanshi.chatbot.util.aly;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class AliETHttpUtil {
   public static HttpResponse sendAsrPost(byte[] audioData,
         String audioFormat, int sampleRate, String url, String ak_id,
         String ak_secret) {
      PrintWriter out = null;
      BufferedReader in = null;
      String result = "";
      HttpResponse response = new HttpResponse();
      try {
         URL realUrl = new URL(url);
         /*
          * http header 参数
          */
         String method = "POST";
         String accept = "application/json";
         String content_type = "audio/" + audioFormat + ";samplerate="
               + sampleRate;
         int length = audioData.length;
         String date = toGMTString(new Date());
         // 1.对body做MD5+BASE64加密
         String bodyMd5 = AESDecode.MD5Base64(audioData);
         String md52 = AESDecode.MD5Base64(bodyMd5.getBytes());
         String stringToSign = method + "\n" + accept + "\n" + md52 + "\n"
               + content_type + "\n" + date;
         // 2.计算 HMAC-SHA1
         String signature = AESDecode.HMACSha1(stringToSign, ak_secret);
         // 3.得到 authorization header
         String authHeader = "Dataplus " + ak_id + ":" + signature;
         // 打开和URL之间的连接
         HttpURLConnection conn = (HttpURLConnection) realUrl
               .openConnection();
         // 设置通用的请求属性
         conn.setRequestProperty("accept", accept);
         conn.setRequestProperty("content-type", content_type);
         conn.setRequestProperty("date", date);
         conn.setRequestProperty("Authorization", authHeader);
         conn.setRequestProperty("Content-Length", String.valueOf(length));
         // 发送POST请求必须设置如下两行
         conn.setDoOutput(true);
         conn.setDoInput(true);
         // 获取URLConnection对象对应的输出流
         OutputStream stream = conn.getOutputStream();
         // 发送请求参数
         stream.write(audioData);
         // flush输出流的缓冲
         stream.flush();
         stream.close();
         response.setStatus(conn.getResponseCode());
         // 定义BufferedReader输入流来读取URL的响应
         if (response.getStatus() == 200) {
            in = new BufferedReader(new InputStreamReader(
                  conn.getInputStream()));
         } else {
            in = new BufferedReader(new InputStreamReader(
                  conn.getErrorStream()));
         }
         String line;
         while ((line = in.readLine()) != null) {
            result += line;
         }
         if (response.getStatus() == 200) {
            response.setResult(result);
            response.setMassage("OK");
         } else {
            response.setMassage(result);
         }
         System.out.println("post response status code: ["
               + response.getStatus() + "], response massage : ["
               + response.getMassage() + "] ,result :["
               + response.getResult() + "]");
      } catch (Exception e) {
         System.out.println("发送 POST 请求出现异常!" + e);
         e.printStackTrace();
      }
      // 使用finally块来关闭输出流、输入流
      finally {
         try {
            if (out != null) {
               out.close();
            }
            if (in != null) {
               in.close();
            }
         } catch (IOException ex) {
            ex.printStackTrace();
         }
      }
      return response;
   }
    /*
     * 发送POST请求
     */
    public static String sendPost(String url, String body, String ak_id, String ak_secret) throws Exception {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        int statusCode = 200;
        try {
            URL realUrl = new URL(url);
            /*
             * http header 参数
             */
            String method = "POST";
            String accept = "json";
            String content_type = "application/json";
            String path = realUrl.getFile();
            String date = toGMTString(new Date());
            String bodyMd5 = "";
            // 1.对body做MD5+BASE64加密
            if(body != null && body != ""){
                bodyMd5 = AESDecode.MD5Base64(body);
            }
            String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date ;
            // 2.计算 HMAC-SHA1
            String signature = AESDecode.HMACSha1(stringToSign, ak_secret);
            // 3.得到 authorization header
            String authHeader = "Dataplus " + ak_id + ":" + signature;
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", accept);
            conn.setRequestProperty("content-type", content_type);
            conn.setRequestProperty("date", date);
            conn.setRequestProperty("Authorization", authHeader);
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(body);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            statusCode = ((HttpURLConnection)conn).getResponseCode();
            if(statusCode != 200) {
                in = new BufferedReader(new InputStreamReader(((HttpURLConnection)conn).getErrorStream()));
            } else {
                in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            }
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        if (statusCode != 200) {
            throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
        }
        return result;
    }
    /*
     * GET请求
     */
    public static String sendGet(String url, String ak_id, String ak_secret) throws Exception {
        String result = "";
        BufferedReader in = null;
        int statusCode = 200;
        try {
            URL realUrl = new URL(url);
            /*
             * http header 参数
             */
            String method = "GET";
            String accept = "json";
            String content_type = "application/json";
            String path = realUrl.getFile();
            String date = toGMTString(new Date());
            // 1.对body做MD5+BASE64加密
//             String bodyMd5 = MD5Base64(body);
            String stringToSign = method + "\n" + accept + "\n" + "" + "\n" + content_type + "\n" + date ;
            // 2.计算 HMAC-SHA1
            String signature = AESDecode.HMACSha1(stringToSign, ak_secret);
            // 3.得到 authorization header
            String authHeader = "Dataplus " + ak_id + ":" + signature;
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", accept);
            connection.setRequestProperty("content-type", content_type);
            connection.setRequestProperty("date", date);
            connection.setRequestProperty("Authorization", authHeader);
            connection.setRequestProperty("Connection", "keep-alive");
            // 建立实际的连接
            connection.connect();
            // 定义 BufferedReader输入流来读取URL的响应
            statusCode = ((HttpURLConnection)connection).getResponseCode();
            if(statusCode != 200) {
                in = new BufferedReader(new InputStreamReader(((HttpURLConnection)connection).getErrorStream()));
            } else {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            }
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (statusCode != 200) {
            throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result);
        }
        return result;
    }
    /*
     * 等同于javaScript中的 new Date().toUTCString();
     */
    public static String toGMTString(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK);
        df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
        return df.format(date);
    }
}

所需工具类:AliETSignUtil

package com.wshanshi.chatbot.util.aly;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * 阿里计算Sign、UTC时间 等公共方法
 */
public class AliETSignUtil {
    private static final String ENCODING = "UTF-8";
    /**
     * 将java Date格式转成Solr支持的UTC时间
     *
     * @param date
     * @return
     */
    public static String getSolrDate(Date date) {
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss");
        sdf2.setTimeZone(TimeZone.getTimeZone("UTC"));
        String result = sdf1.format(date) + "T" + sdf2.format(date) + "Z";
        return result;
    }
    public static HashMap<String, Object> transBean2Map(Object obj) {
        if (obj == null) {
            return null;
        }
        HashMap<String, Object> map = new HashMap<String, Object>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!key.equals("class")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    if (key != null && key != "") {
                        key = key.substring(0, 1).toUpperCase() + key.substring(1);
                    }
                    map.put(key, value);
                }
            }
        } catch (Exception e) {
            System.out.println("transBean2Map Error " + e);
        }
        return map;
    }
    public static HashMap<String, Object> convertToMap(Object obj) throws Exception {
        HashMap<String, Object> map = new HashMap<String, Object>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (int i = 0, len = fields.length; i < len; i++) {
            String varName = fields[i].getName();
            boolean accessFlag = fields[i].isAccessible();
            fields[i].setAccessible(true);
            Object o = fields[i].get(obj);
            if (o != null)
                map.put(varName, o.toString());
            fields[i].setAccessible(accessFlag);
        }
        return map;
    }
    /**
     * SIGN签名生成算法-JAVA版本
     *
     * @param method   请求方式 GET | POST
     * @param params   请求参数集,所有参数必须已转换为字符串类型
     * @param akSecret Access Key Secret
     * @return 签名
     * @throws IOException
     */
    public static String getSignature(String method, HashMap<String, Object> params, String akSecret) throws IOException {
        // 先将参数以其参数名的字典序升序进行排序
        Map<String, Object> sortedParams = new TreeMap<>(params);
        Set<Map.Entry<String, Object>> entrys = sortedParams.entrySet();
        // 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
        StringBuilder CanonicalizedQueryString = new StringBuilder();
        for (Map.Entry<String, Object> param : entrys) {
            //sign参数 和 空值参数 不加入算法
            if (param.getValue() != null && !"".equals(param.getKey().trim()) && !"Signature".equals(param.getKey().trim()) && !"".equals(param.getValue().toString().trim())) {
                CanonicalizedQueryString.append(param.getKey().trim()).append("=").append(URLEncoder.encode(param.getValue().toString().trim(), ENCODING)).append("&");
            }
        }
        String signStr = method + "&" + percentEncode("/") + "&" + percentEncode(CanonicalizedQueryString.toString().substring(0, CanonicalizedQueryString.toString().length() - 1));
        // 使用MD5对待签名串求签
        try {
            String sign = AESDecode.HMACSha1(signStr, akSecret + "&");
            return sign;
        } catch (Exception ex) {
            throw new IOException(ex);
        }
    }
    /**
     * 再次处理。适用于阿里云接口
     *
     * @param value 需要URLEncoder的参数
     * @return String
     * @throws UnsupportedEncodingException
     */
    private static String percentEncode(String value) throws UnsupportedEncodingException {
        return value != null ? URLEncoder.encode(value, ENCODING)
                .replace("+", "%20").replace("*", "%2A").replace("%7E", "~")
                : null;
    }
    /**
     * 获取拼接的参数
     *
     * @param params
     * @return
     * @throws IOException
     */
    public static String getParams(HashMap<String, Object> params) throws IOException {
        //  先将参数以其参数名的字典序升序进行排序
        Map<String, Object> sortedParams = new TreeMap<>(params);
        Set<Map.Entry<String, Object>> entrys = sortedParams.entrySet();
        // 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
        StringBuilder baseString = new StringBuilder();
        for (Map.Entry<String, Object> param : entrys) {
            //sign参数 和 空值参数 不加入算法
            if (param.getValue() != null && !"".equals(param.getKey().trim())
                    && !"".equals(param.getKey().trim())
                    && !"".equals(param.getValue().toString().trim())) {
                baseString
                        .append(param.getKey().trim())
                        .append("=")
                        .append(URLEncoder.encode(param.getValue().toString().trim(), ENCODING)).append("&");
            }
        }
        return baseString.deleteCharAt(baseString.length() - 1).toString();
    }
}

所需工具类:AliYunFaceHttpUtils

package com.wshanshi.chatbot.util.aly;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * 阿里云官方HttpUtils
 * HttpUtils下载
 * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
 */
public class AliYunFaceHttpUtils {
    /**
     * get
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doGet(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpGet request = new HttpGet(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        return (HttpResponse) httpClient.execute(request);
    }
    /**
     * post form
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param bodys
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      Map<String, String> bodys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (bodys != null) {
            List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
            for (String key : bodys.keySet()) {
                nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
            }
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
            request.setEntity(formEntity);
        }
        return (HttpResponse) httpClient.execute(request);
    }
    /**
     * Post String
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      String body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (StringUtils.isNotBlank(body)) {
            request.setEntity(new StringEntity(body, "utf-8"));
        }
        return (HttpResponse) httpClient.execute(request);
    }
    /**
     * Post stream
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String, String> headers,
                                      Map<String, String> querys,
                                      byte[] body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPost request = new HttpPost(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (body != null) {
            request.setEntity(new ByteArrayEntity(body));
        }
        return (HttpResponse) httpClient.execute(request);
    }
    /**
     * Put String
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     String body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (StringUtils.isNotBlank(body)) {
            request.setEntity(new StringEntity(body, "utf-8"));
        }
        return (HttpResponse) httpClient.execute(request);
    }
    /**
     * Put stream
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     byte[] body)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        if (body != null) {
            request.setEntity(new ByteArrayEntity(body));
        }
        return (HttpResponse) httpClient.execute(request);
    }
    /**
     * Delete
     *
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doDelete(String host, String path, String method,
                                        Map<String, String> headers,
                                        Map<String, String> querys)
            throws Exception {
        HttpClient httpClient = wrapClient(host);
        HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(), e.getValue());
        }
        return (HttpResponse) httpClient.execute(request);
    }
    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if (!StringUtils.isBlank(path)) {
            sbUrl.append(path);
        }
        if (null != querys) {
            StringBuilder sbQuery = new StringBuilder();
            for (Map.Entry<String, String> query : querys.entrySet()) {
                if (0 < sbQuery.length()) {
                    sbQuery.append("&");
                }
                if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
                    sbQuery.append(query.getValue());
                }
                if (!StringUtils.isBlank(query.getKey())) {
                    sbQuery.append(query.getKey());
                    if (!StringUtils.isBlank(query.getValue())) {
                        sbQuery.append("=");
                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                    }
                }
            }
            if (0 < sbQuery.length()) {
                sbUrl.append("?").append(sbQuery);
            }
        }
        return sbUrl.toString();
    }
    private static HttpClient wrapClient(String host) {
        HttpClient httpClient = new DefaultHttpClient();
        if (host.startsWith("https://")) {
            sslClient(httpClient);
        }
        return httpClient;
    }
    private static void sslClient(HttpClient httpClient) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] xcs, String str) {
                }
                public void checkServerTrusted(X509Certificate[] xcs, String str) {
                }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = httpClient.getConnectionManager();
            SchemeRegistry registry = ccm.getSchemeRegistry();
            registry.register(new Scheme("https", 443, ssf));
        } catch (KeyManagementException ex) {
            throw new RuntimeException(ex);
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }
}

所需工具类:AliYunHttpUtils

package com.wshanshi.chatbot.util.aly;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

/**
 * 阿里-云小蜜 HTTP工具类
 */
public class AliYunHttpUtils {
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
//       Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
//       for (String key : map.keySet()) {
//          System.out.println(key + "--->" + map.get(key));
//       }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e.getMessage());
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
}

所需工具类:BeeBotRequest

package com.wshanshi.chatbot.util.aly;
import com.alibaba.fastjson.annotation.JSONField;
/**
 * 云小蜜请求对象
 */
public class BeeBotRequest extends GeneralRequest {
    /**
     * @param format           返回值的类型,支持 JSON 与 XML。默认为 XML。
     * @param version          API 版本号,本版本对应为2017-10-11。
     * @param accessKeyId      阿里云颁发给用户的访问服务所用的密钥 ID。
     * @param signature        签名结果串
     * @param signatureMethod  签名方式,目前支持 HMAC-SHA1。
     * @param timestamp        请求的时间戳。日期格式按照 ISO8601 标准表示,并需要使用UTC时间。格式为:YYYY-MM-DDThh:mm:ssZ
     * @param signatureVersion 签名算法版本,目前版本是 1.0。
     * @param signatureNonce   唯一随机数
     * @param action           系统规定参数,取值:Chat
     * @param instanceId       机器人实例ID
     * @param utterance        机器人访问者的输入
     */
    public BeeBotRequest(String format, String version, String accessKeyId,
                         String signature, String signatureMethod, String timestamp,
                         String signatureVersion, String signatureNonce, String action,
                         String instanceId, String utterance) {
        super(format, version, accessKeyId, signature, signatureMethod,
                timestamp, signatureVersion, signatureNonce);
        Action = action;
        InstanceId = instanceId;
        Utterance = utterance;
    }
    /**
     * @param accessKeyId    阿里云颁发给用户的访问服务所用的密钥 ID。
     * @param timestamp      请求的时间戳。日期格式按照 ISO8601 标准表示,并需要使用UTC时间。格式为:YYYY-MM-DDThh:mm:ssZ
     * @param signatureNonce 唯一随机数
     * @param action         系统规定参数,取值:Chat
     * @param instanceId     机器人实例ID
     * @param utterance      机器人访问者的输入
     */
    public BeeBotRequest(String accessKeyId,
                         String timestamp,
                         String signatureNonce, String action,
                         String instanceId, String utterance) {
        super(accessKeyId, timestamp, signatureNonce);
        Action = action;
        InstanceId = instanceId;
        Utterance = utterance;
    }
    @JSONField(name = "Action")
    private String Action;
    @JSONField(name = "InstanceId")
    private String InstanceId;
    @JSONField(name = "Utterance")
    private String Utterance;
    @JSONField(name = "SessionId")
    private String SessionId;
    @JSONField(name = "KnowledgeId")
    private String KnowledgeId;
    @JSONField(name = "SenderId")
    private String SenderId;
    @JSONField(name = "SenderNick")
    private String SenderNick;
    @JSONField(name = "Tag")
    private String Tag;
    public String getAction() {
        return Action;
    }
    public void setAction(String action) {
        Action = action;
    }
    public String getInstanceId() {
        return InstanceId;
    }
    public void setInstanceId(String instanceId) {
        InstanceId = instanceId;
    }
    public String getUtterance() {
        return Utterance;
    }
    public void setUtterance(String utterance) {
        Utterance = utterance;
    }
    public String getSessionId() {
        return SessionId;
    }
    public void setSessionId(String sessionId) {
        SessionId = sessionId;
    }
    public String getKnowledgeId() {
        return KnowledgeId;
    }
    public void setKnowledgeId(String knowledgeId) {
        KnowledgeId = knowledgeId;
    }
    public String getSenderId() {
        return SenderId;
    }
    public void setSenderId(String senderId) {
        SenderId = senderId;
    }
    public String getSenderNick() {
        return SenderNick;
    }
    public void setSenderNick(String senderNick) {
        SenderNick = senderNick;
    }
    public String getTag() {
        return Tag;
    }
    public void setTag(String tag) {
        Tag = tag;
    }
}

所需工具类:GeneralRequest

package com.wshanshi.chatbot.util.aly;
import com.alibaba.fastjson.annotation.JSONField;
/***
 * 公共请求头对象
 */
public class GeneralRequest {
   @JSONField(name="Format")
   private String Format;
   @JSONField(name="Version")
   private String Version;
   @JSONField(name="AccessKeyId")
   private String AccessKeyId;
   @JSONField(name="Signature")
   private String Signature;
   @JSONField(name="SignatureMethod")
   private String SignatureMethod;
   @JSONField(name="Timestamp")
   private String Timestamp;
   @JSONField(name="SignatureVersion")
   private String SignatureVersion;
   @JSONField(name="SignatureNonce")
   private String SignatureNonce;
   public GeneralRequest(String format, String version, String accessKeyId,
         String signature, String signatureMethod, String timestamp,
         String signatureVersion, String signatureNonce) {
      super();
      Format = format;
      Version = version;
      AccessKeyId = accessKeyId;
      Signature = signature;
      SignatureMethod = signatureMethod;
      Timestamp = timestamp;
      SignatureVersion = signatureVersion;
      SignatureNonce = signatureNonce;
   }
   public GeneralRequest(String accessKeyId,String timestamp,String signatureNonce) {
      super();
      Format = "JSON";
      Version = "2017-10-11";
      AccessKeyId = accessKeyId;
      SignatureMethod = "HMAC-SHA1";
      Timestamp = timestamp;
      SignatureVersion = "1.0";
      SignatureNonce = signatureNonce;
   }
   public String getFormat() {
      return Format;
   }
   public void setFormat(String format) {
      Format = format;
   }
   public String getVersion() {
      return Version;
   }
   public void setVersion(String version) {
      Version = version;
   }
   public String getAccessKeyId() {
      return AccessKeyId;
   }
   public void setAccessKeyId(String accessKeyId) {
      AccessKeyId = accessKeyId;
   }
   public String getSignature() {
      return Signature;
   }
   public void setSignature(String signature) {
      Signature = signature;
   }
   public String getSignatureMethod() {
      return SignatureMethod;
   }
   public void setSignatureMethod(String signatureMethod) {
      SignatureMethod = signatureMethod;
   }
   public String getTimestamp() {
      return Timestamp;
   }
   public void setTimestamp(String timestamp) {
      Timestamp = timestamp;
   }
   public String getSignatureVersion() {
      return SignatureVersion;
   }
   public void setSignatureVersion(String signatureVersion) {
      SignatureVersion = signatureVersion;
   }
   public String getSignatureNonce() {
      return SignatureNonce;
   }
   public void setSignatureNonce(String signatureNonce) {
      SignatureNonce = signatureNonce;
   }
   
}

所需工具类:HttpResponse

package com.wshanshi.chatbot.util.aly;
public class HttpResponse {
    private int status;
    private String result;
    private String massage;
   public int getStatus() {
      return status;
   }
   public void setStatus(int status) {
      this.status = status;
   }
   public String getResult() {
      return result;
   }
   public void setResult(String result) {
      this.result = result;
   }
   public String getMassage() {
      return massage;
   }
   public void setMassage(String massage) {
      this.massage = massage;
   }
}
2.2.5、代码运行效果

如上步骤所示,API形式代码也OK了。PostMan测试一下!
在这里插入图片描述
可以看到,效果是一样的。

两种方法,都可以。推荐使用SDK形式,因为真的很方便,哈哈哈哈哈…别忘记点赞哦
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/115759.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!