微信订阅号获取用户基本信息-JAVA

前言

微信公众号分为订阅号和服务号两种,两种公众号对权限,发送频率,显示的级别都不相同,用户可以根据需求选择适合的公众号种类,两者的区别这里不作叙述。

在整理文章的时候先查了一遍官网的资料,发现现在订阅号已经不能直接升级为服务号了(之前是有一次升级的机会的),所以在选择时请慎重!

正文

今天主要讲的是订阅号通过openid获取用户基本信息,通过微信开放平台的官方文档可以知道,服务号是可以直接通过oauth2.0进行网页授权获取用户基本信息,而认证的订阅号也有获取用户基本信息的权限,但是不同的是,订阅号并不是用通过服务号相同的通过网页授权的方式,订阅号需要用户主动触发才能获得,需要进行在订阅号中点击菜单或者发送信息等交互操作才可以获得。

Created with Raphaël 2.2.0 开始 配置微信后台与服务器的后台交互 与服务器产生交互获取用户openid 通过appid和secret获取access_token 通过openid和access_token获取用户基本信息 返回用户基本信息? 结束 yes no

好了,大致的流程图已经看完了,现在来写个例子,这里我直接用springboot来写:

首先,写一个CheckUtil,与微信服务端进行交互验证并获得授权,这里的token与微信公众平台的后台服务器配置一致即可:

import java.security.MessageDigest;
import java.util.Arrays;

public class CheckUtil {
	private static final String token = "checkit";

	public static boolean CheckSignature(String signature, String timestamp, String nonce) {

		String[] arr = new String[] { token, timestamp, nonce };
		// 排序
		Arrays.sort(arr);
		//
		StringBuffer content = new StringBuffer();
		for (int i = 0; i < arr.length; i++) {
			content.append(arr[i]);
		}
		//
		String temp = getSha1(content.toString());

		return temp.equals(signature);

	}

	public static String getSha1(String str) {
		if (null == str || 0 == str.length()) {
			return null;
		}
		char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
			mdTemp.update(str.getBytes("UTF-8"));

			byte[] md = mdTemp.digest();
			int j = md.length;
			char[] buf = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
				buf[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(buf);
		} catch (Exception e) {
			return null;
		}
	}
}

定义用户基本信息的bean类:

public class UserDetail {

	// {"subscribe":1,"openid":"o3UkH0vwlJlLhzQGxhP9Xh-1_NSQ","nickname":"MMY","sex":2,"language":"zh_CN","city":"深圳","province":"广东","country":"中国","headimgurl":"http:\/\/thirdwx.qlogo.cn\/mmopen\/lbkVE3rsT19JuuAg0lLp44rRJEU5m2KANfQxfx7KFlsibl9triazkqAIMz8AiaAp0lNyWjhXMXBBvbMXQiagP2ED9FWK30EuErDS\/132","subscribe_time":1536321291,"remark":"","groupid":0,"tagid_list":[],"subscribe_scene":"ADD_SCENE_QR_CODE","qr_scene":0,"qr_scene_str":""}

	private String openid;
	private String nickname;
	private int sex;
	private String city;
	private String province;
	private String country;
	private String headimgurl;
	private int subscribe;
	private String subscribe_time;
	private String subscribe_scene;
	private String groupid;
	private String tagid_list;
	private String remark;

	public String getOpenid() {
		return openid;
	}

