欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java微信分享接口开发详解

程序员文章站 2024-02-24 15:56:34
本文实例为大家分享了java微信分享接口开发的具体代码,供大家参考,具体内容如下 java微信分享,步骤是 1、根据当前的url,获取signature,noncest...

本文实例为大家分享了java微信分享接口开发的具体代码,供大家参考,具体内容如下

java微信分享,步骤是

1、根据当前的url,获取signature,noncestr,timestamp 和appid。
2、通过signature,noncestr,timestamp 和appid来配置微信 wx.config。
3、通过wx.ready实现微信分享功能。

1、html端

引入微信js-sdk.

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
//分享核心js代码
$(document).ready(function () {
  //通过ajax,在页面加载的时候获取微信分享接口signature,noncestr,timestamp 和appid
  $.ajax({
    type: "post",
    url: "/weixin/share",
    datatype: "json",
    data:"url="+window.location.href,
    success: function (data) {
      wx.config({
        debug: false,
        appid: data.appid,
        timestamp: data.timestamp,
        noncestr: data.noncestr,
        signature: data.signature,
        jsapilist: ['onmenushareappmessage', 'onmenusharetimeline', 'hideallnonbasemenuitem', 'showmenuitems']
        // 功能列表,我们要使用js-sdk的什么功能
      });
      wx.ready(function () {
        // 获取“分享给朋友”按钮点击状态及自定义分享内容接口
        wx.onmenushareappmessage({
          title: "分享自定义标题", // 分享标题
          desc: "分享自定义描述", // 分享描述
          link: "http://localhost/weixin/share?openid=1",//分享点击之后的链接
          imgurl:'/images/photo/1.jpg', // 分享图标
          type: 'link', // 分享类型,music、video或link,不填默认为link
          success: function () {
            //成功之后的回调
          }
        });
        wx.hideallnonbasemenuitem();
        wx.showmenuitems({
          menulist: ['menuitem:share:appmessage', 'menuitem:share:timeline'] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮,所有menu项见附录3
        });
        wx.onmenusharetimeline({
          title: "分享自定义标题", // 分享标题
          desc: "分享自定义描述", // 分享描述
          link: "http://localhost/weixin/share?openid=1",//分享点击之后的链接
          imgurl:'/images/photo/1.jpg', // 分享图标
          type: 'link', // 分享类型,music、video或link,不填默认为link
          success: function () {
            //成功之后的回调
          }
          cancel: function () {
            // 用户取消分享后执行的回调函数
          }
        });
      });
      wx.error(function (res) {
        //打印错误消息。及把 debug:false,设置为debug:ture就可以直接在网页上看到弹出的错误提示
      });
    }
  })
});

2、java代码,获取 signature,noncestr,timestamp 和appid

@requestmapping(value = "/share", method = requestmethod.post)
  @responsebody
  public map<string, object> share(httpservletrequest request) {
    string urltemp = "http://" + request.getservername() + request.getcontextpath();
    string urlpath = "http://" + request.getservername();
    string appurl = request.getparameter("url");
    if (request.getparameter("code") != null) {
      appurl += "&code=" + request.getparameter("code");
    }
    if (request.getparameter("state") != null) {
      appurl += "&state=" + request.getparameter("state");
    }
    return wxconfigutil.getsignature(appurl, contentvalues.appid, contentvalues.secret, urltemp, urlpath);
  }

工具类我就把整个贴上来了,其中有些方法是没有用到的。

getsignature()整个方法是微信分享中的核心方法,用来获取signature,noncestr,timestamp 和appid这几个核心参数。

package com.blog.common.util;

import com.alibaba.fastjson.jsonobject;
import com.blog.common.model.token;

import javax.net.ssl.httpsurlconnection;
import javax.net.ssl.sslcontext;
import javax.net.ssl.sslsocketfactory;
import javax.net.ssl.trustmanager;
import java.io.bufferedreader;
import java.io.inputstream;
import java.io.inputstreamreader;
import java.io.outputstream;
import java.net.connectexception;
import java.net.url;
import java.security.messagedigest;
import java.security.nosuchalgorithmexception;
import java.util.arrays;
import java.util.hashmap;
import java.util.map;


/**
 * 公众平台通用接口工具类
 *
 * @author james
 * @date 2015-02-27
 */
public class wxconfigutil {
  // 获取access_token的接口地址(get) 限2000(次/天)
  public final static string access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=appsecret";
  // 获取jsapi_ticket的接口地址(get) 限2000(次/天)
  public final static string jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=access_token&type=jsapi";
  // 缓存添加的时间
  public static string cacheaddtime = null;
  // token,ticket缓存
  public static map<string, token> token_ticket_cache = new hashmap<string, token>();
  // token对应的key
  private static final string token = "token";
  // ticket对应的key
  private static final string ticket = "ticket";

