~随笔A006~微信扫码的授权、用户绑定、关注公众号、消息反馈

  微信已变成我们生活、工作、社交、出行、娱乐的生活方式。这里总结下微信开发的基本功能。

  一、微信授权登录或访问第三方网站

    微信授权登录或访问第三方网站,需通过微信公众号来授权。

  (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())));
            }
        }   
    }   
}

  

原文地址:https://www.cnblogs.com/gaojl/p/8405186.html