(完整版)java+vue/h5微信分享自定义标题、缩略图、描述

前提:拥有已认证的公众号 + 备案域名

如果还没有已认证的公众号,可先用测试账号 微信测试账号地址:

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

一、登录微信公众号平台

1.在“开发者中心”查看是否拥用网页服务-分享接口的权限
2.在公众号平台JS接口安全域名添加对应域名,例:(www.xxx.com 切记不带http)
3.拿到公众号对应的appID、appsecret

二、JAVA提供接口

描述:接口主要返回appid(公众号id)、timestamp(生成签名的时间戳)、nonceStr(生成签名的随机字符串)、signature(签名)

流程:

        1.根据appID、appsecret获取access_token

        (access_token有效期2小时,频繁刷新会被禁用,建议存储到redis或其它缓存中)

        2.根据access_token获取jsapi_ticket

        (jsapi_ticket有效期2小时,频繁刷新会被禁用,建议存储到redis或其它缓存中)

        3.根据jsapi_ticket生成signature

注意:此接口需要接收url传参地址,地址是指在微信里的地址,所以必须动态传入,第三、四步均有前端传参步骤

代码:

controller层: 注意:如果不是@RestController,就在此方法上再加个@ResponseBody

    @Resource
    private WxSignService wxSignService;
    
    /**
     * 获取signature(微信分享)
     */
    @RequestMapping(value = "/getSignature", method = RequestMethod.POST)
    public Map<String, String>getSignature(@RequestBody UrlParam param) {
        return wxSignService.getSignature(param);
    }

UrlParam类:

package com.wealth.bean.model;

import java.io.Serializable;

/**
 * 通用参数
 */
public class UrlParam implements Serializable {

    private static final long serialVersionUID = 1L;
    
    private String url;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

wxSignService接口:

    /**
     * 获取signature(微信分享)
     */
    Map<String, String> getSignature(UrlParam param);

wxSignServiceImpl实现类:

1.把最上面的app_id和app_secret替换成自己的

2.缓存我用的是redis 可自行选择其它的缓存方式,redis工具类用自己项目中现成的就行

/**
 * <p>微信相关</p>
 * @date : 2021-10-08 15:26
 **/
@Service
public class WxSignServiceImpl implements WxSignService {

    private static final String app_id = "xxxx";

    private static final String app_secret = "xxxxxx";

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 获取signature(微信分享)
     */
    @Override
    public Map<String, String> getSignature(UrlParam param) {
        if(param == null || StringUtils.isBlank(param.getUrl())){
            return null;
        }
        //获取jsapi_ticket
        String jsapi_ticket = getJsapiTicket();
        if(StringUtils.isBlank(jsapi_ticket)) {
            return null;
        }
        return sign(jsapi_ticket, URLDecoder.decode(param.getUrl(), "UTF-8"));
    }

    //获取jsapi_ticket
    private String getJsapiTicket(){
        //redis中是否存在
        Object wx_access_token = redisUtil.get("wx_jsapi_ticket");
        if(wx_access_token != null) {
            return String.valueOf(wx_access_token);
        }

        String jsapi_ticket = "";

        String accessToken = getAccessToken();
        if(StringUtils.isBlank(accessToken)){
            return jsapi_ticket;
        }

        //定义请求信息
        StringBuilder url = new StringBuilder("https://api.weixin.qq.com/cgi-bin/ticket/getticket");
        url.append("?");
        url.append("type=jsapi");
        url.append("&");
        url.append("access_token=" + accessToken);

        //请求微信获取jsapi_ticket
        String sentGet = HttpUtil.sentGet(String.valueOf(url));

        if(StringUtils.isBlank(sentGet)){
            return jsapi_ticket;
        }

        JSONObject jsonObject = JSONObject.parseObject(sentGet);
        if(jsonObject.containsKey("ticket")){
            jsapi_ticket = jsonObject.getString("ticket");
            //存入redis 1.5小时(微信过期机制为2小时)
            redisUtil.set("wx_jsapi_ticket", jsapi_ticket, 60 * 90);
        }
        return jsapi_ticket;
    }

