Java钉钉开发_03_通讯录管理之 人员管理 和 部门管理
Posted shirayner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java钉钉开发_03_通讯录管理之 人员管理 和 部门管理相关的知识,希望对你有一定的参考价值。
一、本节要点
1.通讯录权限
ISV(应用服务商)默认无管理通讯录的权限,企业应用默认有所有通讯录权限。
2.数据传输格式—JSON
请参见: Java_数据交换_fastJSON_01_用法入门
二、代码实现
1.HTTP请求工具类—HttpHelper
package com.ray.dingtalk.qy.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.util.EntityUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; /** * HTTP请求封装,建议直接使用sdk的API */ public class HttpHelper { private static final Logger log = LogManager.getLogger(HttpHelper.class); /** * @desc :1.发起GET请求 * * @param url * @return JSONObject * @throws Exception */ public static JSONObject doGet(String url) throws Exception { //1.生成一个请求 HttpGet httpGet = new HttpGet(url); //2.配置请求的属性 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();//2000 httpGet.setConfig(requestConfig); //3.发起请求,获取响应信息 //3.1 创建httpClient CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; try { //3.2 发起请求,获取响应信息 response = httpClient.execute(httpGet, new BasicHttpContext()); //如果返回结果的code不等于200,说明出错了 if (response.getStatusLine().getStatusCode() != 200) { log.info("request url failed, http code=" + response.getStatusLine().getStatusCode() + ", url=" + url); return null; } //4.解析请求结果 HttpEntity entity = response.getEntity(); //reponse返回的数据在entity中 if (entity != null) { String resultStr = EntityUtils.toString(entity, "utf-8"); //将数据转化为string格式 log.info("GET请求结果:"+resultStr); JSONObject result = JSON.parseObject(resultStr); //将String转换为 JSONObject if(result.getInteger("errcode")==null) { return result; }else if (0 == result.getInteger("errcode")) { return result; }else { log.info("request url=" + url + ",return value="); log.info(resultStr); int errCode = result.getInteger("errcode"); String errMsg = result.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); } } } catch (IOException e) { log.info("request url=" + url + ", exception, msg=" + e.getMessage()); e.printStackTrace(); } finally { if (response != null) try { response.close(); //释放资源 } catch (IOException e) { e.printStackTrace(); } } return null; } /** 2.发起POST请求 * @desc : * * @param url 请求url * @param data 请求参数(json) * @return * @throws Exception JSONObject */ public static JSONObject doPost(String url, Object data) throws Exception { //1.生成一个请求 HttpPost httpPost = new HttpPost(url); //2.配置请求属性 //2.1 设置请求超时时间 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100000).setConnectTimeout(100000).build(); httpPost.setConfig(requestConfig); //2.2 设置数据传输格式-json httpPost.addHeader("Content-Type", "application/json"); //2.3 设置请求实体,封装了请求参数 StringEntity requestEntity = new StringEntity(JSON.toJSONString(data), "utf-8"); httpPost.setEntity(requestEntity); //3.发起请求,获取响应信息 //3.1 创建httpClient CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; try { //3.3 发起请求,获取响应 response = httpClient.execute(httpPost, new BasicHttpContext()); if (response.getStatusLine().getStatusCode() != 200) { log.info("request url failed, http code=" + response.getStatusLine().getStatusCode() + ", url=" + url); return null; } //获取响应内容 HttpEntity entity = response.getEntity(); if (entity != null) { String resultStr = EntityUtils.toString(entity, "utf-8"); log.info("POST请求结果:"+resultStr); //解析响应内容 JSONObject result = JSON.parseObject(resultStr); if(result.getInteger("errcode")==null) { return result; }else if (0 == result.getInteger("errcode")) { return result; }else { log.info("request url=" + url + ",return value="); log.info(resultStr); int errCode = result.getInteger("errcode"); String errMsg = result.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); } } } catch (IOException e) { log.info("request url=" + url + ", exception, msg=" + e.getMessage()); e.printStackTrace(); } finally { if (response != null) try { response.close(); //释放资源 } catch (IOException e) { e.printStackTrace(); } } return null; } /** * @desc : 3. * * @param url * @param file * @return * @throws Exception * JSONObject */ public static JSONObject uploadMedia(String url, File file) throws Exception { HttpPost httpPost = new HttpPost(url); CloseableHttpResponse response = null; CloseableHttpClient httpClient = HttpClients.createDefault(); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build(); httpPost.setConfig(requestConfig); HttpEntity requestEntity = MultipartEntityBuilder.create().addPart("media", new FileBody(file, ContentType.APPLICATION_OCTET_STREAM, file.getName())).build(); httpPost.setEntity(requestEntity); try { response = httpClient.execute(httpPost, new BasicHttpContext()); if (response.getStatusLine().getStatusCode() != 200) { log.info("request url failed, http code=" + response.getStatusLine().getStatusCode() + ", url=" + url); return null; } HttpEntity entity = response.getEntity(); if (entity != null) { String resultStr = EntityUtils.toString(entity, "utf-8"); JSONObject result = JSON.parseObject(resultStr); if (result.getInteger("errcode") == 0) { // 成功 //result.remove("errcode"); //result.remove("errmsg"); return result; } else { log.info("request url=" + url + ",return value="); log.info(resultStr); int errCode = result.getInteger("errcode"); String errMsg = result.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); } } } catch (IOException e) { log.info("request url=" + url + ", exception, msg=" + e.getMessage()); e.printStackTrace(); } finally { if (response != null) try { response.close(); //释放资源 } catch (IOException e) { e.printStackTrace(); } } return null; } public static File downloadMedia(String url, String fileDir) throws Exception { //1.生成一个请求 HttpGet httpGet = new HttpGet(url); //2.配置请求属性 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build(); httpGet.setConfig(requestConfig); //3.发起请求,获取响应信息 //3.1 创建httpClient CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; //4.设置本地保存的文件 File file = new File(fileDir); try { //5. 发起请求,获取响应信息 response = httpClient.execute(httpGet, new BasicHttpContext()); log.info("HttpStatus.SC_OK:"+HttpStatus.SC_OK); log.info("response.getStatusLine().getStatusCode():"+response.getStatusLine().getStatusCode()); //请求成功 if(HttpStatus.SC_OK==response.getStatusLine().getStatusCode()){ //6.取得请求内容 HttpEntity entity = response.getEntity(); if (entity != null) { //这里可以得到文件的类型 如image/jpg /zip /tiff 等等 但是发现并不是十分有效,有时明明后缀是.rar但是取到的是null,这点特别说明 log.info(entity.getContentType()); //可以判断是否是文件数据流 log.info(entity.isStreaming()); //6.1 输出流 FileOutputStream output = new FileOutputStream(file); //6.2 输入流:从钉钉服务器返回的文件流,得到网络资源并写入文件 InputStream input = entity.getContent(); //6.3 将数据写入文件:将输入流中的数据写入到输出流 byte b[] = new byte[1024]; int j = 0; while( (j = input.read(b))!=-1){ output.write(b,0,j); } output.flush(); output.close(); } if (entity != null) { entity.consumeContent(); } } } catch (IOException e) { log.info("request url=" + url + ", exception, msg=" + e.getMessage()); e.printStackTrace(); } finally { if (response != null) try { response.close(); //释放资源 } catch (IOException e) { e.printStackTrace(); } } return file; } }
2.Token工具类—AuthHelper
package com.ray.dingtalk.qy.auth; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Formatter; import java.util.HashMap; import java.util.Map; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import com.alibaba.fastjson.JSONObject; import com.ray.dingtalk.qy.config.Env; import com.ray.dingtalk.qy.util.HttpHelper; /** * 钉钉相关配置参数的获取工具类 * @desc : AccessToken和jsticket的获取封装 * * @author: shirayner * @date : 2017年9月27日 下午5:00:25 */ public class AuthHelper { //private static Logger log = LoggerFactory.getLogger(AuthHelper.class); //获取access_token的接口地址,有效期为7200秒 private static final String GET_ACCESSTOKEN_URL="https://oapi.dingtalk.com/gettoken?corpid=CORPID&corpsecret=CORPSECRET"; //获取getJsapiTicket的接口地址,有效期为7200秒 private static final String GET_JSAPITICKET_URL="https://oapi.dingtalk.com/get_jsapi_ticket?access_token=ACCESSTOKE"; /** 1.获取access_token * @desc : * * @param corpId * @param corpSecret * @return * @throws Exception String */ public static String getAccessToken(String corpId,String corpSecret) throws Exception { //1.获取请求url String url=GET_ACCESSTOKEN_URL.replace("CORPID", corpId).replace("CORPSECRET", corpSecret); //2.发起GET请求,获取返回结果 JSONObject jsonObject=HttpHelper.doGet(url); //3.解析结果,获取accessToken String accessToken=""; if (null != jsonObject) { accessToken=jsonObject.getString("access_token"); //4.错误消息处理 if (0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); } } return accessToken; } /** * 2、获取JSTicket, 用于js的签名计算 * 正常的情况下,jsapi_ticket的有效期为7200秒,所以开发者需要在某个地方设计一个定时器,定期去更新jsapi_ticket * @throws Exception */ public static String getJsapiTicket(String accessToken) throws Exception { //1.获取请求url String url=GET_JSAPITICKET_URL.replace("ACCESSTOKE", accessToken); //2.发起GET请求,获取返回结果 JSONObject jsonObject=HttpHelper.doGet(url); //3.解析结果,获取ticket String ticket=""; if (null != jsonObject) { ticket=jsonObject.getString("ticket"); //4.错误消息处理 if (0 != jsonObject.getInteger("errcode")) { int errCode = jsonObject.getInteger("errcode"); String errMsg = jsonObject.getString("errmsg"); throw new Exception("error code:"+errCode+", error message:"+errMsg); } } return ticket; } /** * @desc : 3.生成签名的函数 * * @param ticket jsticket * @param nonceStr 随机串,自己定义 * @param timeStamp 生成签名用的时间戳 * @param url 需要进行免登鉴权的页面地址,也就是执行dd.config的页面地址 * @return * @throws Exception String */ public static String getSign(String jsTicket, String nonceStr, Long timeStamp, String url) throws Exception { String plainTex = "jsapi_ticket=" + jsTicket + "&noncestr=" + nonceStr + "×tamp=" + timeStamp + "&url=" + url; System.out.println(plainTex); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(plainTex.getBytes("UTF-8")); return byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { throw new Exception(e.getMessage()); } catch (UnsupportedEncodingException e) { throw new Exception(e.getMessage()); } } //将bytes类型的数据转化为16进制类型 private static String byteToHex(byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", new Object[] { Byte.valueOf(b) }); } String result = formatter.toString(); formatter.close(); return result; } /** * @desc :获取前端jsapi需要的配置参数(已弃用,请用getConfig(HttpServletRequest)) * * @param request request:在钉钉中点击微应用图标跳转的url地址 * @return Map<String,Object> 将需要的参数存入map,并返回 */ public static Map<String, Object> getDDConfig(HttpServletRequest request){ Map<String, Object> configMap = new HashMap<String, Object>(); //1.准备好参与签名的字段 /* *以http://localhost/test.do?a=b&c=d为例 *request.getRequestURL的结果是http://localhost/test.do *request.getQueryString的返回值是a=b&c=d */ String urlString = request.getRequestURL().toString(); String queryString = request.getQueryString(); String queryStringEncode = null; String url; if (queryString != null) { queryStringEncode = URLDecoder.decode(queryString); url = urlString + "?" + queryStringEncode; } else { url = urlString; } String nonceStr=UUID.randomUUID().toString(); //随机数 long timeStamp = System.currentTimeMillis() / 1000; //时间戳参数 String signedUrl = url; String accessToken = null; String ticket = null; String signature = null; //签名 //2.进行签名,获取signature try { accessToken=AuthHelper.getAccessToken(Env.CORP_ID, Env.CORP_SECRET); ticket=AuthHelper.getJsapiTicket(accessToken); signature=getSign(ticket,nonceStr,timeStamp,signedUrl); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("accessToken:"+accessToken); System.out.println("ticket:"+ticket); System.out.println("nonceStr:"+nonceStr); System.out.println("timeStamp:"+timeStamp); System.out.println("signedUrl:"+signedUrl); System.out.println("signature:"+signature); System.out.println("agentId:"+Env.AGENTID); System.out.println("corpId:"+Env.CORP_ID); //3.将配置参数存入Map configMap.put("agentId", Env.AGENTID); configMap.put("corpId", Env.CORP_ID); configMap.put("timeStamp", timeStamp); configMap.put("nonceStr", nonceStr); configMap.put("signature", signature); return configMap; } public static String getConfig(HttpServletRequest request){ //1.准备好参与签名的字段 /* *以http://localhost/test.do?a=b&c=d为例 *request.getRequestURL的结果是http://localhost/test.do *request.getQueryString的返回值是a=b&c=d */ String urlString = request.getRequestURL().toString(); String queryString = request.getQueryString(); String queryStringEncode = null; String url; if (queryString != null) { queryStringEncode = URLDecoder.decode(queryString); url = urlString + "?" + queryStringEncode; } else { url = urlString; } String nonceStr=UUID.randomUUID().toString(); //随机数 long timeStamp = System.currentTimeMillis() / 1000; //时间戳参数 String signedUrl = url; String accessToken = null; String ticket = null; String signature = null; //签名 //2.进行签名,获取signature try { accessToken=AuthHelper.getAccessToken(Env.CORP_ID, Env.CORP_SECRET); ticket=AuthHelper.getJsapiTicket(accessToken); signature=getSign(ticket,nonceStr,timeStamp,signedUrl); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("accessToken:"+accessToken); System.out.println("ticket:"+ticket); System.out.println("nonceStr:"+nonceStr); System.out.println("timeStamp:"+timeStamp); System.out.println("signedUrl:"+signedUrl); System.out.println("signature:"+signature); System.out.println("agentId:"+Env.AGENTID); System.out.println("corpId:"+Env.CORP_ID); String configValue = "{jsticket:\'" + ticket + "\',signature:\'" + signature + "\',nonceStr:\'" + nonceStr + "\',timeStamp:\'" + timeStamp + "\',corpId:\'" + Env.CORP_ID + "\',agentId:\'" + Env.AGENTID + "\'}"; System.out.println(configValue); return configValue; } }
3.成员实体类—User
package com.ray.dingtalk.qy.model.contact; import java.util.List; import com.alibaba.fastjson.JSONObject; /**@desc : 用户类 * * @author: shirayner * @date : 2017年9月28日 上午9:38:25 */ public class User { public String userid; public String name; //必须 public boolean active; public String avatar; public List<Long> department; //必须 public String position; public String mobile; //必须 public String tel; public String workPlace; public String remark; public String email; public String jobnumber; public JSONObject extattr; public boolean isAdmin; public boolean isBoss; public String dingId; /** * @return the userid */ public String getUserid() { return userid; } /** * @param userid the userid to set */ public void setUserid(String userid) { this.userid = userid; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the active */ public boolean isActive() { return active; } /** * @param active the active to set */ public void setActive(boolean active) { this.active = active; } /** * @return the avatar */ public String getAvatar() { return avatar; } /** * @param avatar the avatar to set */ public void setAvatar(String avatar) { this.avatar = avatar; } /** * @return the department */ public List<Long> getDepartment() { return department; } /** * @param department the department to set */ public void setDepartment(List<Long> department) { this.department = department; } /** * Java微信公众平台开发_03_消息管理之被动回复消息java_03.Linux的常用命令:vim/vi命令重定向输出>和>>管道 |&&命令执行控制网络通讯命令系统管理命令
大数据技术之_16_Scala学习_11_客户信息管理系统+并发编程模型 Akka+Akka 网络编程-小黄鸡客服案例+Akka 网络编程-Spark Master Worker 进程通讯项目(示例代