获取企业微信中登录第三方应用的员工信息

实际项目中需要获取在企业微信中员工的信息,这边做下记录

首先了解企业微信的API

https://work.weixin.qq.com/api/doc#10013

1,自己注册一个测试的企业微信,在应用与小程序里面创建自己的测试应用,在企业微信上发布第三方应用

2,详情看API,主要看关于

3,获取员工信息的思路是(1)通过鉴权的回调获取code(2)固定地获取access_token,(3)通过code和access_token获取UserId(4)通过UserId获取员工信息

(1)通过鉴权的回调获取code:

(2)固定地获取access_token:

https://work.weixin.qq.com/api/doc#10013/%E7%AC%AC%E4%B8%89%E6%AD%A5%EF%BC%9A%E8%8E%B7%E5%8F%96access_token

corpid:我的企业---->企业信息----->

corpsecret:

这里面有两种不同叫法的token

解释:

(3)通过code和access_token获取UserId

(4)通过UserId获取员工信息

注:这个接口在:不在当前页面,因为是第三方,不需要获取user_ticket,再去获取员工信息

--------------------------------------------以下为java代码----------------------------------------------------

直接贴代码了,

controller:

package com.movitech.mobile.controller;

import com.movitech.mobile.entity.Members;
import com.movitech.mobile.service.WechatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping(value = "Wechat")
public class WechatController {
	@Autowired
	private WechatService wechatService;

	@GetMapping(value = "/getMemberInfo")
	public String get(HttpServletRequest request) throws Exception {
		String code = request.getParameter("code");
		Members members = wechatService.getMembersInfo(code);
        return "name:" + members.getName() + ";mobile:" + members.getMobile() + ";email:" + members.getEmail();
	}
}

WechatService

package com.movitech.mobile.service;

import com.movitech.mobile.entity.Members;
import org.json.JSONException;

public interface WechatService {
	Members getMembersInfo(String code) throws IllegalAccessException, JSONException;
}

WechatServiceImp

package com.movitech.mobile.service.impl;

import com.movitech.mobile.entity.AccessToken;
import com.movitech.mobile.entity.Members;
import com.movitech.mobile.service.WechatService;
import com.movitech.mobile.utils.QiYeWeiXinUtil;
import org.json.JSONException;
import org.springframework.stereotype.Service;

@Service("wechatService")
public class WechatServiceImpl implements WechatService {
	@Override
	public Members getMembersInfo(String code) throws JSONException {
		//1,获取access_token
		AccessToken accessToken = QiYeWeiXinUtil.access_token();
		String access_token = accessToken.getAccess_token();
		//2,获取UserId
		String UserId = QiYeWeiXinUtil.getUserId(access_token,code);
		//3,获取Members
		Members members = QiYeWeiXinUtil.getMembers(access_token,UserId);
		return members;
	}
}

QiYeWeiXinUtil

package com.movitech.mobile.utils;

import com.movitech.mobile.entity.AccessToken;
import com.movitech.mobile.entity.Members;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.InputStream;

/**
 * 微信企业号调用类 {"errcode":0,"errmsg":"ok"} 此结果表示调用方法成功返回
 * Created by Cerulean on 2018/8/25.
 */

public class QiYeWeiXinUtil {

