企业微信集成方案

1.概述

         企业微信集成方案,通过请求微信API的方式,获得当前微信访问用户的ID,然后通过用户ID实现对微信报表的权限管控。

2.  前期准备

        a) 准备企业微信,需要给开发人员管理员权限,官网:https://work.weixin.qq.com/

        b) 创建企业应用小程序,如下图:

          企业微信集成方案_第1张图片

      c) 准备好企业微信的企业ID(Corpid),点击我的企业即可查看,如下图:

        企业微信集成方案_第2张图片

   d) 准备好应用的AgentId和Secret (CorpSecret),如下图:

      企业微信集成方案_第3张图片

  e) 企业微信API,官网:http://work.weixin.qq.com/api/doc#10012

 

3.开始开发

  a)  发送请求到微信API,获得微信验证 用户授权CODE

https://open.weixin.qq.com/connect/oauth2/authorize?appid={CORP_ID}&redirect_uri= {REDIRECT_URI}&response_type=code&scope=SCOPE&agentid={AGENT_ID}&state=STATE#wechat_redirect

    {CORP_ID} = 企业ID

   {REDIRECT_URI} = 请求成功之后,回调的URL。

 

  b)  发送请求到微信API,获得ACCESS_TOKEN(权限验证TOKEN

    https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={CORP_ID}&corpsecret={CORPSECRET}
    {CORP_ID} = 企业ID
    {CORPSECRET} = 应用的Secret

  c) 发送请求到微信API,获得微信当前访问的USERID(用户名) 

     https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={ACCESS_TOKEN}&code={CODE}&agentid={AGENTID}

    {ACCESS_TOKEN} = 之前获得的ACCESS_TOKEN

    {CODE} = 之前获得的 用户授权的CODE

    {AGENTID} = 应用的AgentId

 

4. 代码剖析

   微信API调用类

package action;


import com.opensymphony.xwork2.ActionSupport;
import dto.WeChatUrlConstant;
import net.sf.json.JSONObject;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import servlet.WeiXinTools;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;

/**
 * 微信API调用类
 */
public class WeChatReportAction extends ActionSupport{
   // 输出日志打印
   public static Logger log = LoggerFactory.getLogger(WeChatReportAction.class);

   /**
    * 获得微信授权Code
    */
   public void getWeChatCode(){
      //获得Servlet 请求响应对象
      HttpServletRequest request = ServletActionContext.getRequest();
      HttpServletResponse response = ServletActionContext.getResponse();
      String getCodeUrl="";
      try {
         //拼接请求code链接的url
         getCodeUrl = WeChatUrlConstant.GET_CODE.replace("{CORP_ID}",WeChatUrlConstant.CORP_ID ).replace("{REDIRECT_URI}",URLEncoder.encode("https://wechat.aimatech.com:7777/aima/queryUserInfo.action","UTF-8"));
         //跳转 重定向到获取ceode请求
         response.sendRedirect(getCodeUrl);
      } catch (Exception e) {
         log.error("Default boot user authorization failed!---{}", e);
      }
   }

   /**
    * 获得微信当前访问的用户信息
    */
   public void queryUserInfo(){
      //获得Servlet 请求响应对象
      HttpServletRequest request = ServletActionContext.getRequest();
      HttpServletResponse response = ServletActionContext.getResponse();
      try {
         //通过刚刚重定向的URL  在请求对象中 拿到 用户授权code
         String code = request.getParameter("code");
         //获取ACCESS_TOKEN
         JSONObject accessToken_json = WeiXinTools.sendHttps(WeChatUrlConstant.GET_ACCESS_TOKEN.replace("{CORP_ID}",WeChatUrlConstant.CORP_ID).replace("{CORPSECRET}", WeChatUrlConstant.CORPSECRET), "GET", null);

         String accesstoken = accessToken_json.getString("access_token");
         //获取用户user_id接口
         String url = WeChatUrlConstant.GET_USER_ID.replace("{ACCESS_TOKEN}",accesstoken).replace("{CODE}", code).replace("{AGENTID}", WeChatUrlConstant.AGENT_ID);
         JSONObject josnObj = WeiXinTools.sendHttps(url, "GET", null);
         if(josnObj.containsKey("errmsg")){    //请求调用后,调用失败返回的编码
            log.error("code:==>"+code+"url==>"+url+"==== Failed to get UserId!");
         }
         String userId = (String)josnObj.get("UserId");  //获取用户id
         //日志打印 用户ID
         log.info("UserId:==>"+userId);
         //跳转的URL
         String redirectUrl ="https://wechat.aimatech.com:7777/aima/page/index.html?userId="+userId;
         //跳转  重定向URL
         response.sendRedirect(redirectUrl);
      } catch (Exception e) {
         log.error("Failed to get user information, specific error :"+e.getMessage());
      }
   }

}





  工具类

package servlet;

import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 工具类
 * 主要功能:
