zoukankan      html  css  js  c++  java
  • Java与微信相关

    微信登录并不复杂,其核心逻辑是每个用户对应每个应用都有唯一openId,根据openId进行用户的校验和处理。


    //初始化方法

    public static String getCodeUrl(String username) throws ClientProtocolException, IOException {
    String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";

    url = url.replace("APPID", appid);
    url = url.replace("STATE", "1");
    url = url.replace("REDIRECT_URI", URLEncoder.encode(redictUri, "utf-8"));
    //System.out.println("----------微信取用户url="+url+",redictUri="+redictUri);
    return url;
    }

    访问该url执行初始化,在微信上设置回调函数,将秘钥文件放在目录结构下,就可以回调了。(微信公众号必须是服务号,订阅号不支持)

    //微信获取openId方法 

    //获取access_token,openId
    public static Map<String,Object> getOpendId(String code) {

    String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=AppId&secret=AppSecret&code=CODE&grant_type=authorization_code";
    url = url.replace("AppId", appid).replace("AppSecret", appsecret).replace("CODE", code);

    Map<String, Object> headersParams = new HashMap<>();
    //获取access_token,openId等
    String result = HttpRequestUtil.sendPost(url, headersParams,"UTF-8");
    System.out.println("获取accessToken和openId:url="+url+",返回结果:"+result);
    JSONObject obj = JSONObject.parseObject(result);

    //把返回参数(4个)返回
    JSONObject resultObj = new JSONObject();
    headersParams.put("openid",obj.getString("openid"));
    headersParams.put("accessToken",obj.getString("access_token"));
    headersParams.put("appid",appid);
    headersParams.put("appname","应用名称");
    return headersParams;
    }
    //获取用户信息
    public static JSONObject getUserInfo(String openid,String accessToken){
    //拉取用户信息
    String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
    url = url.replace("ACCESS_TOKEN",accessToken);
    url = url.replace("OPENID",openid);
    String result = HttpRequestUtil.sendGet(url, "");
    System.out.println("拉取用户信息:url="+url+",返回结果:"+result);
    JSONObject obj = JSONObject.parseObject(result);
    return obj;
    }


    -------------------------------------------微信分享相关-----------------------------------
    微信分享相对稍微复杂,主要是对签名的计算,首先需要引入微信的js文件,然后根据appid,随机数,时间戳和url进行加密运算,必须匹配才可分享
    前端引入
    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

    前端需要引入的自定义js文件需要引入的内容:
    function wx_ready_fenxiang(title, desc, imgUrl,url){
    $.post("/weixin/share",{"url":url},function(result){
    var appid,timestamp,nonceStr,signature;
    appid = result.appId;
    timestamp = result.timestamp;
    nonceStr = result.nonceStr;
    signature = result.signature;
    wx.config({
    debug: false,//debug模式会打印日志,微信端会弹框
    appId: appid,
    timestamp:timestamp,
    nonceStr: nonceStr,
    signature: signature,
    jsApiList: [
    'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone'
    ]
    });
    _wx(title, desc, imgUrl, 'link',url);

    },"json")
    }

    function _wx(title, desc, imgUrl, type,url){
    wx.ready(function() {
    //朋友圈
    wx.onMenuShareTimeline({
    title: title, // 分享标题
    link: url, // 分享链接
    imgUrl: imgUrl, // 分享图标
    success: function() {
    // alert('谢谢分享');
    // 用户确认分享后执行的回调函数
    },
    cancel: function() {
    // alert('谢谢分享');
    // 用户取消分享后执行的回调函数
    }
    });

    //微信好友
    wx.onMenuShareAppMessage({
    title: title, // 分享标题
    desc: desc, // 分享描述
    link: url, // 分享链接
    imgUrl: imgUrl, // 分享图标
    type: type, // 分享类型,music、video或link,不填默认为link
    // dataUrl: dataurl, // 如果type是music或video,则要提供数据链接,默认为空
    success: function() {
    // alert('谢谢分享');
    },
    cancel: function() {
    // alert('分享失败');
    // 用户取消分享后执行的回调函数
    }
    });

    //qq好友
    wx.onMenuShareQQ({
    title: title, // 分享标题
    desc: desc, // 分享描述
    link: url, // 分享链接
    imgUrl: imgUrl, // 分享图标
    success: function() {
    // 用户确认分享后执行的回调函数
    },
    cancel: function() {
    // 用户取消分享后执行的回调函数
    }
    });
    //腾讯微博
    wx.onMenuShareWeibo({
    title: title, // 分享标题
    desc: desc, // 分享描述
    link: url, // 分享链接
    imgUrl: imgUrl, // 分享图标
    success: function() {
    // 用户确认分享后执行的回调函数
    },
    cancel: function() {
    // 用户取消分享后执行的回调函数
    }
    });
    //qq空间
    wx.onMenuShareQZone({
    title: title, // 分享标题
    desc: desc, // 分享描述
    link: url, // 分享链接
    imgUrl: imgUrl, // 分享图标
    success: function() {
    // 用户确认分享后执行的回调函数
    },
    cancel: function() {
    // 用户取消分享后执行的回调函数
    }
    });
    // alert("wx ready 哈哈哈");
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

    });
    wx.error(function(res) {
    // alert(res + "wx-error");
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
    });
    }

    //调用方法
    wx_ready_fenxiang("名称", "详情", '图片url',location.href)
    JAVA后台部分:
    //获取分享的token
    public static String getShareAccessToken() throws IOException {

    String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appid+"&secret="+appsecret;
    Map<String, String> headersParams = new HashMap<>();
    String resultStr = HttpUtils.get(url,headersParams);
    // sendGet:用get方法获取数据 ,具体请参考之间的关于微信的文章 http://www.cnblogs.com/jiduoduo/p/5749363.html
    System.out.println("------------微信分享share的accessToken:url="+url+",返回结果:"+resultStr);
    //返回结果
    JSONObject obj = JSONObject.parseObject(resultStr);
    String access_token = obj.getString("access_token");
    return access_token;

    }


    //获取jsapi_ticket
    public static String getJsapiTicket(String accessToken) throws IOException {
    String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + accessToken;

    Map<String, String> headersParams = new HashMap<>();
    String resultStr = HttpUtils.get(url, headersParams);

    System.out.println("Redpack.WeixinUtils.getJsapiTicket获取JsapiTicket:url="+url+",返回结果:"+resultStr);
    //返回结果
    JSONObject obj = JSONObject.parseObject(resultStr);
    String ticket = obj.getString("ticket");
    return ticket;

    }

    //生成签名
    public static String getSignature(String jsapi_ticket, String noncestr, Long timeStamp, String url) {
    String string1 = "jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=URL";
    string1 = string1.replace("JSAPI_TICKET", jsapi_ticket);
    string1 = string1.replace("NONCESTR", noncestr);
    string1 = string1.replace("TIMESTAMP", timeStamp.toString());
    string1 = string1.replace("URL",url);
    String signature= DigestUtils.shaHex(string1);
    System.out.println("------生成签名string1="+string1+",结果signature="+signature);
    return signature;

    }
    Controller层,就是前台js引用的接口:
    @RequestMapping("/share")
    @ResponseBody
    public JSONObject share(HttpServletRequest request,@RequestParam String url) throws IOException {
    System.out.println("----------------------------微信分享url="+url);
    //url = url.replace("sendfriend","redpack/get");

    //时间戳(10位)
    Long timeStamp = System.currentTimeMillis()/1000;
    //随机数(可以任意指定)
    String noncestr="12345678";
    //获得jsapi_ticket

    //1.拿到accessToken
    String accessToken = WeixinUtils.getShareAccessToken();
        //此处accessToken过期时间为2个小时,第一次取可以存入redis,两个小时之内有效,如果accessToken尚在有效期内,再次取是会报错的。
          String jsapi_ticket = WeixinUtils.getJsapiTicket(accessToken);
    //获得签名
    String signature = WeixinUtils.getSignature(jsapi_ticket,noncestr,timeStamp,url);
    //Map<String,Object> param = WeixinUtils.getOpendId(code);


    JSONObject obj = new JSONObject();
    obj.put("appId",PropertyConstants.getValue("com.tencent.weixin.appid"));
    obj.put("timestamp",timeStamp);
    obj.put("nonceStr",noncestr);
    obj.put("signature",signature);
    obj.put("jsapi_ticket",jsapi_ticket);
    obj.put("url",url);
    return obj;
    }
    注意:
    1.时间戳必须是10位,13位的时间戳是无法取到正确的值的。
    2.随机数可以任意指定,不需要太复杂,我就设的12345678
    3.可否分享就是看签名校验是否正确,可以在微信公众号开发者工具里的网址进行计算,匹配则可分享。
    4.分享标题和内容是有敏感词的,比如红包,现金等,具体请查阅微信官方的说明。
    5.分享只能分享当前页,不能分享其他页。



  • 相关阅读:
    JUnit中的设计模式:组合模式 Composite
    Activity在屏幕显示的方向切换
    Jenkins插件之有用
    Jenkins插件之Dashboard和wall display
    python技巧32[常用技巧集]
    Jenkins插件之构建与MSBuild
    Jenkins插件之Publish Over SSH/CIFS/FTP
    使用devenv/MSBuild在命令行编译单个project
    Jenkins中执行batch和Python
    python翻译[排序高级]
  • 原文地址:https://www.cnblogs.com/rock-turf/p/9460630.html
Copyright © 2011-2022 走看看