zoukankan      html  css  js  c++  java
  • ~随笔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())));
                }
            }   
        }   
    }
    

      

  • 相关阅读:
    LeetCode 79. 单词搜索
    LeetCode 1143. 最长公共子序列
    LeetCode 55. 跳跃游戏
    LeetCode 48. 旋转图像
    LeetCode 93. 复原 IP 地址
    LeetCode 456. 132模式
    LeetCode 341. 扁平化嵌套列表迭代器
    LeetCode 73. 矩阵置零
    LeetCode 47. 全排列 II
    LeetCode 46. 全排列
  • 原文地址:https://www.cnblogs.com/gaojl/p/8405186.html
Copyright © 2011-2022 走看看