  /**
   * 外部获取签名入口类
   *
   * @param appurl  应用的url
   * @return
   */
  public static map<string, object> getsignature(string appurl, string appid, string secret, string url, string urlpath) {
    // 生成签名的随机串
    string noncestr = randomutil.getstringrandom(4);
    if (appurl == null || "".equals(appurl)) {
      return null;
    }
    string signature = null;
    token accesstocken = gettoken(appid, secret, system.currenttimemillis() / 1000);
    token accessticket = getticket(accesstocken.gettoken(), system.currenttimemillis() / 1000);
    signature = signature(accessticket.getticket(), cacheaddtime, noncestr, appurl);
    system.out.println("-=-=-=-=-=-=-=-=appurl:" + appurl);
    system.out.println("-=-=-=-=-=-=-=-=token:" + accesstocken.gettoken());
    system.out.println("-=-=-=-=-=-=-=-=ticket:" + accessticket.getticket());
    system.out.println("-=-=-=-=-=-=-=-=signature:" + signature);
    system.out.println("-=-=-=-=-=-=-=-=timestamp:" + cacheaddtime);
    map<string, object> map = new hashmap<>();
    map.put("appid", appid);
    map.put("timestamp", cacheaddtime);
    map.put("noncestr", noncestr);
    map.put("appurl", appurl);
    map.put("signature", signature);
    map.put("url", url);
    map.put("urlpath", urlpath);
    return map;
  }

  /**
   * 获得token
   *
   * @return
   */
  public static string gettoken(string appid, string secret) {
    token accesstocken = gettoken(appid, secret, system.currenttimemillis() / 1000);
    return accesstocken.gettoken();
  }

  /**
   * 签名
   *
   * @param timestamp
   * @return
   */
  private static string signature(string jsapi_ticket, string timestamp, string noncestr, string url) {
    jsapi_ticket = "jsapi_ticket=" + jsapi_ticket;
    timestamp = "timestamp=" + timestamp;
    noncestr = "noncestr=" + noncestr;
    url = "url=" + url;
    string[] arr = new string[]{jsapi_ticket, noncestr, timestamp, url};
    // 将token、timestamp、nonce,url参数进行字典序排序
    arrays.sort(arr);
    stringbuilder content = new stringbuilder();
    for (int i = 0; i < arr.length; i++) {
      content.append(arr[i]);
      if (i != arr.length - 1) {
        content.append("&");
      }
    }
    messagedigest md = null;
    string tmpstr = null;

    try {
      md = messagedigest.getinstance("sha-1");
      // 将三个参数字符串拼接成一个字符串进行sha1加密
      byte[] digest = md.digest(content.tostring().getbytes());
      tmpstr = bytetostr(digest);
    } catch (nosuchalgorithmexception e) {
      e.printstacktrace();
    }

    content = null;
    return tmpstr;
  }

  /**
   * 获取access_token
   *
   * @param appid   凭证
   * @param appsecret 密钥
   * @return
   */
  public static token gettoken(string appid, string appsecret, long currenttime) {
    token tockenticketcache = gettokenticket(token);
    token token = null;

    if (tockenticketcache != null && (currenttime - tockenticketcache.getaddtime() <= tockenticketcache.getexpiresin())) {// 缓存存在并且没过期
      system.out.println("==========缓存中token已获取时长为:" + (currenttime - tockenticketcache.getaddtime()) + "毫秒,可以重新使用");
      return tockenticketcache;
    }
    system.out.println("==========缓存中token不存在或已过期===============");
    string requesturl = access_token_url.replace("appid", appid).replace("appsecret", appsecret);
    jsonobject jsonobject = httprequest(requesturl, "get", null);
    // 如果请求成功
    if (null != jsonobject) {
      token = new token();
      token.settoken(jsonobject.getstring("access_token"));
      token.setexpiresin(jsonobject.getintvalue("expires_in") / 2);// 正常过期时间是7200秒,此处设置3600秒读取一次
      system.out.println("==========tocket缓存过期时间为:" + token.getexpiresin() + "毫秒");
      token.setaddtime(currenttime);
      updatetoken(token, token);
    }
    return token;
  }