    //获取access_token
    private String getAccessToken(){
        //redis中是否存在
        Object wx_access_token = redisUtil.get("wx_access_token");
        if(wx_access_token != null) {
            return String.valueOf(wx_access_token);
        }

        //定义请求信息
        StringBuilder url = new StringBuilder("https://api.weixin.qq.com/cgi-bin/token");
        url.append("?");
        url.append("grant_type=client_credential");
        url.append("&");
        url.append("appid=" + app_id);
        url.append("&");
        url.append("secret=" + app_secret);

        String access_token = "";
        //请求微信获取access_token
        String sentGet = HttpUtil.sentGet(String.valueOf(url));

        if(StringUtils.isBlank(sentGet)){
            return access_token;
        }

        JSONObject jsonObject = JSONObject.parseObject(sentGet);
        if(jsonObject.containsKey("access_token")){
            access_token = jsonObject.getString("access_token");
            //存入redis 1.5小时(微信过期机制为2小时)
            redisUtil.set("wx_access_token", access_token, 60 * 90);
        }

        return access_token;
    }

    //获取签名signature
    public static Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<>();
        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;
        try{
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }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);
        ret.put("appid", app_id);

        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);
    }
}
HttpUtil类:
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

public class HttpUtil {
	
	/**
	 * get请求
	 * @return
	 * @param url
	 */
	public static String sentGet(String url) {
		try {
			HttpClient client = HttpClients.createDefault();
			//发送get请求
			HttpGet request = new HttpGet(url);
			HttpResponse response = client.execute(request);

			/**请求发送成功,并得到响应**/
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				/**读取服务器返回过来的json字符串数据**/
				String strResult = EntityUtils.toString(response.getEntity());
				return strResult;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}
}

三、Vue请求接口以及设置微信分享

1.执行命令

npm install weixin-js-sdk

2.在需要分享的页面添加导包

import wx from 'weixin-js-sdk';

3.在需要分享的页面添加代码

描述:

1.mounted为页面初始化加载内容

2.this.$httpServer.post为封装的post请求,此处使用自己项目中的post请求方式即可

    mounted() {
        this.initData();
    }
    //微信分享源码
    initData(){
      const data = {
        url: encodeURIComponent(location.href.split('#')[0])
      }
      this.$httpServer
        .post("/getSignature", data)
        .then((response) => {
          var result = response;
            wx.config({
            debug: true,//生产环境需要关闭debug模式
            appId: result.appid,
            timestamp: result.timestamp,//生成签名的时间戳
            nonceStr: result.nonceStr,//生成签名的随机字符串
            signature: result.signature,//签名
            jsApiList: [
                'onMenuShareTimeline','onMenuShareAppMessage'
            ]
            });
            const shareData = {
            "imgUrl": "",//这里填照片,必须是绝对路径 例http https开头可以直接访问
            "title": "这是标题",
            "desc": "这是内容",
            'link': "https://www.xxx.com/"//这里要填和你js安全填的那个一致,不过这里需要加http
            };
            wx.ready(function() {
                wx.onMenuShareTimeline(shareData);
                wx.onMenuShareAppMessage(shareData);
                wx.error(function(res) {
                    alert(res.errMsg);
                });
            });
        })
        .catch((e) => {

        });
    }

四、H5请求接口以及设置微信分享

1.在需要分享的页面引入js

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script src="/js/common/shareJssdk.js"></script>

2.shareJssdk.js内容

$(function(){
    var url = encodeURIComponent(location.href.split('#')[0]);
    //分享
    $.ajax({
        type : "get",
        url : "/getSignature",
        dataType : "json",
        data:{
            url:url
        },
        success : function(result){
            wxstart(result);
        },
        error:function(data){
            alert("连接失败!");
        }
    });

    function wxstart(result){
        wx.config({
            debug: true, // 正式环境关闭调试模式
            appId: result.appid, //公众号的唯一标识
            timestamp: result.timestamp, //生成签名的时间戳
            nonceStr: result.nonceStr, //生成签名的随机串
            signature: result.signature,//签名
            jsApiList: ["onMenuShareTimeline", "onMenuShareAppMessage"]
        });

        const shareData = {
            "imgUrl": "",//这里填照片,必须是绝对路径 例http https开头可以直接访问
            "title": "这是标题",
            "desc": "这是内容",
            'link': "https://www.xxx.com/"//这里要填和你js安全填的那个一致,不过这里需要加http
        };
        wx.ready(function() {
            wx.onMenuShareTimeline(shareData);
            wx.onMenuShareAppMessage(shareData);
            wx.error(function(res) {
               alert(res.errMsg);
            });
        });
    }
})

猜你喜欢

转载自blog.csdn.net/fuxingsheng1/article/details/120670765