微信公众分享到朋友圈(Java+js)

直接上干货

1. 首先你需要有一个可以访问的外网IP(需要和域名绑定(这个绑定就是域名解析。)) 直接Java代码


package org.jeecg.modules.wx.controller;

import com.alibaba.fastjson.JSONObject;
import io.micrometer.core.instrument.util.StringUtils;
import io.swagger.annotations.Api;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.wx.util.HttpClientUtils;
import org.jeecg.modules.wx.util.SignUtil;
import org.jeecg.modules.zz.bstCompanyAccount.entity.BstCompanyAccount;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.util.*;

@Api(tags = "微信相关接口")
@RestController
@RequestMapping("/wx")
public class GetWx {

    public static String appid = "wx12****1";
    public static String appsecret = "445d***1349d1";
 

    @PostMapping("/Get_access_token")
    public Result<?> Get_access_token(String code) throws IOException {

        // 第二步:通过code换取网页授权access_token
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appsecret;
        JSONObject jsonObject = HttpClientUtils.doGet(url);


        String access_Token = jsonObject.getString("access_token");

        System.out.println(access_Token + "--------" + code);

        return Result.OK(access_Token);

    }


    @PostMapping("/getticket")
    public Result<?> getticket(String code) throws IOException {


        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appsecret;
        JSONObject jsonObject = HttpClientUtils.doGet(url);
        String ACCESS_TOKEN = jsonObject.getString("access_token");


        String url2 = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + ACCESS_TOKEN + "&type=jsapi";
        JSONObject jsonObject2 = HttpClientUtils.doGet(url2);


        return Result.OK(jsonObject2);

    }



	   //其实上面两个接口可以同时并到 下面这个接口中

    /**
     * 对string1进行sha1签名,得到signature:
     *
     *
     * @return
     * @throws IOException
     */
    @PostMapping("/getSha1")
    public Result<?> getSha1(String ticket, String url) throws Exception {
        //获取access_token
//        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + appsecret;
//        JSONObject jsonObject = HttpClientUtils.doGet(accessTokenUrl);
//        String ACCESS_TOKEN = jsonObject.getString("access_token");
//        //获取Ticket
//        String getTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + ACCESS_TOKEN + "&type=jsapi";
//        JSONObject jsonObject2 = HttpClientUtils.doGet(getTicketUrl);
//        String ticket = (String) jsonObject2.get("ticket");


        Map<String,String> paraMap = new HashMap<String,String>();

        paraMap.put("jsapi_ticket",ticket);
        paraMap.put("noncestr", create_nonce_str(16));
        paraMap.put("timestamp", create_timestamp());
        paraMap.put("url",url);

        String string1 = getSign(paraMap);
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(string1.getBytes("UTF-8"));

        paraMap.put("signature",byteToHex(crypt.digest()));

        System.out.println(paraMap.toString());
        return  Result.ok(paraMap);

    }


    