  /**
   * 获取ticket
   *
   * @param token
   * @return
   */
  private static token getticket(string token, long currenttime) {
    token tockenticketcache = gettokenticket(ticket);
    token token = null;
    if (tockenticketcache != null && (currenttime - tockenticketcache.getaddtime() <= tockenticketcache.getexpiresin())) {// 缓存中有ticket
      system.out.println("==========缓存中ticket已获取时长为:" + (currenttime - tockenticketcache.getaddtime()) + "毫秒,可以重新使用");
      return tockenticketcache;
    }
    system.out.println("==========缓存中ticket不存在或已过期===============");
    string requesturl = jsapi_ticket_url.replace("access_token", token);
    jsonobject jsonobject = httprequest(requesturl, "get", null);
    // 如果请求成功
    if (null != jsonobject) {
      token = new token();
      token.setticket(jsonobject.getstring("ticket"));
      token.setexpiresin(jsonobject.getintvalue("expires_in") / 2);// 正常过期时间是7200秒,此处设置3600秒读取一次
      system.out.println("==========ticket缓存过期时间为:" + token.getexpiresin() + "毫秒");
      token.setaddtime(currenttime);
      updatetoken(ticket, token);
    }
    return token;
  }

  /**
   * 发起https请求并获取结果
   *
   * @param requesturl  请求地址
   * @param requestmethod 请求方式(get、post)
   * @param outputstr   提交的数据
   * @return jsonobject(通过jsonobject.get(key)的方式获取json对象的属性值)
   */
  private static jsonobject httprequest(string requesturl, string requestmethod, string outputstr) {
    jsonobject jsonobject = null;
    stringbuffer buffer = new stringbuffer();
    try {
      // 创建sslcontext对象,并使用我们指定的信任管理器初始化
      trustmanager[] tm = {new myx509trustmanager()};
      sslcontext sslcontext = sslcontext.getinstance("ssl", "sunjsse");
      sslcontext.init(null, tm, new java.security.securerandom());
      // 从上述sslcontext对象中得到sslsocketfactory对象
      sslsocketfactory ssf = sslcontext.getsocketfactory();

      url url = new url(requesturl);
      httpsurlconnection httpurlconn = (httpsurlconnection) url.openconnection();
      httpurlconn.setsslsocketfactory(ssf);

      httpurlconn.setdooutput(true);
      httpurlconn.setdoinput(true);
      httpurlconn.setusecaches(false);
      // 设置请求方式(get/post)
      httpurlconn.setrequestmethod(requestmethod);

      if ("get".equalsignorecase(requestmethod))
        httpurlconn.connect();

      // 当有数据需要提交时
      if (null != outputstr) {
        outputstream outputstream = httpurlconn.getoutputstream();
        // 注意编码格式,防止中文乱码
        outputstream.write(outputstr.getbytes("utf-8"));
        outputstream.close();
      }

      // 将返回的输入流转换成字符串
      inputstream inputstream = httpurlconn.getinputstream();
      inputstreamreader inputstreamreader = new inputstreamreader(inputstream, "utf-8");
      bufferedreader bufferedreader = new bufferedreader(inputstreamreader);

      string str = null;
      while ((str = bufferedreader.readline()) != null) {
        buffer.append(str);
      }
      bufferedreader.close();
      inputstreamreader.close();
      // 释放资源
      inputstream.close();
      inputstream = null;
      httpurlconn.disconnect();
      jsonobject = jsonobject.parseobject(buffer.tostring());
      // jsonobject = jsonobject.fromobject(buffer.tostring());
    } catch (connectexception ce) {
      system.out.println("weixin server connection timed out.");
    } catch (exception e) {
      system.out.println("https request error:{}" + e.getmessage());
    }
    return jsonobject;
  }

  /**
   * 将字节数组转换为十六进制字符串
   *
   * @param bytearray
   * @return
   */
  private static string bytetostr(byte[] bytearray) {
    string strdigest = "";
    for (int i = 0; i < bytearray.length; i++) {
      strdigest += bytetohexstr(bytearray[i]);
    }
    return strdigest;
  }

  /**
   * 将字节转换为十六进制字符串
   *
   * @param mbyte
   * @return
   */
  private static string bytetohexstr(byte mbyte) {

    char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    char[] temparr = new char[2];
    temparr[0] = digit[(mbyte >>> 4) & 0x0f];
    temparr[1] = digit[mbyte & 0x0f];

    string s = new string(temparr);
    return s;
  }

  /**
   * 从缓存中读取token或者ticket
   *
   * @return
   */
  private static token gettokenticket(string key) {
    if (token_ticket_cache != null && token_ticket_cache.get(key) != null) {
      system.out.println("==========从缓存中获取到了" + key + "成功===============");
      return token_ticket_cache.get(key);
    }
    return null;
  }

  /**
   * 更新缓存中token或者ticket
   *
   * @return
   */
  private static void updatetoken(string key, token accesstocken) {
    if (token_ticket_cache != null && token_ticket_cache.get(key) != null) {
      token_ticket_cache.remove(key);
      system.out.println("==========从缓存中删除" + key + "成功===============");
    }
    token_ticket_cache.put(key, accesstocken);
    cacheaddtime = string.valueof(accesstocken.getaddtime());// 更新缓存修改的时间
    system.out.println("==========更新缓存中" + key + "成功===============");
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。