作者:张振琦

前篇介绍了API v2 如何调用,本篇以获取工单列表接口为例,介绍如果使用Java调用Udesk的API v2接口。先看一下获取工单列表接口的说明:


注:完整的接口说明请参考Udesk官网开发者中心:https://www.udesk.cn/doc/

简单分析一下这个接口,接口相对地址是/tickets,请求方式是GET,有两个可选参数page和per_page,默认值为 第一页,每页20条记录。

按照前篇的总结,我们开始第一步获取open_api_token,需要发送一个post请求给log_in,并传入超管的邮箱和密码。既然要发请求,就需要准备一个HttpsUtil ,直接提供给大家,该HttpsUtil提供了Udesk API v2 会使用到的全部请求方式。
HttpsUtil.java

package com.udesk.support.common;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;public class HttpsUtil {private static final class DefaultTrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return null;}}private static HttpsURLConnection getHttpsURLConnection(String uri, String method,String content_type) throws IOException {SSLContext ctx = null;try {ctx = SSLContext.getInstance("TLS");ctx.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom());} catch (KeyManagementException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}SSLSocketFactory ssf = ctx.getSocketFactory();URL url = new URL(uri);HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection();httpsConn.setSSLSocketFactory(ssf);httpsConn.setHostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String arg0, SSLSession arg1) {return true;}});httpsConn.setRequestMethod(method);if(content_type.equals("json"))httpsConn.setRequestProperty("Content-type", "application/json");if(content_type.equals("stream"))httpsConn.setRequestProperty("Content-type", "application/octet-stream");httpsConn.setDoInput(true);httpsConn.setDoOutput(true);return httpsConn;}private static byte[] getBytesFromStream(InputStream is) throws IOException {ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] kb = new byte[1024];int len;while ((len = is.read(kb)) != -1) {baos.write(kb, 0, len);}byte[] bytes = baos.toByteArray();baos.close();is.close();return bytes;}private static void setBytesToStream(OutputStream os, byte[] bytes) throws IOException {ByteArrayInputStream bais = new ByteArrayInputStream(bytes);byte[] kb = new byte[1024];int len;while ((len = bais.read(kb)) != -1) {os.write(kb, 0, len);}os.flush();os.close();bais.close();}private static void setFileToStream(OutputStream os, String filePath) throws IOException {    FileInputStream inputStream = new FileInputStream(filePath);byte[] data = new byte[2048];int len = 0;int sum = 0;while ((len = inputStream.read(data)) != -1) {//将读取到的本地文件流读取到HttpsURLConnection,进行上传os.write(data, 0, len);sum = len + sum;}os.flush();os.close();inputStream.close();System.out.println("上传图片大小为:" + sum);}public static String doGet(String uri) throws IOException {HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "GET", "json");return new String (getBytesFromStream(httpsConn.getInputStream()),"utf-8");}public static String doGetNoJson(String uri) throws IOException {HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "GET", "");return new String (getBytesFromStream(httpsConn.getInputStream()),"utf-8");}public static String doPost(String uri, String data) throws IOException {HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "POST", "json");setBytesToStream(httpsConn.getOutputStream(), data.getBytes());return new String (getBytesFromStream(httpsConn.getInputStream()),"utf-8");}public static String doPostFile(String uri, String filePath) throws IOException {HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "POST", "stream");setFileToStream(httpsConn.getOutputStream(), filePath);return new String (getBytesFromStream(httpsConn.getInputStream()),"utf-8");}public static String doPut(String uri, String data) throws IOException {HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "PUT", "json");setBytesToStream(httpsConn.getOutputStream(), data.getBytes());return new String (getBytesFromStream(httpsConn.getInputStream()),"utf-8");}public static String doPutFile(String uri, String filePath) throws IOException {HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "PUT", "stream");setFileToStream(httpsConn.getOutputStream(), filePath);return new String (getBytesFromStream(httpsConn.getInputStream()),"utf-8");}public static String doDelete(String uri) throws IOException {HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "DELETE", "json");return new String (getBytesFromStream(httpsConn.getInputStream()),"utf-8");}public static String doDelete(String uri,String data) throws IOException {HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "DELETE", "json");setBytesToStream(httpsConn.getOutputStream(), data.getBytes());return new String (getBytesFromStream(httpsConn.getInputStream()),"utf-8");}
}

有了HttpsUtil,获取open_api_token就简单了。使用超管的邮箱和密码拼接JSON串,调用HttpsUtil.doPost方法,得到返回结果。解析结果对象的code值,如果是1000,则说明获取成功。

private boolean login()
{String url = this.rooturl+"/log_in";String data = "{\"email\": \""+this.email+"\",\"password\": \""+this.password+"\"}";try {String result = HttpsUtil.doPost(url, data);Gson gson = new Gson();LoginResult loginResult = gson.fromJson(result, LoginResult.class);if(loginResult.getCode() == 1000){this.apitoken = loginResult.getOpen_api_auth_token();}else{System.out.println(result);return false;}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return false;}return true;
}

代码使用到了一个辅助模型LoginResult ,源码如下:

package com.udesk.support.common;public class LoginResult {private int code;private String message;private String open_api_auth_token;public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getOpen_api_auth_token() {return open_api_auth_token;}public void setOpen_api_auth_token(String open_api_auth_token) {this.open_api_auth_token = open_api_auth_token;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}

第二步我们要得到签名,签名是通过SHA256加密算法,对固定格式字符串进行加密得到。

this.timestamp = new Date().getTime()/1000+"";
this.nonce = UUID.randomUUID().toString();
String orgin = this.email+"&"+this.apitoken+"&"+this.timestamp+"&"+this.nonce+"&v2";
this.sign = SHA256.getSHA256(orgin);

其中需要注意,时间戳是秒,不是毫秒。nonce 要求15分钟内不能重复,我们就使用UUID的值作为nonce。SHA256加密算法类源码如下:

package com.udesk.support.common;import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class SHA256 {public static String getSHA256(String str) {MessageDigest messageDigest;String encodestr = "";try {messageDigest = MessageDigest.getInstance("SHA-256");messageDigest.update(str.getBytes("UTF-8"));encodestr = byte2Hex(messageDigest.digest());} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return encodestr;}private static String byte2Hex(byte[] bytes) {StringBuffer stringBuffer = new StringBuffer();String temp = null;for (int i = 0; i < bytes.length; i++) {temp = Integer.toHexString(bytes[i] & 0xFF);if (temp.length() == 1) {stringBuffer.append("0");}stringBuffer.append(temp);}return stringBuffer.toString();}
}

第三步拼接固定的url参数:

"email="+this.email+"&timestamp="+this.timestamp+"&sign="+this.sign+"&nonce="+this.nonce+"&sign_version=v2"

完整的获取固定URL参数方式如下:

private String getCommonArgs()
{this.timestamp = new Date().getTime()/1000+"";this.nonce = UUID.randomUUID().toString();String orgin = this.email+"&"+this.apitoken+"&"+this.timestamp+"&"+this.nonce+"&v2";this.sign = SHA256.getSHA256(orgin);return "email="+this.email+"&timestamp="+this.timestamp+"&sign="+this.sign+"&nonce="+this.nonce+"&sign_version=v2";
}

最后,我们要获取工单列表接口了。page,per_page为非必填int类型,代码实现了一个逻辑,如果传入值为-1则不传这个参数,使用系统默认值。

private String getTickets(int page,int per_page)
{String option = "";if(page != -1){option += "page="+page+"&";}if(per_page != -1){option += "per_page="+per_page+"&";}String url = this.rooturl+"/tickets"+"?"+option+getCommonArgs();System.out.println(url);String result = "";try {result = HttpsUtil.doGet(url);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;
}

完整的实现类代码如下:Tickets.java

package com.udesk.support.demo;import java.io.IOException;
import java.util.Date;
import java.util.UUID;import com.google.gson.Gson;
import com.udesk.support.common.HttpsUtil;
import com.udesk.support.common.LoginResult;
import com.udesk.support.common.SHA256;public class Tickets {private String rooturl;private String email;private String password;private String apitoken;private String timestamp;private String nonce;private String sign;public Tickets(String rooturl,String email,String password){this.rooturl = rooturl;this.email = email;this.password = password;}private boolean login(){String url = this.rooturl+"/log_in";String data = "{\"email\": \""+this.email+"\",\"password\": \""+this.password+"\"}";try {String result = HttpsUtil.doPost(url, data);Gson gson = new Gson();LoginResult loginResult = gson.fromJson(result, LoginResult.class);if(loginResult.getCode() == 1000){this.apitoken = loginResult.getOpen_api_auth_token();}else{System.out.println(result);return false;}} catch (IOException e) {e.printStackTrace();return false;}return true;}private String getCommonArgs(){this.timestamp = new Date().getTime()/1000+"";this.nonce = UUID.randomUUID().toString();String orgin = this.email+"&"+this.apitoken+"&"+this.timestamp+"&"+this.nonce+"&v2";this.sign = SHA256.getSHA256(orgin);return "email="+this.email+"&timestamp="+this.timestamp+"&sign="+this.sign+"&nonce="+this.nonce+"&sign_version=v2";}//获取工单列表//GET /tickets//该接口用于获取获取多个工单信息private String getTickets(int page,int per_page){String option = "";if(page != -1){option += "page="+page+"&";}if(per_page != -1){option += "per_page="+per_page+"&";}String url = this.rooturl+"/tickets"+"?"+option+getCommonArgs();System.out.println(url);String result = "";try {result = HttpsUtil.doGet(url);} catch (IOException e) {e.printStackTrace();}return result;}public static void main(String[] args) throws IOException {Tickets demo = new Tickets("https://你的域名/open_api_v1", "你的超管邮箱", "你的超管密码");if(demo.login()){String result = "";result = demo.getTickets(-1, -1);System.out.println(result);}}
}

运行后,可以使用JSON查看工具,查看返回结果。

结果返回了20条记录,当前页为第一页,与请求参数相符。详细的结果说请参考Udesk官网:https://www.udesk.cn/doc/apiv2/tickets/#_21

我们已经成功的实现了API v2 接口的调用,其他的接口也参考此返利代码自己实现。用到的请求方法在HttpsUtil 都已经提供,大家只需要根据API文档,修改url和参数即可。

完整代码下载地址:https://download.csdn.net/download/zczhangzhenqi/12881929

Java实现调用Udesk API v2(二)相关推荐

  1. Udesk API v2 使用介绍(一)

    作者:张振琦 Udesk提供了两个版本的API供用户使用,API v1和API v2.官方推荐使用API v2,今天就来说说API v2的接口如何使用. API v2 提供了客户接口.工单接口.客户公 ...

  2. Java 中调用 Apache API 实现图片文件的 压缩 与 解压 实例

    < Java 中调用 Apache API 实现图片文件的 压缩 与 解压 > 为什么不直接使用 Java JDK 中自带的 API 呢?必须使用 Apache API 实现文件的压缩与解 ...

  3. java 有多少api_Java常用API(二)

    API 正则表达式 正则表达式的概念 正则表达式(英语:Regular Expression,在代码中常简写为regex) 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配一系列符 ...

  4. 调用百度API(二)——百度翻译

    python 调用百度翻译API 序 一.预备知识 二.操作实例 三.应用 1.设计目标 2.简述 3.程序分析 4.完整代码 四.最后 序 继昨天发的--申请调用百度翻译API(一),今天给大家分享 ...

  5. flink的java api_Flink 流处理API之二

    1.Transform 1.1 map val streamMap = stream.map { x => x * 2 } 1.2 flatmap flatMap的函数签名:def flatMa ...

  6. java 微信分账POST请求 (java代码调用微信api)

    今天用java 调用 微信分账api 由于上传的数据是xml 格式, 用post请求发送 .在网上找的现成函数,微信服务器老是返回签名错误,但是我用postman 发送返回的数据没有问题,于是经过自己 ...

  7. notes java api_如何使用Java来调用Notes API发送邮件(包括附件)

    做这个确实是费了老鼻子劲了,搜了半天网上都找不到一个靠谱的教程,最后其实还是看Notes的Info Center 完成的. 做完了看,其实也不是很难, 几个需要注意的地方: Import的时候不要用d ...

  8. java 调用win32 api 学习总结

    java使用JInvoke调用windows API 使用jinvoke调用windowsAPI.jna使用比较麻烦,需要写c代码和参数转换,jinvoke的使用就像jdk中的包一样. 官网使用参考: ...

  9. java 调用微信api发送消息

    要在 Java 中调用微信 API 发送消息,你需要做的第一步是在微信公众平台中注册自己的公众号,然后获取到自己的 AppID 和 AppSecret. 然后你可以使用微信公众平台提供的开发文档,来了 ...

最新文章

  1. GET POST 区别详解
  2. Bert 中文使用方式
  3. 【Android】3.22 示例22--LBS云检索功能
  4. 【python图像处理】python绘制3D图形
  5. Java技术栈---语言基础
  6. MacOS/MacBook设置短语快捷键
  7. 开发者成功学:扔掉你那些很sexy的想法
  8. 使用NAS动态存储卷创建有状态应用
  9. linux mysql 5.6.23_mysql 5.6.23 的安装
  10. 程序猿怎样的生活方式才能兼顾工作、家庭和自我提升
  11. python 下载文件-python实现下载文件的三种方法_python
  12. SAP财务管理大全-采购收货-标准成本法 移动平均价
  13. 在Postfix里给邮箱定虚拟别名
  14. iOS帐号、证书之漫谈(三)—— 申请Apple ID
  15. 误码率matlab怎么计算,PSK理论误码率与实际误码率MATLAB仿真程序(最新整理)
  16. android 路由表命令,一个轻量简易的Android路由框架
  17. js控制禁用退格键回到上一个页面
  18. Android自定义控件--仿安全卫士中的一键加速【圆形进度条】
  19. state=08S01,code=0
  20. 360°全方位解析C语言的三目运算符

热门文章

  1. 人工智能研究综述与协同智能研究展望(简纲)
  2. 仓库管理|电子物料存储环境及温度要求
  3. jQuery+SVG生成信用卡代码
  4. html_常用标签_盒子标签_图片标签_超链接_列表标签(2)
  5. EMS快递单号也能批量查询?怎么操作呢
  6. Windows10电脑音频出现故障【开机小喇叭突然变红叉,我成功解决的方法】
  7. 鼠标悬浮变手指或者左右箭头
  8. 基于CenOS7.9安装Ambari2.7.4.0+HDP3.1.4.0大数据平台
  9. 线稿要怎么画?小白该怎么去学习绘画线稿?
  10. 《Python Spark 2.0 Hadoop机器学习与大数据实战_林大贵(著)》pdf