Java企业微信开发_03_通讯录同步
Posted shirayner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java企业微信开发_03_通讯录同步相关的知识,希望对你有一定的参考价值。
一、本节要点
1.获取通讯录密钥
获取方式:
登录企业微信—>管理工具—>通讯录同步助手—>开启“API接口同步” ; 开启后,即可看到通讯录密钥,也可设置通讯录API的权限:读取或者编辑通讯录。
获取通讯录密钥的目的:
通过企业ID(CorpId)和 通讯录密钥可以获取通讯录相关接口的使用凭证(AccessToken)。有了AccessToken,就可以使用通讯录相关接口了。
凭证的获取方式有两种(此处暂时存疑,以待勘误):
通讯录AccessToken:CorpId+通讯录密钥
其他AccessToken:CorpId+应用密钥
2.json序列化
2.1序列化和反序列化的概念
把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
2.2对象的序列化的目的
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
2.3java序列化方式
(1)java原生序列化
(2)json序列化
而json序列化可使用 ① json-lib
②fastJson
③gson
2.4json序列化与反序列化
这里我们采用gson来实现java对象的序列化,需要引入 gson-2.7.jar 包。
(1)简单的Jason
{ "userid": "zhangsan", "name": "张三", "english_name": "jackzhang" }
使用gson.toJson(user)即可将user对象顺序转成json字符串,如下
Gson gson = new Gson(); String jsonU1 =gson.toJson(user);
(2)带数组的json
将department设为list<Integer>类型即可
{ "userid": "zhangsan", "name": "张三", "english_name": "jackzhang" "department": [1, 2], }
(3)包含子对象的json
以下代码为文本消息的json字符串,将text属性类型设为Text,Text类中包含content属性。然后使用 gson.toJson(user)
{ "msgtype" : "text", "agentid" : 1, "text" : { "content" : "你的快递已到,请携带工卡前往邮件中心领取。\\n出发前可查看<a href=\\"http://work.weixin.qq.com\\">邮件中心视频实况</a>,聪明避开排队。" }, }
关于Json序列化,读者在 Java企业微信开发_05_消息推送之发送消息 这一节会有更深刻的理解,这一周将会继续总结。
3.企业微信开发思路
企业微信的开发大体可分为以下几步:
(1)封装实体类
参考官方文档给出的请求包、回包(即响应包),封装对应的java实体类。
(2)java对象的序列化
将java对象序列化为json格式的字符串
(3)获取AccessToken,拼接请求接口url
(4)调用接口发送http请求
封装好http请求方法:httpRequest(请求url, 请求方法POST/GET, 请求包);
1 /** 2 * 1.发起https请求并获取结果 3 * 4 * @param requestUrl 请求地址 5 * @param requestMethod 请求方式(GET、POST) 6 * @param outputStr 提交的数据 7 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) 8 */ 9 public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) { 10 JSONObject jsonObject = null; 11 StringBuffer buffer = new StringBuffer(); 12 try { 13 // 创建SSLContext对象,并使用我们指定的信任管理器初始化 14 TrustManager[] tm = { new MyX509TrustManager() }; 15 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); 16 sslContext.init(null, tm, new java.security.SecureRandom()); 17 // 从上述SSLContext对象中得到SSLSocketFactory对象 18 SSLSocketFactory ssf = sslContext.getSocketFactory(); 19 20 URL url = new URL(requestUrl); 21 HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); 22 httpUrlConn.setSSLSocketFactory(ssf); 23 24 httpUrlConn.setDoOutput(true); 25 httpUrlConn.setDoInput(true); 26 httpUrlConn.setUseCaches(false); 27 // 设置请求方式(GET/POST) 28 httpUrlConn.setRequestMethod(requestMethod); 29 30 if ("GET".equalsIgnoreCase(requestMethod)) 31 httpUrlConn.connect(); 32 33 // 当有数据需要提交时 34 if (null != outputStr) { 35 OutputStream outputStream = httpUrlConn.getOutputStream(); 36 // 注意编码格式,防止中文乱码 37 outputStream.write(outputStr.getBytes("UTF-8")); 38 outputStream.close(); 39 } 40 41 // 将返回的输入流转换成字符串 42 InputStream inputStream = httpUrlConn.getInputStream(); 43 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 44 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 45 46 String str = null; 47 while ((str = bufferedReader.readLine()) != null) { 48 buffer.append(str); 49 } 50 bufferedReader.close(); 51 inputStreamReader.close(); 52 // 释放资源 53 inputStream.close(); 54 inputStream = null; 55 httpUrlConn.disconnect(); 56 jsonObject = JSONObject.fromObject(buffer.toString()); 57 } catch (ConnectException ce) { 58 log.error("Weixin server connection timed out."); 59 } catch (Exception e) { 60 log.error("https request error:{}", e); 61 } 62 return jsonObject; 63 }
二、代码实现
相关jar包:
2.1 工具类之微信参数封装类——WeiXinParamesUtil.java
此类封装了微信的相关参数,如企业id、应用凭证、通讯录凭证等。封装起来更易维护,实现一处修改多处改变。
1 package com.ray.util; 2 /** 3 * 微信参数 4 * @author shirayner 5 * 6 */ 7 public class WeiXinParamesUtil { 8 //1.微信参数 9 //token 10 public final static String token = "ray"; 11 // encodingAESKey 12 public final static String encodingAESKey = "z2W9lyOAR1XjY8mopEmiSqib0TlBZzCFiCLp6IdS2Iv"; 13 //企业ID 14 public final static String corpId = "ww92f5da92bb24696e"; 15 16 //应用的凭证密钥 17 public final static String agentSecret = "I73733veH3uCs6H_ijPvIq0skjTaOePsFF4MyCEi3Ag"; 18 //通讯录秘钥 19 public final static String contactsSecret = "1m_9XP62YrXjSiYtL5ThbexiLVWBThukiK5sH7wm1TM"; 20 21 //企业应用的id,整型。可在应用的设置页面查看 22 public final static int agentId = 1000002; 23 24 }
2.2 工具类之微信辅助类——WeiXinUtil.java
此类封装了http请求、https请求、获取accessToken的方法
1 package com.ray.util; 2 3 import java.io.BufferedReader; 4 import java.io.InputStream; 5 import java.io.InputStreamReader; 6 import java.io.OutputStream; 7 import java.net.ConnectException; 8 import java.net.HttpURLConnection; 9 import java.net.URL; 10 import javax.net.ssl.HttpsURLConnection; 11 import javax.net.ssl.SSLContext; 12 import javax.net.ssl.SSLSocketFactory; 13 import javax.net.ssl.TrustManager; 14 import org.slf4j.Logger; 15 import org.slf4j.LoggerFactory; 16 import com.ray.pojo.AccessToken; 17 import net.sf.json.JSONException; 18 import net.sf.json.JSONObject; 19 20 public class WeiXinUtil { 21 22 private static Logger log = LoggerFactory.getLogger(WeiXinUtil.class); 23 //微信的请求url 24 //获取access_token的接口地址(GET) 限200(次/天) 25 public final static String access_token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={corpsecret}"; 26 27 28 29 /** 30 * 1.发起https请求并获取结果 31 * 32 * @param requestUrl 请求地址 33 * @param requestMethod 请求方式(GET、POST) 34 * @param outputStr 提交的数据 35 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) 36 */ 37 public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) { 38 JSONObject jsonObject = null; 39 StringBuffer buffer = new StringBuffer(); 40 try { 41 // 创建SSLContext对象,并使用我们指定的信任管理器初始化 42 TrustManager[] tm = { new MyX509TrustManager() }; 43 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); 44 sslContext.init(null, tm, new java.security.SecureRandom()); 45 // 从上述SSLContext对象中得到SSLSocketFactory对象 46 SSLSocketFactory ssf = sslContext.getSocketFactory(); 47 48 URL url = new URL(requestUrl); 49 HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); 50 httpUrlConn.setSSLSocketFactory(ssf); 51 52 httpUrlConn.setDoOutput(true); 53 httpUrlConn.setDoInput(true); 54 httpUrlConn.setUseCaches(false); 55 // 设置请求方式(GET/POST) 56 httpUrlConn.setRequestMethod(requestMethod); 57 58 if ("GET".equalsIgnoreCase(requestMethod)) 59 httpUrlConn.connect(); 60 61 // 当有数据需要提交时 62 if (null != outputStr) { 63 OutputStream outputStream = httpUrlConn.getOutputStream(); 64 // 注意编码格式,防止中文乱码 65 outputStream.write(outputStr.getBytes("UTF-8")); 66 outputStream.close(); 67 } 68 69 // 将返回的输入流转换成字符串 70 InputStream inputStream = httpUrlConn.getInputStream(); 71 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 72 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 73 74 String str = null; 75 while ((str = bufferedReader.readLine()) != null) { 76 buffer.append(str); 77 } 78 bufferedReader.close(); 79 inputStreamReader.close(); 80 // 释放资源 81 inputStream.close(); 82 inputStream = null; 83 httpUrlConn.disconnect(); 84 jsonObject = JSONObject.fromObject(buffer.toString()); 85 } catch (ConnectException ce) { 86 log.error("Weixin server connection timed out."); 87 } catch (Exception e) { 88 log.error("https request error:{}", e); 89 } 90 return jsonObject; 91 } 92 93 /** 94 * 2.发起http请求获取返回结果 95 * 96 * @param requestUrl 请求地址 97 * @return 98 */ 99 public static String httpRequest(String requestUrl) { 100 StringBuffer buffer = new StringBuffer(); 101 try { 102 URL url = new URL(requestUrl); 103 HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection(); 104 105 httpUrlConn.setDoOutput(false); 106 httpUrlConn.setDoInput(true); 107 httpUrlConn.setUseCaches(false); 108 109 httpUrlConn.setRequestMethod("GET"); 110 httpUrlConn.connect(); 111 112 // 将返回的输入流转换成字符串 113 InputStream inputStream = httpUrlConn.getInputStream(); 114 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 115 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 116 117 String str = null; 118 while ((str = bufferedReader.readLine()) != null) { 119 buffer.append(str); 120 } 121 bufferedReader.close(); 122 inputStreamReader.close(); 123 // 释放资源 124 inputStream.close(); 125 inputStream = null; 126 httpUrlConn.disconnect(); 127 128 } catch (Exception e) { 129 } 130 return buffer.toString(); 131 } 132 133 134 /** 135 * 3.获取access_token 136 * 137 * @param appid 凭证 138 * @param appsecret 密钥 139 * @return 140 */ 141 public static AccessToken getAccessToken(String appid, String appsecret) { 142 AccessToken accessToken = null; 143 144 String requestUrl = access_token_url.replace("{corpId}", appid).replace("{corpsecret}", appsecret); 145 JSONObject jsonObject = httpRequest(requestUrl, "GET", null); 146 // 如果请求成功 147 if (null != jsonObject) { 148 try { 149 accessToken = new AccessToken(); 150 accessToken.setToken(jsonObject.getString("access_token")); 151 accessToken.setExpiresIn(jsonObject.getInt("expires_in")); 152 } catch (JSONException e) { 153 accessToken = null; 154 // 获取token失败 155 log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); 156 } 157 } 158 return accessToken; 159 } 160 161 162 }
发送https请求需要一个证书信任管理器,所以此类依赖于MyX509TrustManager.java
1 package com.ray.util; 2 3 import java.security.cert.CertificateException; 4 import java.security.cert.X509Certificate; 5 6 import javax.net.ssl.X509TrustManager; 7 8 /** 9 * 证书信任管理器(用于https请求) 10 * 11 * @author liufeng 12 * @date 2013-08-08 13 */ 14 public class MyX509TrustManager implements X509TrustManager { 15 16 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 17 } 18 19 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 20 } 21 22 public X509Certificate[] getAcceptedIssuers() { 23 return null; 24 } 25 }
2.3 实体类之凭证封装类——AccessToken.java
1 package com.ray.pojo; 2 3 /** 4 * @desc : 微信通用接口凭证 5 * 6 * @author: shirayner 7 * @date : 2017-8-20 下午9:35:11 8 */ 9 public class AccessToken { 10 // 获取到的凭证 11 private String token; 12 // 凭证有效时间,单位:秒 13 private int expiresIn; 14 15 public String getToken() { 16 return token; 17 } 18 19 public void setToken(String token) { 20 this.token = token; 21 } 22 23 public int getExpiresIn() { 24 return expiresIn; 25 } 26 27 public void setExpiresIn(int expiresIn) { 28 this.expiresIn = expiresIn; 29 } 30 }
2.4 实体类之用户类——User.java
注:这两个实体类只添加了User的部分属性,如有需要,读者可根据官方文档自行添加相关属性。
1 package com.ray.pojo; 2 3 public class User { 4 private String userid; 5 private String name; 6 private int department; 7 private String mobile; 8 private String email; 9 private String position; 10 private String gender; 11 12 public User(){}; 13 public User(String userid, String name, int department, String mobile, 14 String email, String position, String gender) { 15 super(); 16 this.userid = userid; 17 this.name = name; 18 this.department = department; 19 this.mobile = mobile; 20 this.email = email; 21 this.position = position; 22 this.gender = gender; 23 } 24 public String getUserid() { 25 return userid; 26 } 27 public void setUserid(String userid) { 28 this.userid = userid; 29 } 30 public String getName() { 31 return name; 32 } 33 public void setName(String name) { 34 this.name = name; 35 } 36 37 public int getDepartment() { 38 return department; 39 } 40 public void setDepartment(int department) { 41 this.department = department; 42 } 43 public String getMobile() { 44 return mobi以上是关于Java企业微信开发_03_通讯录同步的主要内容,如果未能解决你的问题,请参考以下文章