微信公众号开发-静默授权实现消息推送(微服务方式)

  一:引用pom

    <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>weixin-java-mp</artifactId>
      <version>${weixin-java-mp.version}</version>
    </dependency>

 

二:获取code

  注意:redirect_uri 回调地址。请求完成后,微信在回调该地址的时候会带上code,然后根据code去拿openId。亲测不需要编码!!!

       要在微信客户端打开接口地址,推荐工具https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455784140 微信官方web开发工具。

  传入appId就行了,state是回调的时候带的参数

  @ApiOperation(value = "获取code,并回调获取openId", notes = "获取code,并回调获取openId")
  @GetMapping(value = "/routerForOpenId")
  public void redirectToMyPage(HttpServletRequest request, HttpServletResponse response,
      String phone) {
    StringBuffer sb = new StringBuffer();
    StringBuffer encodeUrl = new StringBuffer(300);
    //公众号中配置的回调域名(网页授权回调域名)
//    String doname =
//        request.getScheme() + "://" + request.getServerName() + (-1 == request.getLocalPort() ? ""
//            : ":" + request.getLocalPort());
    String doname = "http://xuexing.ngrok.xiaomiqiu.cn";
    String root = "/WeChat";
    String appId = "wxb6fac4047e049312";
    sb.append("https://open.weixin.qq.com/connect/oauth2/authorize?appid=");
    sb.append(appId);
    String url = "";
    try {
      //对重定向url进行编码,官方文档要求
      encodeUrl.append(doname).append(root).append("/openId.html");
//      url = URLEncoder.encode(encodeUrl.toString(), "utf-8");
      sb.append("&redirect_uri=").append(encodeUrl.toString());
      //网页授权的静默授权snsapi_base
      sb.append("&response_type=code&scope=snsapi_base&state=").append(phone);
      sb.append("#wechat_redirect");
      response.sendRedirect(sb.toString());
    } catch (UnsupportedEncodingException e) {
      log.error("重定向url编码失败:>>" + e.getMessage());
      e.printStackTrace();
    } catch (Exception e) {
      log.error("response重定向失败:>>" + e.getMessage());
      e.printStackTrace();
    }
  }

三:回调地址方法

  调用回调地址之前需要一些准备工作:

  1,回调地址需要做一个内网穿透,推荐工具Ngrok,花生壳。。本人使用的是Ngrok

    1)在Ngrok官网下载好客户端 http://www.ngrok.cc/download.html  

    

 

    2)在官网注册账号并开通隧道 http://www.ngrok.cc  按官网教程开通,有免费隧道,完全可以满足本地开发使用。

    3)运行Sunny-Ngrok启动工具.bat   在命令行中输入 clientId (就是在官网注册的邮箱)和 隧道Id(看清,是Id 不是名字)

    4)成功后界面,恭喜你内网穿透已经做好,可以在外网环境访问你的服务接口了。

     

 

  2,配置微信授权域名

    1)微信公众平台 https://mp.weixin.qq.com/ 

    

    

      

      

     2)在保存的时候,会验证是否在你域名的根目录下保存了这个文件。事实上他验证的本质就是通过 [域名+/txt文件名] 是否能访问到txt文件中的字符码,所以我们在微服务中写一个接口将文件中字符返回出来,保存的时候就能校验通过了。

      注意:[域名+/txt文件名]和[域名+/openId.html]一定要都可以访问同,微信才能通过 redirect_uri 回调

       

 

     

    

@ApiOperation(value = "回调获取openId", notes = "回调获取openId")
  @GetMapping(value = "/openId.html")
  //发送请求,根据code获取openId
  public String getOpenId(HttpServletRequest request, HttpServletResponse response, String code,
      String state) {

    String content = "";
    String openId = "";
    String unionId = "";
    //封装获取openId的微信API
    StringBuffer url = new StringBuffer();
    url.append("https://api.weixin.qq.com/sns/oauth2/access_token?appid=")
        .append("wxb6fac4047e049312")
        .append("&secret=")
        .append("726b163b73fe82a282903084805b663a")
        .append("&code=")
        .append(code)
        .append("&grant_type=authorization_code");

    ObjectMapper objectMapper = new ObjectMapper();
    try {
      HttpGet httpGet = new HttpGet(url.toString());//这里发送get请求
      HttpClient httpClient = HttpClientBuilder.create().build();
      HttpResponse httpResponse = httpClient.execute(httpGet);
      // 判断网络连接状态码是否正常(0--200都数正常)
      if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
        content = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
      }
      Map map = objectMapper.readValue(content, Map.class);
      openId = String.valueOf(map.get("openid"));
      unionId = String.valueOf(map.get("unionid"));

      log.info("获取的openID:" + openId);
      /*
       * 将openId保存到session中,当其他业务获取openId时,
       * 可先从session中获取openId.
       */
      request.getSession().setAttribute("openId", openId);
    } catch (JsonParseException e) {
      log.error("json解析失败:", e);
    } catch (JsonMappingException e) {
      log.error("map转换成json失败:", e);
    } catch (Exception e) {
      log.error("http获取openId请求失败:", e);
    }
    return openId;
  }

 在这里我们就能够拿到当前微信用户的openid 并在消息推送的时候进行用户 判断,来针对性的推送

posted @ 2019-05-16 19:45  诗错り亦染  阅读(2708)  评论(0编辑  收藏  举报