	public void setOpenid(String openid) {
		this.openid = openid;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public int getSex() {
		return sex;
	}

	public void setSex(int sex) {
		this.sex = sex;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public String getHeadimgurl() {
		return headimgurl;
	}

	public void setHeadimgurl(String headimgurl) {
		this.headimgurl = headimgurl;
	}

	public int getSubscribe() {
		return subscribe;
	}

	public void setSubscribe(int subscribe) {
		this.subscribe = subscribe;
	}

	public String getSubscribe_time() {
		return subscribe_time;
	}

	public void setSubscribe_time(String subscribe_time) {
		this.subscribe_time = subscribe_time;
	}

	public String getSubscribe_scene() {
		return subscribe_scene;
	}

	public void setSubscribe_scene(String subscribe_scene) {
		this.subscribe_scene = subscribe_scene;
	}

	public String getGroupid() {
		return groupid;
	}

	public void setGroupid(String groupid) {
		this.groupid = groupid;
	}

	public String getTagid_list() {
		return tagid_list;
	}

	public void setTagid_list(String tagid_list) {
		this.tagid_list = tagid_list;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	@Override
	public String toString() {
		return "UserDetail [openid=" + openid + ", nickname=" + nickname + ", sex=" + sex + ", city=" + city
				+ ", province=" + province + ", country=" + country + ", headimgurl=" + headimgurl + ", subscribe="
				+ subscribe + ", subscribe_time=" + subscribe_time + ", subscribe_scene=" + subscribe_scene
				+ ", groupid=" + groupid + ", tagid_list=" + tagid_list + ", remark=" + remark + "]";
	}

}

定义一个WeixinUtil工具类:

import com.alibaba.fastjson.JSON;
import com.checkit.bean.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class WeixinUtil {
    private static final String APPID = "替换成自己的APPID";
    private static final String APPSECRET = "替换成自己的SECRET";
    //获取access_token的地址
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    //发送模板信息的地址
    private static final String SEND_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
    //获取用户信息的地址
    private static final String GET_USER_INFO = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";


    /**
     * 获取用户信息
     *
     * @param openId
     * @return
     */
    public static String getUserInfo(String openId) {
        return httpGet(GET_USER_INFO.replace("ACCESS_TOKEN", getAcessToken()).replaceAll("OPENID", openId));
    }

    /**
     * get
     *
     * @param url
     * @return
     */
    public static String doGetStr(String url) {

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        // JSONObject jsonObject = null;
        String result = "";
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                result = EntityUtils.toString(entity, "UTF-8");
                // jsonObject = JSONObject.fromObject(result);
                return result;
            }
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return result;

    }

    public static String httpGet(String url) {
        // get请求返回结果
        String strResult = null;
        try {
            DefaultHttpClient client = new DefaultHttpClient();
            // 发送get请求
            HttpGet request = new HttpGet(url);
            HttpResponse response = client.execute(request);

            /** 请求发送成功,并得到响应 **/
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                /** 读取服务器返回过来的json字符串数据 **/
                strResult = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return strResult;
    }

    /**
     * post
     *
     * @param url
     * @param outStr
     * @return
     */
    public static String doPostStr(String url, String outStr) {

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        // JSONObject jsonObject = null;
        String result = "";
        try {
            httpPost.setEntity(new StringEntity(outStr, "UTF-8"));
            HttpResponse response = httpClient.execute(httpPost);
            result = EntityUtils.toString(response.getEntity(), "UTF-8");
            // jsonObject = JSONObject.fromObject(result);
            return result;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;

    }

    /**
     * access_token
     *
     * @return
     */
    public static String getAcessToken() {

        AcessToken token = new AcessToken();
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        String tokenFtxt = "";

        Calendar c;
        String dir = System.getProperty("user.dir");
        dir = dir + File.separator + "token.txt";
        File file = new File(dir);
        if (!file.exists()) {
            try {
                // System.out.println("【ACCESS_TOKEN】-->acess_token文件不存在");
                String url = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
                String jsonStr = doGetStr(url);

                if (jsonStr != null) {
                    TokenResponse response = JSON.parseObject(jsonStr, TokenResponse.class);
                    token.setToken(response.getAccess_token());
                    token.setExpiresIn(response.getExpires_in());
                }
                fos = new FileOutputStream(dir);
                osw = new OutputStreamWriter(fos, "UTF-8");
                bw = new BufferedWriter(osw);
                c = Calendar.getInstance();
                // int date = c.get(Calendar.DATE);
                // int hour = c.get(Calendar.HOUR_OF_DAY);
                bw.write(token.getToken() + "\r\n");
                bw.write(System.currentTimeMillis() + "\r\n");
                // bw.write(date + "\r\n");
                // bw.write(hour + "\r\n");
                return token.getToken();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    if (bw != null)
                        bw.close();
                    if (osw != null)
                        osw.close();
                    if (fos != null)
                        fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }

        } else {
            BufferedReader bf = null;
            try {
                bf = new BufferedReader(new FileReader(file));
                tokenFtxt = bf.readLine();
                String last = bf.readLine();
                // String date = bf.readLine();
                // String hour = bf.readLine();

                if (tokenFtxt.isEmpty()) {
                    // System.out.println("【ACCESS_TOKEN】-->acess_token文件为空");
                    file.delete();
                    String url = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
                    String jsonStr = doGetStr(url);

                    if (jsonStr != null) {
                        TokenResponse response = JSON.parseObject(jsonStr, TokenResponse.class);
                        token.setToken(response.getAccess_token());
                        token.setExpiresIn(response.getExpires_in());
                    }
                    fos = new FileOutputStream(dir);
                    osw = new OutputStreamWriter(fos, "UTF-8");
                    bw = new BufferedWriter(osw);
                    c = Calendar.getInstance();
                    // int date2 = c.get(Calendar.DATE);
                    // int hour2 = c.get(Calendar.HOUR_OF_DAY);
                    bw.write(token.getToken() + "\r\n");
                    bw.write(System.currentTimeMillis() + "\r\n");
                    // bw.write(date2 + "\r\n");
                    // bw.write(hour2 + "\r\n");
                    return token.getToken();
                } else if (checkTimeOUt(last)) {
                    // System.out.println("【ACCESS_TOKEN】-->acess_token超时");
                    file.delete();
                    String url = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
                    String jsonStr = doGetStr(url);

                    if (jsonStr != null) {
                        TokenResponse response = JSON.parseObject(jsonStr, TokenResponse.class);
                        token.setToken(response.getAccess_token());
                        token.setExpiresIn(response.getExpires_in());
                    }
                    fos = new FileOutputStream(dir);
                    osw = new OutputStreamWriter(fos, "UTF-8");
                    bw = new BufferedWriter(osw);
                    c = Calendar.getInstance();
                    int date2 = c.get(Calendar.DATE);
                    int hour2 = c.get(Calendar.HOUR_OF_DAY);
                    bw.write(token.getToken() + "\r\n");
                    bw.write(System.currentTimeMillis() + "\r\n");
                    return token.getToken();
                } else {
                    return tokenFtxt;
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    if (bf != null)
                        bf.close();
                    if (bw != null)
                        bw.close();
                    if (osw != null)
                        osw.close();
                    if (fos != null)
                        fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
        return null;

    }

    private static boolean checkTimeOUt(String lastTime) {
        long last = Long.parseLong(lastTime);
        long current = System.currentTimeMillis();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy年-MM月dd日-HH时mm分ss秒");
        // System.out.println("【ACCESS_TOKEN】-->上次获取token时间"
        // + formatter.format(new Date(last)));
        // System.out.println("【ACCESS_TOKEN】-->当前获取token时间"
        // + formatter.format(new Date(current)));
        float during = (current - last) / 1000;
        if (during > 1 * 60 * 60) {
            // System.out.println("【ACCESS_TOKEN】-->during=" + during
            // + "token已经超时");
            return true;
        }
        // System.out.println("【ACCESS_TOKEN】-->during=" + during + "token未超时");
        return false;
    }


    public static Map<String, String> xmlToMap(String str) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        if (str == null || str.isEmpty() || str.length() <= 0)
            return null;
        Document document = DocumentHelper.parseText(str);
        Element root = document.getRootElement();
        Iterator<?> list = root.elementIterator();
        while (list.hasNext()) {
            Element e = (Element) list.next();
            map.put(e.getName(), e.getText());
        }
        return map;
    }

}

接下来是controller层,定义访问接口:

import com.alibaba.fastjson.JSON;
import com.checkit.Service.WechatService;
import com.checkit.Utils.CheckUtil;
import com.checkit.Utils.WeixinUtil;
import com.checkit.bean.UserDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
public class WechatController {
	@Autowired
	WechatService wechatService;

	@GetMapping(value = "wechat")
	public String getWechatGet(@RequestParam String signature, @RequestParam String timestamp,
			@RequestParam String nonce, @RequestParam String echostr) {
		System.out.println("接受到token验证");
		return CheckUtil.CheckSignature(signature, timestamp, nonce) ? echostr : null;
	}
	
	@GetMapping(value = "/wechat/getUserInfo")
	public String getUserInfo(@RequestParam String openId) {
		String userInfo = WeixinUtil.getUserInfo(openId);
		UserDetail userDetail = JSON.parseObject(userInfo, UserDetail.class);
		System.out.println("userInfo imgUrl : " + userDetail.getHeadimgurl());
		return userInfo;
	}

}

打包完部署到接收微信server推送的服务器上,运行,然后直接在浏览器输入http://接收微信server推送的服务器IP/wechat/getUserInfo?openId=用户的openId,即可获得用户信息。
总结下来主要是几步:

1.建立自己服务器跟微信服务器的连接;

2.通过微信公众平台后台提供的APPID和SECRET获取access_token,注意access_token的过期时间;

3.用户通过与微信公众号交互将openid发送至自己的服务器,此处获取用户的openid;

4.通过将openid和access_token作为参数访问微信官方接口获取用户基本信息,根据自己的需求进行处理;

微信订阅号获取用户基本信息的流程今天就分享到这里,如有纰漏,欢迎指正,感谢~

发布了29 篇原创文章 · 获赞 9 · 访问量 9967

猜你喜欢

转载自blog.csdn.net/weixin_42669785/article/details/88039106