    public static String getSign(Map<String, String> params) {
        Map<String, String> sortMap = new TreeMap<String, String>();
        sortMap.putAll(params);
        // 以k1=v1&k2=v2...方式拼接参数
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, String> s : sortMap.entrySet()) {
            String k = s.getKey();
            String v = s.getValue();
            if (StringUtils.isBlank(v)) {// 过滤空值
                continue;
            }
            builder.append(k).append("=").append(v).append("&");
        }
        if (!sortMap.isEmpty()) {
            builder.deleteCharAt(builder.length() - 1);
        }
        return builder.toString();
    }

    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(int length) {

        String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random=new Random();
        StringBuffer sb=new StringBuffer();
        for(int i=0;i<length;i++){
            int number=random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();

    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

}



工具类

package org.jeecg.modules.wx.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jeecgframework.poi.util.MyX509TrustManager;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.URL;

public class HttpClientUtils {


    public static String httpsRequest(String requestUrl,String requestMethod,String outputStr){
        StringBuffer buffer=null;
        try{
            //创建SSLContext
            SSLContext sslContext= SSLContext.getInstance("SSL");
            TrustManager[] tm={new MyX509TrustManager()};
            //初始化
            sslContext.init(null, tm, new java.security.SecureRandom());;
            //获取SSLSocketFactory对象
            SSLSocketFactory ssf=sslContext.getSocketFactory();
            URL url=new URL(requestUrl);
            HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            //设置当前实例使用的SSLSoctetFactory
            conn.setSSLSocketFactory(ssf);
            conn.connect();
            //往服务器端写内容
            if(null!=outputStr){
                OutputStream os=conn.getOutputStream();
                os.write(outputStr.getBytes("utf-8"));
                os.close();
            }

            //读取服务器端返回的内容
            InputStream is=conn.getInputStream();
            InputStreamReader isr=new InputStreamReader(is,"utf-8");
            BufferedReader br=new BufferedReader(isr);
            buffer=new StringBuffer();
            String line=null;
            while((line=br.readLine())!=null){
                buffer.append(line);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return buffer.toString();
    }


    /**
     * 发起一个GET请求, 返回数据是以JSON格式返回
     * @param url
     * @return
     * @throws IOException
     */
    public static JSONObject doGet(String url) throws IOException {
        JSONObject jsonObject = null;
        CloseableHttpClient client = HttpClients.createDefault();


        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();

        if (entity != null) {
            String result = EntityUtils.toString(entity, "UTF-8");
            jsonObject = JSONObject.parseObject(result);
        }

        httpGet.releaseConnection();
        return jsonObject;
    }
}

2. 需要配置你 业务域名 JS接口安全域名 网页授权域名 IP白名单(千万要注意域名这里www.xxx.com 和 xxxx.com 是不一样的,本人就是在这里踩坑了)

在这里插入图片描述
在这里插入图片描述

3. 前端js 代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>
</head>

<body>

    <h1>分享</h1>

    <button class="btn">分享</button>

    <script src="./jweixin-1.6.0.js"></script>
    <script src="./jquery-3.2.1.js"></script>
    <script>

       
        const URL = "https://***.com/jeecg-boot/"
        const APPID = "wx***e81";
        const APPSECRET = "445****1";



        //获取 GetAccessToken
        function GetAccessToken() {
            return $.ajax({
                url: URL + "/wx/Get_access_token",
                type: "post",
                success(res) {

                }
            })
        }


        //获取 getTicket
        function getTicket(ACCESS_TOKEN) {
            return $.ajax({
                url: URL + "/wx/getticket?ACCESS_TOKEN=" + ACCESS_TOKEN,
                type: "post",
                success(res) {

                }
            })
        }
        function getSha1(ticket) {
            let urlParams = decodeURIComponent(location.href.split('#'));

            console.error(location.href.split('#'))
            return $.ajax({
                url: URL + `/wx/getSha1?url=${urlParams}&ticket=${ticket}`,
                method: "post",
                async: false,
                success(res) {
                    console.log(res)
                    let data = res.result






                }
            })
        }

        async function init() {
            let ACCESS_TOKEN = await GetAccessToken()
            console.log("GetAccessToken", ACCESS_TOKEN.result)

            let ticket = await getTicket(ACCESS_TOKEN.result)
            console.log("ticket", ticket.result.ticket)

            // ACCESS_TOKEN.result.ticket
            let signature = await getSha1(ticket.result.ticket)
            console.log("signature", signature.result)

            let data = signature.result



            wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: "wx1239d9ad87f2ae81", // 必填,公众号的唯一标识
                timestamp: data.timestamp, // 必填,生成签名的时间戳
                nonceStr: data.noncestr, // 必填,生成签名的随机串
                signature: data.signature,// 必填,签名
                jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ']
            })


            wx.ready(function(){ 
                wx.onMenuShareTimeline({
                    title: '这是标题', // 分享标题
                    link: 'https://***.com/home/newList/newInfo?id=1476123610963910657', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                    imgUrl: 'https://***.com:9000/jeecg-boot/temp/5_1629256461497.png', // 分享图标
                    success: function () {
                        // 设置成功
                    }
                })
            })


        }


        init()






      





    </script>
</body>

</html>

4. 至此你需要把你写的这个页面放到微信公众中进行分享就可以了

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值