微信已变成我们生活、工作、社交、出行、娱乐的生活方式。这里总结下微信开发的基本功能。
一、微信授权登录或访问第三方网站
微信授权登录或访问第三方网站,需通过微信公众号来授权。
(1)通过接口 https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect进行授权登录
public static void wxBind(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 引导用户进行相关授权,获取code // 创建回调地址 String table=req.getParameter("table"); String shortUrl=req.getParameter("shortUrl"); ReadProperties pro = new ReadProperties(); Map<String, String> map = pro.getProperties(); String protocol = map.get("protocol"); String domain = map.get("domain"); // String port = map.get("port"); String project = map.get("project"); String backUrl = protocol + domain + project + "wexinUtil.do?verify&table="+table+"&shortUrl="+shortUrl; // https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + "appid=" + AuthUtil.APPID + "&redirect_uri=" + URLEncoder.encode(backUrl) + "&response_type=code" + "&scope=snsapi_userinfo" // 选择userinfo作用域 // +"&scope=snsapi_base" //选择userinfo作用域 + "&state=STATE#wechat_redirect"; System.out.println("redirect_uri:" + URLEncoder.encode(backUrl)); resp.sendRedirect(url); // 请求重定向 }
(2)授权成功后,会跳转到backUrl的地址
@RequestMapping(params = "verify") protected Object verify(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String table=req.getParameter("table"); String shortUrl=req.getParameter("shortUrl"); String code=req.getParameter("code");//获取OAuth2.0请求后,服务器返回的code内容,这个code在接下来向微信服务请求用户信息时会使用 System.out.println("code::::::::"+code); //https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code String url="https://api.weixin.qq.com/sns/oauth2/access_token?" +"appid="+AuthUtil.APPID +"&secret="+AuthUtil.APPSECRET +"&code="+code +"&grant_type=authorization_code"; //发送请求 JSONObject jsonObject=AuthUtil.doGetJson(url); System.out.println("jsonObject新获取::::::::"+jsonObject); String openid=jsonObject.getString("openid"); String token=jsonObject.getString("access_token"); //判断用户是否关注公众号 String isFollow = judgeIsFollow(getAccessToken().getToken(),openid); System.out.println("isFollow==="+isFollow); //拉取用户信息路径 //https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN /*String infoUrl="https://api.weixin.qq.com/sns/userinfo?access_token="+token +"&openid="+openid +"&lang=zh_CN"; //发送请求 JSONObject userInfo=AuthUtil.doGetJson(infoUrl); System.out.println("userInfo:"+userInfo); */ //链接数据库查询 String sql = "select user_code,operation,bind from user_mobile_er where openid='"+openid+"'"; System.out.println("sql+++++++++"+sql); List<Map<String, Object>> findList = systemService.findForJdbc(sql); System.out.println("findList+++++++++"+findList); System.out.println("openid===="+openid); String bind=null; String operation=null; if(findList!=null&&findList.size()>0){ operation= (String) findList.get(0).get("operation"); bind=(String) findList.get(0).get("bind");// 结果为Y/N }else { bind="0";//用户未申请绑定 operation="0";//无维护权限 } System.out.println("redirect:/resftlCon.do?"+table+"&shortUrl="+shortUrl); //return "redirect:/resftlCon.do?"+table+"&shortUrl="+shortUrl+"&openid="+openid+"&bind=Y"; return "redirect:/resftlCon.do?"+table+"&shortUrl="+shortUrl+"&isFollow="+isFollow+"&bind="+bind+"&operation="+operation+"&openid="+openid; }
二、微信用户与第三方平台绑定
每个微信用户针对每个公众号有个唯一标识openid,我们可通过授权访问时获取的openID与数据库中存储的指定用户的openID进行对比
三、判断否关注公众号(使用openID和access_token)
/** * 判断用户是否关注了公众号 * @param token * @param openid * @return */ public static String judgeIsFollow(String token,String openid){ // Integer subscribe=0; String subscribe=null; String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+token+"&openid="+openid+"&lang=zh_CN"; try { URL urlGet = new URL(url); HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); http.setRequestMethod("GET"); // 必须是get方式请求 http.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); http.setDoOutput(true); http.setDoInput(true); http.connect(); InputStream is = http.getInputStream(); int size = is.available(); byte[] jsonBytes = new byte[size]; is.read(jsonBytes); String message = new String(jsonBytes, "UTF-8"); System.out.println("message字符串==="+message); JSONObject demoJson = JSONObject.fromObject(message); System.out.println("JSON字符串==="+demoJson); subscribe=demoJson.get("subscribe").toString(); //subscribe = demoJson.getInt("subscribe"); System.err.println("subscribe在json中值为==="+subscribe); is.close(); } catch (Exception e) { e.printStackTrace(); } //return 1==subscribe?true:false; return "1".equals(subscribe)?"Y":"N"; }
通过接口https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+AuthUtil.APPID+"&secret="+AuthUtil.APPSECRET
获取access_token
/** * 获取AccessToken * @return 返回拿到的access_token及有效期 */ public static AccessToken getAccessToken() throws ClientProtocolException, IOException{ AccessToken token = new AccessToken(); String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+AuthUtil.APPID+"&secret="+AuthUtil.APPSECRET; JSONObject jsonObject = doGetStr(url);//使用刚刚写的doGet方法接收结果 if(jsonObject!=null){ //如果返回不为空,将返回结果封装进AccessToken实体类 token.setToken(jsonObject.getString("access_token"));//取出access_token token.setExpiresIn(jsonObject.getInt("expires_in"));//取出access_token的有效期 } System.out.println("==============token:"+token.getToken()+"expiresIn:"+token.getExpiresIn()); return token; } /** * 编写Get请求的方法。但没有参数传递的时候,可以使用Get请求 * * @param url 需要请求的URL * @return 将请求URL后返回的数据,转为JSON格式,并return */ public static JSONObject doGetStr(String url) throws ClientProtocolException, IOException { DefaultHttpClient client = new DefaultHttpClient();//获取DefaultHttpClient请求 HttpGet httpGet = new HttpGet(url);//HttpGet将使用Get方式发送请求URL JSONObject jsonObject = null; HttpResponse response = client.execute(httpGet);//使用HttpResponse接收client执行httpGet的结果 HttpEntity entity = response.getEntity();//从response中获取结果,类型为HttpEntity if(entity != null){ String result = EntityUtils.toString(entity,"UTF-8");//HttpEntity转为字符串类型 jsonObject = JSONObject.fromObject(result);//字符串类型转为JSON类型 } return jsonObject; }
AccessToken的实体类
package com.jeecg.util.wxBind; public class AccessToken { public String token; public int expiresIn; public String getToken() { return token; } public void setToken(String token) { this.token = token; } public int getExpiresIn() { return expiresIn; } public void setExpiresIn(int expiresIn) { this.expiresIn = expiresIn; } }
四、第三方平台对指定用户进行消息推送(需要使用weixin4j.jar)
使用接口https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+oAuthToken.getAccess_token()
进行推送;消息推送的前提是该指定用户已关注认证公众号。
package com.jeecg.util.wxBind; import java.net.URLEncoder; import java.util.Map; import org.weixin4j.Configuration; import org.weixin4j.Weixin; import org.weixin4j.WeixinException; import org.weixin4j.WeixinSupport; import org.weixin4j.http.HttpsClient; import org.weixin4j.http.OAuthToken; import org.weixin4j.http.Response; import com.alibaba.fastjson.JSONObject; import com.jeecg.controller.demo.ReadProperties; import com.jeecg.controller.wx.auth.util.AuthUtil; public class WeixinMessagePush extends WeixinSupport { Weixin weixin=new Weixin(); OAuthToken oAuthToken=null; public WeixinMessagePush(){ } public WeixinMessagePush(String appId,String secret){ try { oAuthToken = weixin.login(appId, secret); } catch (WeixinException e) { e.printStackTrace(); } } public void templateMessagePush(String openId,String title,String description) throws WeixinException{ JSONObject json=new JSONObject(); JSONObject text=new JSONObject(); JSONObject keyword1=new JSONObject(); JSONObject keyword2=new JSONObject(); JSONObject first=new JSONObject(); JSONObject remark=new JSONObject(); json.put("touser",openId); json.put("template_id","jhES0sm0yRNXxe8USlYcB1nsaS568gtFt7l6_qCY4_8"); ReadProperties pro = new ReadProperties(); Map<String, String> map = pro.getProperties(); String protocol = map.get("protocol"); String domain = map.get("domain"); // String port = map.get("port"); String project = map.get("project"); String backUrl = protocol + domain + project + "userMobileErController.do?remark"; String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + "appid=" + AuthUtil.APPID + "&redirect_uri=" + URLEncoder.encode(backUrl) + "&response_type=code" + "&scope=snsapi_userinfo" // 选择userinfo作用域 // +"&scope=snsapi_base" //选择userinfo作用域 + "&state=STATE#wechat_redirect"; // json.put("url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx22c699fe80c91471&redirect_uri=http%3A%2F%2Fwewill9014.s1.natapp.cc%2FPTCOA%2Fservlet%2FOAuthAPIServlet&response_type=code&scope=snsapi_userinfo&state=state#wechat_redirect"); json.put("utl", url); json.put("topcolor","#ff1a75"); first.put("value",title); // first.put("color","#007f80"); keyword1.put("value",description ); // keyword1.put("color", "#007f80"); keyword2.put("value","通过" ); // keyword2.put("color","#007f80"); remark.put("value", "如有疑问请联系管理员"); remark.put("color", "#007f80"); text.put("keyword1", keyword1); text.put("keyword2", keyword2); text.put("first", first); text.put("remark",remark); json.put("data", text); //创建请求对象 HttpsClient http=new HttpsClient(); Response res = http.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+oAuthToken.getAccess_token(), json); //根据请求结果判定,是否验证成功 JSONObject jsonObj = res.asJSONObject(); if (jsonObj != null) { if (Configuration.isDebug()) { System.out.println("模板消息返回json:" + jsonObj.toString()); } Object errcode = jsonObj.get("errcode"); if (errcode != null && !errcode.toString().equals("0")) { //返回异常信息 throw new WeixinException(getCause(Integer.parseInt(errcode.toString()))); } } } }