关于如何获取微信已关注用户的基本信息,我这里先说一下步骤:那些基本的信息就不多说了,如AppID,AppSecret1、首先成为开发者,需要外网,如果没有外网,建议在花生壳申请一个账号,通过映射,可以映射到外网,配置好了,如下界面
2、完成第一步后,接下来就是获取opinid了,关于如何获取openID,其实是比较头疼的,网上给出了各种各样的答案,我这里详细说一下,
3、设置好了回调域名,接下来就是通过网页来授权了
文档也说了,有两种方式:
我用的是第二种,因为第一种要用到https协议,工作紧,故没有去试,那我直接说第二种:
请求地址是:
APPID不用说了吧,redirect_uri这个,请记住,这个一定是你回调域名下面的一级,如果你的回调域名为
那你的redirect_uri填的是weixin下的一级,不能跨级。weixin这个是我的项目名,那redirect_uri可以填weixin/servlet,也可以填weixin/index.jsp,记得URL转码。scope为snsapi_userinfo,其他参数默认就行了,稍后本人会加上我的项目供大家参考,因为本人也很菜,代码就见笑了。。
如果这个填好了,那其他的基本没什么问题了,如果有疑问,欢迎大家加我工作qq320302887,乐意解答。
接下来用代码解释一下。
这是我们要获得用户的一些基本信息(User类)//用户的唯一标识
private String openId;
// 关注状态(1是关注,0是未关注),未关注时获取不到其余信息
private int subscribe;
// 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
private String subscribeTime;
// 昵称
private String nickname;
// 用户的性别(1是男性,2是女性,0是未知)
private int sex;
// 用户所在国家
private String country;
// 用户所在省份
private String province;
// 用户所在城市
private String city;
// 用户的语言,简体中文为zh_CN
private String language;
// 用户头像地址
private String headImgUrl;
记得get set这些属性。
这是我们要获得token,获得的Accesstoken只有两个小时的生命,多刷新。
// 接口访问凭证
private String accessToken;
// 凭证有效期,单位:秒
private int expiresIn;
记得get set这两个属性。 还要这个类
public class MyX509TrustManager implements X509TrustManager{ // 检查客户端证书 @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } // 检查服务器端证书 @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } // 返回受信任的X509证书数组 @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; }
然后还要写一个CommonUtil类,
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import net.sf.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CommonUtil { // private static Logger log = LoggerFactory.getLogger(CommonUtil.class); // 凭证获取(GET) // public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=OPENID&secret=APPSECRET"; /** * 发送https请求 * "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID" * * @param requestUrl * 请求地址 * @param requestMethod * 请求方式(GET、POST) * @param outputStr * 提交的数据 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) */ public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { System.out.println("进入httpsRequest方法"); JSONObject jsonObject=null; try { // 创建SSLContext对象,并使用我们指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 设置请求方式(GET/POST) conn.setRequestMethod(requestMethod); // 当outputStr不为null时向输出流写数据 if (null != outputStr) { OutputStream outputStream = conn.getOutputStream(); // 注意编码格式 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 从输入流读取返回内容 InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader( inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader( inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 释放资源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; conn.disconnect(); jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { // log.error("连接超时:{}", ce); } catch (Exception e) { // log.error("https请求异常:{}", e); } // System.out.println("json为123:"+jsonObject); return jsonObject; } /** * 获取接口访问凭证 * * @param appid * 凭证 * @param appsecret * 密钥 * @return * https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential * &appid=OPENID&secret=APPSECRET */ public static Token getToken(String appid, String appsecret) { Token token = null; String requestUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+appsecret; // String requestUrl = token_url.replace("APPID", appid).replace( // "APPSECRET", appsecret); // 发起GET请求获取凭证 JSONObject jsonObject = httpsRequest(requestUrl, "GET", null); if (null != jsonObject) { try { token = new Token(); token.setAccessToken(jsonObject.getString("access_token")); token.setExpiresIn(jsonObject.getInt("expires_in")); } catch (Exception e) { token = null; // // 获取token失败 // log.error("获取token失败 errcode:{} errmsg:{}", // jsonObject.getInt("errcode"), // jsonObject.getString("errmsg")); } } System.out.println(token); return token; } /** * URL编码(utf-8) * 因为只是获取用户基本信息,故下面两个方法用不到 * @param source * @return */ /* public static String urlEncodeUTF8(String source) { String result = source; try { result = java.net.URLEncoder.encode(source, "utf-8"); } catch (Exception e) { e.printStackTrace(); } return result; }*/ /** * 根据内容类型判断文件扩展名 * * @param contentType * 内容类型 * @return */ /* public static String getFileExt(String contentType) { String fileExt = ""; if ("image/jpeg".equals(contentType)) fileExt = ".jpg"; else if ("audio/mpeg".equals(contentType)) fileExt = ".mp3"; else if ("audio/amr".equals(contentType)) fileExt = ".amr"; else if ("video/mp4".equals(contentType)) fileExt = ".mp4"; else if ("video/mpeg4".equals(contentType)) fileExt = ".mp4"; return fileExt; }*/ }
这个类就这两个方法供使用。
然后就是用户信息实现的类我这里省去,因为我直接写在servlet里了,额,代码好乱,等下再整理吧,加上自己写代码的过程。
public class Servlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; private static String code; private static String oauth2_url; private static String openid; private static String appid="wxd00dac2a2ee71120"; private static String appsecret="db9f234cd02a73e809f5ab02a35e6f09"; private static JSONObject jsonObject; private static JSONObject jsonObject1; private static String accessToken; private static User user; // private static int subscribe; // private static String access_token="EMpAts8L2GNBPCqd7JwZSD4vAsS9SjK_MoF1aTGxqe8iRXY4Dgh7xZAhDdVpfTFkG6SC9_SuYzyHMNQopxqFrtZdqE9zNZsrJerPY28-JiRqCooYncA3dg8bH1q3JwslDWZdABARKN"; // public String Getco(){ // return code; // } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); System.out.println("Servlet"); code=request.getParameter("code"); oauth2_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxd00dac2a2ee71120&secret=db9f234cd02a73e809f5ab02a35e6f09&code="+code+"&grant_type=authorization_code"; System.out.println("code:" + code); // String openId = CommonUtil1.getOpenId(code); // System.out.println("openid"+openId); jsonObject = CommonUtil.httpsRequest(oauth2_url, "POST", null); openid = jsonObject.getString("openid"); // subscribe=jsonObject.getInt("subscribe"); // System.out.println("获得的subscribe为"+subscribe); System.out.println("获得的openID为"+openid); Token token = CommonUtil.getToken(appid, appsecret); accessToken=token.getAccessToken(); System.out.println(token); System.out.println("最后的opinion*-----"+openid); user = getUserInfo(accessToken,openid); int s=jsonObject1.getInt("subscribe"); System.out.println(s); System.out.println("------------------------"); // openid = jsonObject.getString("openid"); System.out.println(openid); // int subscribe = jsonObject.getInt("subscribe"); System.out.println(jsonObject); // System.out.println(subscribe); System.out.println("这个user为、、、、、、、、、、"+user); } public static User getUserInfo(String accessToken, String openId) { System.out.println("进入getUserInfo方法"); user = null; // jsonObject1=null; String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openId; //appid wx69d4d8acc08af18e //9f4b4d5d514b45054d25c1c2787062cf // 拼接请求地址 //https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID // requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace( // "OPENID", openId); // 获取用户信息 jsonObject1 = CommonUtil .httpsRequest(requestUrl, "POST", null); System.out.println(jsonObject1); System.out.println("到这了没有"); if (jsonObject1.getJSONArray("tagid_list").isEmpty()) { System.out.println("进来了没有"); // user.setOpenId(jsonObject1.getString("openid")); System.out.println("这里的opinid777777777"); // int ss = jsonObject1.getInt("subscribe"); // user.setSubscribe(jsonObject1.getInt("subscribe")); // System.out.println("执行了没有"); return user; } System.out.println("想要的json:"+jsonObject1); if (null != jsonObject1) { try { user = new User(); // 用户的标识 System.out.println(333); user.setOpenId(jsonObject1.getString("openid")); // 关注状态(1是关注,0是未关注),未关注时获取不到其余信息 // user.setSubscribe(ss); // 用户关注时间 user.setSubscribeTime(jsonObject1.getString("subscribe_time")); // 昵称 user.setNickname(jsonObject1.getString("nickname")); // 用户的性别(1是男性,2是女性,0是未知) user.setSex(jsonObject1.getInt("sex")); // 用户所在国家 user.setCountry(jsonObject1.getString("country")); // 用户所在省份 user.setProvince(jsonObject1.getString("province")); // 用户所在城市 user.setCity(jsonObject1.getString("city")); // 用户的语言,简体中文为zh_CN user.setLanguage(jsonObject1.getString("language")); // 用户头像 user.setHeadImgUrl(jsonObject1.getString("headimgurl")); } catch (Exception e) { // if (0 == user.getSubscribe()) { // log.error("用户{}已取消关注", user.getOpenId()); // } else { // int errorCode = jsonObject.getInt("errcode"); // String errorMsg = jsonObject.getString("errmsg"); // log.error("获取用户信息失败 errcode:{} errmsg:{}", errorCode, // errorMsg); // } e.printStackTrace(); } } // System.out.println("user为:--"+user); return user; }
这里有一点要注意,如果用户没有关注就无法获得他的基本信息了,只能获得他的openID和关注状态,关注的用户就可以获得全部了就以上代码放同一个包应该就不会报错了,
以下是微信客户端打开链接获得的信息:
还有一些jar包需要下载
这里要配置一下web.xml,配置那个servlet。。。
所需jar下载地址:http://pan.baidu.com/s/1bo2n4qr 密码:8y3m。