* 1、recv():将微信公众平台发来的reuquest请求转换成一个具体的接收消息类
* 2、send():消息的发送
* 3、builderSendByRecv():根据接收消息类构建一个发送消息类
* @author 魏友元 * */ public final class WeiXinTools { private static Logger log = LoggerFactory.getLogger(WeiXinTools.class); private static double x_pi = 3.14499265358979324 * 3000.0 / 180.0; /** * 校验类 * @param token * @param signature * @param timestamp * @param nonce * @return */ public static boolean access(String token,String signature,String timestamp,String nonce) { List ss = new ArrayList(); ss.add(timestamp); ss.add(nonce); ss.add(token); Collections.sort(ss); StringBuilder builder = new StringBuilder(); for(String s : ss) { builder.append(s); } return signature.equalsIgnoreCase(HashKit.sha1(builder.toString())); } /** * 调用接口,在这里做数据处理 * @param url 请求的接口路径 * @param obj 需要发送的消息数据封装类 * @param methodType 请求方式(POST、GET) * @return */ public static String sendTemp(String url,Object obj,String methodType) { String result = ""; // 将消息对象转换成json字符串 String dataJson = JSONObject.fromObject(obj).toString(); // 调用对应的接口 JSONObject jsonObject = sendHttps(url, methodType, dataJson); if (null != jsonObject) { if (null != jsonObject.getString("errcode")&&!jsonObject.getString("errcode").equals("")) { result = jsonObject.getString("errcode"); } } return result; } /** * 发起https请求并获取结果 * * @param requestUrl 请求地址 * @param requestMethod 请求方式(GET、POST) * @param outputStr 提交的数据 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) */ public static JSONObject sendHttps(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 创建SSLContext对象,并使用我们指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(new KeyManager[0], tm, new java.security.SecureRandom()); // 从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setHostnameVerifier(new HostnameVerifier() { public boolean verify(String s, SSLSession sslsession) { return true;//全部通过 } }); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 设置请求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); httpUrlConn.setRequestProperty("Accept", "text/xml,text/javascript,text/html"); httpUrlConn.setRequestProperty("User-Agent", "top-sdk-java"); if ("GET".equalsIgnoreCase(requestMethod)){ httpUrlConn.connect(); } // 当有数据需要提交时 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 释放资源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); if(buffer!=null&&!buffer.equals("")&&buffer.toString().indexOf("{")==0){ jsonObject = JSONObject.fromObject(buffer.toString()); } } catch (ConnectException ce) { log.error("Weixin server connection timed out."); } catch (Exception e) { log.error("https request error:{}", e); } return jsonObject; } /** * 向指定 URL 发送POST方法的请求 * * @param url * 发送请求的 URL * @param param * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { BufferedReader in = null; OutputStreamWriter out =null; String result = ""; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8"); conn.setRequestProperty("user-agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257 MicroMessenger/6.0.2 NetType/WIFI"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // 发送请求参数 out.write(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8")); String line; while ((line = in.readLine()) != null) { result += line; } } 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 result; } /** * 向指定URL发送GET方法的请求 * * @param url * 发送请求的URL * @param param * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */ public static String sendGet(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url; if(param!=null && !param.equals("")){ if(url.indexOf("?")!=-1){ urlNameString = urlNameString + "&" + param; }else{ urlNameString = urlNameString + "?" + param; } } URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 // connection.setRequestProperty("accept", "*/*"); // connection.setRequestProperty("connection", "Keep-Alive"); // connection.setRequestProperty("user-agent", // "Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257 MicroMessenger/6.0.2 NetType/WIFI"); // 建立实际的连接 connection.connect(); // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8")); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { log.error("发送GET请求出现异常!" + e); } //log.info("get请求获取的数据1:---->"+result); return result; } /** * 向指定URL发送GET方法的请求 * * @param url * 发送请求的URL * @param param * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */ public static InputStream getImg(String url, String param) { InputStream in = null; try { String urlNameString = url; if(param!=null && !param.equals("")){ if(url.indexOf("?")!=-1){ urlNameString = urlNameString + "&" + param; }else{ urlNameString = urlNameString + "?" + param; } } URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); // 建立实际的连接 connection.connect(); in = connection.getInputStream(); } catch (Exception e) { System.out.println("下载图片请求出现异常!" + e); e.printStackTrace(); } return in; } /** * 文件存储 * @param fileName 文件名 * @param inputStream 文件输入流 * @return */ public static String uploadFile(String fileName,InputStream inputStream){ byte[] data = new byte[1024]; int len = 0; FileOutputStream fileOutputStream = null; String saveU =""; try { String tempPath="c:/wxScanUpload/"+new SimpleDateFormat("yyyyMMdd").format(new Date()); File file=new File(tempPath); if(!file.exists() && !file.isDirectory()){ file.mkdirs(); } String name=fileName+".jpg"; saveU=tempPath+"/"+name; fileOutputStream = new FileOutputStream(saveU); while ((len = inputStream.read(data)) != -1) { fileOutputStream.write(data, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return saveU; } /** * 表情转换 * @param emoji * @return */ public static String getEmoji(int emoji){ return String.valueOf(Character.toChars(emoji)); } /** *中国正常坐标系GCJ02协议的坐标,转到 百度地图对应的 BD09 协议坐标 * @param lat 维度 * @param lng 经度 * 返回经度+纬度的字符串 例如 119.2321,31.12321 */ public static String Convert_GCJ02_To_BD09(double lat,double lng){ double x = lng, y = lat; double z =Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x)+ 0.000003 * Math.cos(x * x_pi); lng = z * Math.cos(theta)+ 0.0065; lat = z * Math.sin(theta) + 0.006; return lng+","+lat; } /** *中国正常坐标系GCJ02协议的坐标,转到 百度地图对应的 BD09 协议坐标 * @param lat 维度 * @param lng 经度 * 返回纬度+经度的字符串 例如 31.12321,119.2321 */ public static String Convert_GCJ02_To_BD09_1(double lat,double lng){ double x = lng, y = lat; double z =Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x)+ 0.000003 * Math.cos(x * x_pi); lng = z * Math.cos(theta)+ 0.0065; lat = z * Math.sin(theta) + 0.006; return lat+","+lng; } /** *百度地图对应的 BD09 协议坐标,转到 中国正常坐标系GCJ02协议的坐标 * @param lat 维度 * @param lng 经度 */ public static String Convert_BD09_To_GCJ02(double lat, double lng){ double x = lng - 0.0065, y = lat - 0.006; double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); lng = z * Math.cos(theta); lat = z * Math.sin(theta); return lat+","+lng; } }

 

你可能感兴趣的:(微信集成)