微信分享功能

最近做微信分享功能,第一次做,看了好久的官方文档,最终解决了,在这里记录一下。

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

需要在微信公众号后台进行设置:公众号设置-->功能设置-->JS接口安全域名。打开这个页面之后你会看到下面的提示。需要先下载这个文件并上传到指定域名的根目录(配置的域名+MP_verify_bjZ2nipw3mAGlvUF.txt必需要能访问才能保存成功)。

2.前台页面的开发

页面中引入<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>   
和以下代码;

$(function(){
    var busiParam={"busiData":{}};
    var title,desc,link,imgUrl;
    //对ajax的封装(自己用的框架,你们可以直接用ajax),去后台数据库查询分享的标题,图片路径,描述,link
    stc.rest.query("/AgentWechat/ShareData",{"busiParam":JSON.stringify(busiParam)},function(data){
        var wechatData=data.shareData[0];
        title=wechatData.wechat_title;
        desc=wechatData.wechat_description;
        link=location.href.split('#')[0];
        imgUrl=wechatData.wechat_imgurl;
            });
    var url= location.href.split('#')[0];
    var appId,timestamp,nonceStr,signature;
    var busiParam={"busiData":{"url":url}};
    //对ajax的封装,根据appId等数据,得到以下数据
    stc.rest.query("/AgentWechat/wechatShare",{"busiParam":JSON.stringify(busiParam)},function(data){
        appId=data.appid;// 必填,公众号的唯一标识  
        timestamp=data.timestamp; // 必填,生成签名的时间戳  
        nonceStr=data.noncestr;// 必填,生成签名的随机串  
        signature= data.signature;// 必填,签名  
        wx.config({    
            debug: false,  //是否开启调试模式 
            appId: appId,    
            timestamp: timestamp,    
            nonceStr: nonceStr,    
            signature: signature,    
            jsApiList: [    
                        'onMenuShareTimeline',    //调用的接口
                        'onMenuShareAppMessage'    
                        ]    
        });
    });
    wx.ready(function () {    
        var shareData = {    
                title: title,    
                desc: desc,    
                link: link,    
                imgUrl: imgUrl,    
                success: function (res) {    
                    console('已分享');    
                },    
                cancel: function (res) {    
                }    
        };    
        wx.onMenuShareAppMessage({    
            title: title,    
            desc: desc,    
            link: link,    
            imgUrl: imgUrl,    
            trigger: function (res) {    
                //  console('用户点击发送给朋友');    
            },    
            success: function (res) {    
                console('已分享');    
            },    
            cancel: function (res) {    
                //alert('已取消');    
            },    
            fail: function (res) {    
                console(JSON.stringify(res));    
            }    
        });    
        wx.onMenuShareTimeline(shareData);    
    });    
    wx.error(function (res) {    
        console("error: " + res.errMsg);    
    });    

});


3.后台开发,主要是根据appid,AppSecret等数据获取参数

@RequestMapping(value="/wechatShare",method=RequestMethod.GET)
    @ResponseBody
    public JSONObject wechatShare(HttpServletRequest request,HttpServletResponse response,
            Locale  locale) throws Exception{
        JSONObject json = new JSONObject();
        String[] params=new String[]{"url"};
        Map<String,Object> paramMap=RequestUtils.getParamMap(request, params);
        logger.info("~~~~~url~~~~~::"+paramMap.get("url").toString().replace("&amp;", "&"));
        // 微信appid  
        String appid = bank_config.getString("WECHAY_APPID");
        logger.info("~~~~~appid~~~~~::"+appid);
        // 微信secret   
        String secret = bank_config.getString("WECHAT_AppSecret");
        logger.info("~~~~~AppSecret~~~~~::"+secret);
        // 初始化access_token  
        String access_token = "";  
        //  获取URL 这里的URL指的是需要分享的那个页面地址,建议这里不要写成固定地址,而是获取当前地址.  
        String url = paramMap.get("url").toString().replace("&amp;", "&");

        // 创建通过Api获取Token的链接与参数  
        String requestTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";  
        requestTokenUrl = requestTokenUrl.replace("APPID", appid);  
        requestTokenUrl = requestTokenUrl.replace("SECRET", secret);  
        logger.info("~~~~~requestTokenUrl~~~~~::"+requestTokenUrl);
        JSONObject jsonObject2 = CommonUtil.httpsRequestResult(appid, secret);
        logger.info("~~~~~jsonObject2~~~~~::"+jsonObject2);
        if(jsonObject2!=null){
            // 创建日期赋值为当前日期  
            long  createDate =new Date().getTime()/1000;
            // 获取Token值  
            access_token = jsonObject2.getString("access_token");
            logger.info("~~~~~access_token~~~~~::"+access_token);
            // 获取Token有效期值  
            String expires_in = jsonObject2.getString("expires_in");
            
        }
             //获取ACCESS_TOKEN
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";  
        requestUrl = requestUrl.replace("ACCESS_TOKEN", access_token);  
        logger.info("~~~~~requestUrl~~~~~::"+requestUrl);
        // 获取凭证  
        JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);  
        logger.info("~~~~~获取凭证~~~~~::"+jsonObject);
        if(jsonObject!=null){  

            try { 

扫描二维码关注公众号,回复: 2147133 查看本文章

           //jsapi_ticket是公众号用于调用微信JS接口的临时票据。

                String ticket = jsonObject.getString("ticket");  
                logger.info("~~~~~获取凭证jsapi_ticket~~~~~::"+ticket);
                Sign sign = new Sign();
                Map<String, String> MapRestult = sign.sign(ticket, url);
                json.put("noncestr", MapRestult.get("nonceStr"));
                logger.info("~~~~~noncestr~~~~~::"+MapRestult.get("nonceStr"));
                json.put("timestamp", MapRestult.get("timestamp"));
                logger.info("~~~~~timestamp~~~~~::"+MapRestult.get("timestamp"));
                json.put("jsapi_ticket", MapRestult.get("jsapi_ticket"));
                logger.info("~~~~~jsapi_ticket~~~~~::"+MapRestult.get("jsapi_ticket"));
                json.put("signature", MapRestult.get("signature"));
                logger.info("~~~~~signature~~~~~::"+MapRestult.get("signature"));
                json.put("url", MapRestult.get("url"));
                logger.info("~~~~~url~~~~~::"+MapRestult.get("url"));
                json.put("appid",bank_config.getString("WECHAY_APPID"));
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }
        return json;  
    }
   
