说明:也是没有段子的一天…在没有段子的日子里…我们继续探讨阿里云的客服机器人…
一、集成方式
官网上提供了两种接入方式,今天楼主就以这两种接入方式进行完整的代码示例。当然还会展示一种“偷懒”的快捷生成代码形式…
友情链接: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条。
可以看到返回的结果、响应码之类的。
重点来了,点击SDK示例可以看到调用的代码生成。
如果使用这里生成的代码,需要引入pom依赖。点击右上角的:SDK依赖信息
pom.xml中引入该依赖就可以使用啦。是不是超级方便,哈哈哈哈…
建议使用升级版SDK吧,功能比较完善。感兴趣的可以看下两者的区别。
好了,好了。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