    //获取access_token
    public static AccessToken access_token() {
        AccessToken accessToken = null;
        String id = "ww3c9853412b633936";
        String corpsecret = "DjdwKnjlsyzwC82fzspYTOMxmN4dMtA3WHz7hCQGS2A";
        String urlNameString = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=Id&corpsecret=Secrect";
        urlNameString = urlNameString.replace("Id", id);
        urlNameString = urlNameString.replace("Secrect", corpsecret);
        String result = "";
        try {
            // 根据地址获取请求
            HttpGet request = new HttpGet(urlNameString);//这里发送get请求
            // 获取当前客户端对象
            @SuppressWarnings({"resource", "deprecation"})
            HttpClient httpClient = new DefaultHttpClient();
            // 通过请求对象获取响应对象
            HttpResponse response = httpClient.execute(request);

            // 判断网络连接状态码是否正常(0--200都数正常)
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream instream = entity.getContent();
                    result = IOUtils.toString(instream, "utf-8");
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        accessToken = (AccessToken) JsonMapper.fromJsonString(result, AccessToken.class);
        if (accessToken != null) {
            return accessToken;
        }
        return null;
    }

    //获取UserId
    public static String getUserId(String accessToken, String code) throws JSONException {
        String urlNameString = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";
        urlNameString = urlNameString.replace("ACCESS_TOKEN", accessToken);
        urlNameString = urlNameString.replace("CODE", code);
        String result = "";
        try {
            // 根据地址获取请求
            HttpGet request = new HttpGet(urlNameString);//这里发送get请求
            // 获取当前客户端对象
            @SuppressWarnings({"resource", "deprecation"})
            HttpClient httpClient = new DefaultHttpClient();
            // 通过请求对象获取响应对象
            HttpResponse response = httpClient.execute(request);

            // 判断网络连接状态码是否正常(0--200都数正常)
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream instream = entity.getContent();
                    result = IOUtils.toString(instream, "utf-8");
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        JSONObject jsonObject = new JSONObject(result);
        return jsonObject.getString("UserId");
    }

    //获取name,email,mobile
    public static Members getMembers(String accessToken, String userid) throws JSONException {
        Members members = new Members();
        String urlNameString = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&userid=USERID";
        urlNameString = urlNameString.replace("ACCESS_TOKEN", accessToken);
        urlNameString = urlNameString.replace("USERID", userid);
        String result = "";
        try {
            // 根据地址获取请求
            HttpGet request = new HttpGet(urlNameString);//这里发送get请求
            // 获取当前客户端对象
            @SuppressWarnings({"resource", "deprecation"})
            HttpClient httpClient = new DefaultHttpClient();
            // 通过请求对象获取响应对象
            HttpResponse response = httpClient.execute(request);

            // 判断网络连接状态码是否正常(0--200都数正常)
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream instream = entity.getContent();
                    result = IOUtils.toString(instream, "utf-8");
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        JSONObject jsonObject = new JSONObject(result);
        members.setName(jsonObject.getString("name"));
        members.setEmail(jsonObject.getString("email"));
        members.setMobile(jsonObject.getString("mobile"));
        return members;
    }
}

代码上全:包括一些实体类

Members

package com.movitech.mobile.entity;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Members {
    //成员名称
    private String name;
    //手机号码
    private String mobile;
    //邮箱
    private String email;
   /* // 错误code
    private Integer errcode;
    // 错误msg
    private String errmsg;
    //成员UserID
    private String userid;
    //成员名称
    private String name;
    //手机号码
    private String mobile;
    //成员所属部门id列表
    private Integer[] department;
    //部门内的排序值,默认为0
    private Integer[] order;
    //职务信息
    private String position;
    //性别0表示未定义,1表示男性,2表示女性
    private String gender;
    //邮箱
    private String email;
    //上级字段
    private String isleader;
    //头像url
    private String avatar;
    //座机
    private String telephone;
    //成员启用状态。1表示启用的成员,0表示被禁用
    private Integer enable;
    //英文名
    private String english_name;
    //扩展属性
    private JsonObject extattr;
    //激活状态: 1=已激活,2=已禁用,4=未激活。
    private Integer status;
    //员工个人二维码
    private String qr_code;
    //成员对外属性
    private JsonObject external_profile;
*/

    @Override
    public String toString() {
        return "Members{" +
                "name='" + name + '\'' +
                ", mobile='" + mobile + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

JsonMapper

package com.movitech.mobile.utils;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.TimeZone;

/**
 * 简单封装Jackson,实现JSON String<->Java Object的Mapper.
 * 封装不同的输出风格, 使用不同的builder函数创建实例.
 * @author cc
 */
public class JsonMapper extends ObjectMapper {

    private static final long serialVersionUID = 1L;

    private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);

    private static JsonMapper mapper;

    public JsonMapper() {
        this(Include.NON_EMPTY);
    }

    public JsonMapper(Include include) {
        // 设置输出时包含属性的风格
        if (include != null) {
            this.setSerializationInclusion(include);
        }
        // 允许单引号、允许不带引号的字段名称
        this.enableSimple();
        // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
        this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 空值处理为空串
        this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
            @Override
            public void serialize(Object value, JsonGenerator jgen,
                                  SerializerProvider provider) throws IOException,
                    JsonProcessingException {
                jgen.writeString("");
            }
        });
        // 进行HTML解码。
        this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){
            @Override
            public void serialize(String value, JsonGenerator jgen,
                                  SerializerProvider provider) throws IOException,
                    JsonProcessingException {
                jgen.writeString(StringEscapeUtils.unescapeHtml4(value));
            }
        }));
        // 设置时区
        this.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT+8:00")
    }

    /**
     * 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用.
     */
    public static JsonMapper getInstance() {
        if (mapper == null){
            mapper = new JsonMapper().enableSimple();
        }
        return mapper;
    }

    /**
     * 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。
     */
    public static JsonMapper nonDefaultMapper() {
        if (mapper == null){
            mapper = new JsonMapper(Include.NON_DEFAULT);
        }
        return mapper;
    }

    /**
     * Object可以是POJO,也可以是Collection或数组。
     * 如果对象为Null, 返回"null".
     * 如果集合为空集合, 返回"[]".
     */
    public String toJson(Object object) {
        try {
            return this.writeValueAsString(object);
        } catch (IOException e) {
            logger.warn("write to json string error:" + object, e);
            return null;
        }
    }

    /**
     * 反序列化POJO或简单Collection如List<String>.
     *
     * 如果JSON字符串为Null或"null"字符串, 返回Null.
     * 如果JSON字符串为"[]", 返回空集合.
     *
     * 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType)
     * @see #fromJson(String, JavaType)
     */
    public <T> T fromJson(String jsonString, Class<T> clazz) {
        if (StringUtils.isEmpty(jsonString)) {
            return null;
        }
        try {
            return this.readValue(jsonString, clazz);
        } catch (IOException e) {
            logger.warn("parse json string error:" + jsonString, e);
            return null;
        }
    }

    /**
     * 反序列化复杂Collection如List<Bean>, 先使用函數createCollectionType构造类型,然后调用本函数.
     * @see #createCollectionType(Class, Class...)
     */
    @SuppressWarnings("unchecked")
    public <T> T fromJson(String jsonString, JavaType javaType) {
        if (StringUtils.isEmpty(jsonString)) {
            return null;
        }
        try {
            return (T) this.readValue(jsonString, javaType);
        } catch (IOException e) {
            logger.warn("parse json string error:" + jsonString, e);
            return null;
        }
    }

    /**
     * 構造泛型的Collection Type如:
     * ArrayList<MyBean>, 则调用constructCollectionType(ArrayList.class,MyBean.class)
     * HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class)
     */
    public JavaType createCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return this.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    /**
     * 當JSON裡只含有Bean的部分屬性時,更新一個已存在Bean,只覆蓋該部分的屬性.
     */
    @SuppressWarnings("unchecked")
    public <T> T update(String jsonString, T object) {
        try {
            return (T) this.readerForUpdating(object).readValue(jsonString);
        } catch (JsonProcessingException e) {
            logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
        } catch (IOException e) {
            logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);
        }
        return null;
    }

    /**
     * 輸出JSONP格式數據.
     */
    public String toJsonP(String functionName, Object object) {
        return toJson(new JSONPObject(functionName, object));
    }

    /**
     * 設定是否使用Enum的toString函數來讀寫Enum,
     * 為False時時使用Enum的name()函數來讀寫Enum, 默認為False.
     * 注意本函數一定要在Mapper創建後, 所有的讀寫動作之前調用.
     */
    public JsonMapper enableEnumUseToString() {
        this.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
        this.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
        return this;
    }

    /**
     * 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。
     * 默认会先查找jaxb的annotation,如果找不到再找jackson的。
     */
    public JsonMapper enableJaxbAnnotation() {
        JaxbAnnotationModule module = new JaxbAnnotationModule();
        this.registerModule(module);
        return this;
    }

    /**
     * 允许单引号
     * 允许不带引号的字段名称
     */
    public JsonMapper enableSimple() {
        this.configure(Feature.ALLOW_SINGLE_QUOTES, true);
        this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        return this;
    }

    /**
     * 取出Mapper做进一步的设置或使用其他序列化API.
     */
    public ObjectMapper getMapper() {
        return this;
    }

    /**
     * 对象转换为JSON字符串
     * @param object
     * @return
     */
    public static String toJsonString(Object object){
        return JsonMapper.getInstance().toJson(object);
    }

    /**
     * JSON字符串转换为对象
     * @param jsonString
     * @param clazz
     * @return
     */
    public static Object fromJsonString(String jsonString, Class<?> clazz){
        return JsonMapper.getInstance().fromJson(jsonString, clazz);
    }
}

最后,部署完企业微信中应用的url,将后台前台代码发布到外网,在手机端测试,能看见打印员工的name+mobile+email,必须在手机端测,因为code值只能从手机端获取。

拿着员工信息可以做进一步的鉴权。

遇到的一些坑,token的两种获取方式,其实都一样,code只能用一次,因为调试必须每改一行代码就得发布到外网,code,一般都已经被消耗了,你就不能通过微信web开发工具看code,再用它去调试之后的接口,主要是code这个导致第一次玩企业微信,调试要半天!

完。

猜你喜欢

转载自blog.csdn.net/qq_34707991/article/details/82146950