在这里数据返回正常,就可以正常分享了,下面上一下我做测分享成功的截图,其实不难,调式代码的时候仔细看日志,就行

以下是上面用到的工具类 CommonUtil,

package com.xxx.prm.util;xxx
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 javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xxx.prm.cdsp.userCenter.localreq.bean.MyX509TrustManager;



/**
* 类名: CommonUtil </br>
* 描述: 通用工具类 </br>
* 开发人员: tomcat </br>
* 创建时间:  2018-06-30 </br>
* 发布版本:V1.0  </br>
 */
public class CommonUtil {
    private static Logger log = LoggerFactory.getLogger(CommonUtil.class);

    /**
     * 发送https请求
     *
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式(GET、POST)
     * @param outputStr 提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        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 conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            conn.setRequestMethod(requestMethod);

            // 当outputStr不为null时向输出流写数据
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 从输入流读取返回内容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error("连接超时:{}", ce);
        } catch (Exception e) {
            log.error("https请求异常:{}", e);
        }
        return jsonObject;
    }
    /**
     * 获取接口访问凭证
     *
     * @param appid 凭证
     * @param appsecret 密钥
     * @return
     */
    public static JSONObject httpsRequestResult(String appid, String appsecret) {
         // 凭证获取(GET)
        String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
        String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
        // 发起GET请求获取凭证
        log.info("~~~~~~~~~token_url~~~~~~~~~"+token_url);
        JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
        return jsonObject;
    }
}

package com.sitech.prm.cdsp.userCenter.localreq.bean;
/** 
 * @author 作者 E-mail: 
 * @version 创建时间:2018年5月30日 下午3:13:18 
 * 类说明 
 */

工具类Sign

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Sign {
    private Log logger = LogFactory.getLog(Sign.class);
    public Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";
        // 注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
                + "&timestamp=" + timestamp + "&url=" + url;
        logger.debug("[string1] = " + string1);
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
            logger.debug("[signature] = " + signature);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        logger.debug("[ret] = " + ret);
       return ret;
    }
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
    /**
     * 用SHA1算法生成安全签名
     * 
     * @param token
     *            票据
     * @param timestamp
     *            时间戳
     * @param nonce
     *            随机字符串
     * @param encrypt
     *            密文
     * @return 安全签名
     * @throws NoSuchAlgorithmException
     * @throws AesException
     */
    public String getSHA1(String token, String timestamp, String nonce)
            throws NoSuchAlgorithmException {
        String[] array = new String[] { token, timestamp, nonce };
        StringBuffer sb = new StringBuffer();
        // 字符串排序
        Arrays.sort(array);
        for (int i = 0; i < 3; i++) {
            sb.append(array[i]);
        }
        String str = sb.toString();
        // SHA1签名生成
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(str.getBytes());
        byte[] digest = md.digest();
        StringBuffer hexstr = new StringBuffer();
        String shaHex = "";
        for (int i = 0; i < digest.length; i++) {
            shaHex = Integer.toHexString(digest[i] & 0xFF);
            if (shaHex.length() < 2) {
                hexstr.append(0);
            }
            hexstr.append(shaHex);
        }
        return hexstr.toString();
    }

}

工具类MyX509TrustManager 

package com.xx.prm.cdsp.userCenter.localreq.bean;
/** 
 * @author 作者 E-mail: 
 * @version 创建时间:2018年5月30日 下午3:20:11 
 * 类说明 
 */
import java.security.cert.CertificateException;  
import java.security.cert.X509Certificate;  
  
import javax.net.ssl.X509TrustManager;  
  
public class MyX509TrustManager implements X509TrustManager {  
    public void checkClientTrusted(X509Certificate[] chain, String authType)  
            throws CertificateException  
          {  
          }  
  
          public void checkServerTrusted(X509Certificate[] chain, String authType)  
            throws CertificateException  
          {  
          }  
  
          public X509Certificate[] getAcceptedIssuers()  
          {  
            return null;  
          }  
}  



猜你喜欢

转载自blog.csdn.net/junge1545/article/details/80921643