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;
    }

    

}
View Code

 

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 + "&timestamp=" + 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;  
    }  
    
}
View Code

 

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_消息管理之被动回复消息

Aurora钉钉_总结_02_开发简介

java_03.Linux的常用命令:vim/vi命令重定向输出>和>>管道 |&&命令执行控制网络通讯命令系统管理命令

大数据技术之_16_Scala学习_11_客户信息管理系统+并发编程模型 Akka+Akka 网络编程-小黄鸡客服案例+Akka 网络编程-Spark Master Worker 进程通讯项目(示例代

Java企业微信开发_07_素材管理之上传本地临时素材文件

Java企业微信开发_09_素材管理之下载微信临时素材到本地服务器