(full version) java+vue/h5 WeChat share custom title, thumbnail, description

Prerequisite: have a certified official account + registered domain name

If you do not have a certified official account, you can first use the test account WeChat to test the address of the account:

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

1. Log in to the WeChat public account platform

1. In the "Developer Center", check whether you have the authority to use the web service-sharing interface
2. Add the corresponding domain name in the JS interface security domain name of the official account platform, for example: (www.xxx.com, remember not to include http)
3. Get the appID and appsecret corresponding to the official account

Two, JAVA provides interface

Description: The interface mainly returns appid (official account id), timestamp (time stamp of signature generation), nonceStr (random string of signature generation), signature (signature)

process:

        1. Obtain access_token according to appID and appsecret

        (access_token is valid for 2 hours, and frequent refreshing will be disabled. It is recommended to store it in redis or other caches)

        2. Obtain jsapi_ticket according to access_token

        (jsapi_ticket is valid for 2 hours, and frequent refreshing will be disabled. It is recommended to store it in redis or other caches)

        3. Generate signature according to jsapi_ticket

Note: This interface needs to receive the url parameter transfer address. The address refers to the address in WeChat, so it must be passed in dynamically. The third and fourth steps have front-end parameter transfer steps

code:

Controller layer: Note: If it is not @RestController, add @ResponseBody to this method

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

UrlParam class:

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 interface:

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

wxSignServiceImpl implementation class:

1. Replace the top app_id and app_secret with your own

2. I use redis for caching. You can choose other caching methods by yourself. The redis tools can be used in your own project.

/**
 * <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 class:
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 "";
	}
}

3. Vue request interface and set WeChat sharing

1. Execute the command

npm install weixin-js-sdk

2. Add the guide package on the page that needs to be shared

import wx from 'weixin-js-sdk';

3. Add code on the page that needs to be shared

describe:

1.mounted loads content for page initialization

2.this.$httpServer.post is an encapsulated post request, here you can use the post request method in your own project

    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) => {

        });
    }

4. H5 request interface and setting WeChat sharing

1. Introduce js to the page that needs to be shared

<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 content

$(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);
            });
        });
    }
})

Guess you like

Origin blog.csdn.net/fuxingsheng1/article/details/120670765