H5分享到微信朋友圈与好友实现思路_java myx509trustmanager maven_会飞的大鹌鹑的博客-程序员宅基地

技术标签: java  javascript  

H5分享到微信朋友圈与好友实现思路

本文只是实现思路,代码写的比较水,仅供参考

使用springBoot 返回ModelAndView 实现

HTML使用Thymeleaf

1.添加MyX509TrustManager类(从微信提供的包中导入或自己创建都可以)

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;  
          }  
}  

2.maven添加JSON依赖

<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib-ext-spring</artifactId>
    <version>1.0.2</version>
</dependency>

3.创建WeixinUtil类

需要注意:

1.由于微信限制access_token获取次数,access_token需要缓存,建议由程序统一获取和刷新access_token,其他业务逻辑所使用的access_token均来自于该统一获取的access_token,不应该各自去刷新,目前access_token的有效期为7200秒,此处示例代码不做处理,实际开发请自行处理

2.微信appId与secret请根据项目要求自行存放到配置文件或Config类

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

public class WeixinUtil {
    
    /**
    * 方法名:httpRequest</br>
    * 详述:发送http请求</br>
    * @param requestUrl
    * @param requestMethod
    * @param outputStr
    * @return 说明返回值含义
    * @throws 说明发生此异常的条件
     */
    public static JSONObject httpRequest(String requestUrl,String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            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);
            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.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            ce.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    /**
    * 方法名:getWxConfig</br>
    * 详述:获取微信的配置信息 </br>
    * @param request
    * @return 说明返回值含义
    * @throws 说明发生此异常的条件
     */
    public static Map<String, Object> getWxConfig(HttpServletRequest request) {
        Map<String, Object> ret = new HashMap<String, Object>();
      
        //此处appid与secret应该放到配置文件中,测试实现仅供参考
        String appId = "wxappId "; // 必填,公众号的唯一标识
        String secret = "wxsecret";

        //url
        String requestUrl = request.getRequestURL().toString();
        
        String access_token = "";
        String jsapi_ticket = "";
        String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳
        String nonceStr = UUID.randomUUID().toString(); // 必填,生成签名的随机串
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId + "&secret=" + secret;
        JSONObject json = WeixinUtil.httpRequest(url, "GET", null);
        if (json != null) {
            //要注意,由于微信限制access_token获取次数,access_token需要缓存,
            //建议由程序统一获取和刷新access_token,其他业务逻辑所使用的access_token均来自于该统一获取的access_token,不应该各自去刷新,
            //目前access_token的有效期为7200秒,此处示例代码不做处理,实际开发请自行处理
            access_token = json.getString("access_token");
            url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token + "&type=jsapi";
            json = WeixinUtil.httpRequest(url, "GET", null);
            if (json != null) {
                jsapi_ticket = json.getString("ticket");
            }
        }
        String signature = "";
        // 注意这里参数名必须全部小写,且必须有序
        String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "&timestamp=" + timestamp + "&url=" + requestUrl;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(sign.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        ret.put("appId", appId);
        ret.put("timestamp", timestamp);
        ret.put("nonceStr", nonceStr);
        ret.put("signature", signature);
        return ret;
    }

    /**
    * 方法名:byteToHex</br>
    * 详述:字符串加密辅助方法 </br>
    * 开发人员:souvc  </br>
    * 创建时间:2016-1-5  </br>
    * @param hash
    * @return 说明返回值含义
    * @throws 说明发生此异常的条件
     */
    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;
    }
}

4.测试controller

其中title/desc等字段亦可由前端通过js代入

@Controller
public class TestController {

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ModelAndView test(HttpServletRequest request){
        ModelAndView model = new ModelAndView();
        Map<String,Object> ret = new HashMap<String,Object>();
        //获取必要参数信息
        ret= WeixinUtil.getWxConfig(request);
        根据业务编写业务代码
        //......

        //加入需要展示的标题title
        ret.put("title", "xxx");
        //加入需要展示的详情desc
        ret.put("desc", "xxx");
        //获取URL
        String url = request.getRequestURL().toString();
        //加入需要展示的详情URL
        ret.put("link", url);
        model.addObject("wxConfig",ret);
        //返回页面
        model.setViewName("test");
        return model;
    }
}

5.HTML页面

//1.引入js
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

//2.通过config接口注入权限验证配置
wx.config({
    debug: true,
    appId: '[(${wxConfig.appId})]',
    timestamp: '[(${wxConfig.timestamp})]',
    nonceStr: '[(${wxConfig.nonceStr})]',
    signature: '[(${wxConfig.signature})]',
    jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData']
});

//3.通过ready接口处理成功验证,并调用相应接口
wx.ready(function(){
    // 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
    wx.updateAppMessageShareData({
        title: '[(${wxConfig.title})]', // 分享标题
        desc: '[(${wxConfig.desc})]', // 分享描述
        link: '[(${wxConfig.link})]', //分享URL
        imgUrl: "https://picsum.photos/200/200", // 分享图标,此处我测试使用了外部图片
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
    // 获取“分享给朋友”按钮点击状态及自定义分享内容接口
    wx.updateTimelineShareData({
        title: '[(${wxConfig.title})]', // 分享标题
        link: '[(${wxConfig.link})]', //分享URL
        //分享给朋友不需要使用分享描述desc字段
        imgUrl: "https://picsum.photos/200/200", // 分享图标,此处我测试使用了外部图片
        success: function () {
            // 用户确认分享后执行的回调函数
        },
        cancel: function () {
            // 用户取消分享后执行的回调函数
        }
    });
});

6.在微信公众号配置中添加JS接口安全域名

7.测试效果

分享给好友:

分享到朋友圈:

8.完成

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/nijibahaoa/article/details/112194289

智能推荐

java okhttp3源码,OkHttp源码分析(一) 请求和响应过程简单分析-程序员宅基地

这篇文章简要介绍OkHttp的请求和响应过程。0 前言​ OkHttp作为当下Java系编程的网络请求库,其热门程度自不必说了。网上有关OkHttp的使用、封装和源码分析的文章和代码也早已是百家齐放、甚至可以说是烂大街了。然而尽管如此,笔者还是希望能够将对OkHttp的学习和研究记录下来形成自己的内容,方便以后查看,于是开始写吧,好记性不如烂笔头。​ 那就从最简单的开始..._java okhttp怎么判断请求失败

python基础入门--07 列表、元组、字典、集合-程序员宅基地

上一篇我们已经认识和了解了列表的基本操作,今天做一下简单补充说明,同时进一步对元组、字典、集合这几个容器类型进行学习。一.列表的几点补充1.列表的值[a, b, c],类型是对象2.对象类型: 列表、字典、集合、元素、通过类创建的对象3.变量在存储对象数据的时候,存的对象保存在内存中的地址。如果用存对象的变量给另外一个变量赋值,赋的是地址注意:如果变量里存的对象,要注意赋值的...

缓冲区溢出攻击相关知识-程序员宅基地

本文是coursera软件安全课程学习总结,算是梳理知识,细节太多,只写了要点。0. 内存模型0.1 内存分配使用malloc函数分配的内存在heap区域,stack从高地址向低地址生长,heap相反。0.2 函数调用时的堆栈变化每当使用call指令进行函数调用时,都会将原来的eip寄存器中的值压栈,然后,将新的函数指针写入eip寄存器,...

Will , will be 的差別以及用法-程序员宅基地

问题我是國2生 我不太會分別 will 和 will be 的用法 如果在選擇題上出現 will , will be , is going to , is going to be 我真的不知該選什麼好 可以告訴 will , will be , is going to , is going to be 的差別嗎 請問有什麼訣竅嗎 該怎麼辨識呢 尤其是 will be 後面要加什麼They

什么是死锁以及避免死锁-程序员宅基地

一、定义  线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。当然死锁的产生是必须要满..._死锁避免的含义

xcode java mac_小白搭建Java环境之Mac篇-程序员宅基地

一、安装GIT和IDE1、既然是小白,那么就直接XCODE吧,Git等直接都装好了,可惜要耗费大概10GB空间2、剩下的IDEA和MyEclipse那就看大家心情了二、本机搭建JAVA环境:2.进入root帐号:sudo -s3、vim ~/.bash_profile最后一行增加:JAVA_HOME=”/Library/Java/JavaVirtualMachines/jdk1.8.0_121.j..._xcode java环境

随便推点

2021年10月份 中国最具影响力的50位钧瓷匠人排行榜_钧瓷大师排名前十-程序员宅基地

2021年10月份 中国最具影响力的50位钧瓷匠人排行榜数据来源 钧瓷内参钧瓷数据库排名算法 上榜和排名算法与10项规则有关,其中和个人的知名度,影响力,用户评价,平台指数正相关;制作流程 协同制作——协同评审——联合发布制作成员 人民日报人民号,微拍堂,钧瓷内参,得藏智库,禹州钧瓷新媒体,钧瓷TV2021年10月份中国最具影响力的50位钧瓷匠人排行榜排名 姓名 价格指数1 晋佩章 4.092 刘富安 3.843 孔相卿 2.064 任星航 1.945 杨志 1.906 刘建军 ._钧瓷大师排名前十

sqli-labs预备知识_sqli lab基本知识-程序员宅基地

一、系统函数 version()------------------------------------------mysql版本 user()---------------------------------------------数据库用户名 database()-----------------------------------------数据库名 @@datadir----..._sqli lab基本知识

pip install scrapy 报错: "cannot open include file: 'io.h' "-程序员宅基地

本文创建时间:2018-12-01Windows 下安装 Scrapy 报错安装环境 Windows 10, 安装时间 2018-12-01pip install scrapy 报错。 主要报错内容:raiser.c c:\python\python37\include\pyconfig.h(59): fatal error C1083: 无法打开包括文件: “i...

树莓派(Raspberry B+)PPPOE拨号上网并开放wifi热点步骤-程序员宅基地

第一部分 连接笔记本和树莓派: 1. 下载SDFormatter,格式化SD卡; 2.下载Win32DiskImager和Raspberry系统,用Win32DiskImager将Raspberry系统系统刷入SD卡; 3.打开SD卡的boot分区,新建一个文件,文件名为ssh。找到cm..._pppoe转移动热点

Piwigo 2.7.1 SQLI学习_piwigo2.7.1安装-程序员宅基地

https://144.one/piwigo-271-sqlixue-xi.html_piwigo2.7.1安装

计算机专业的你,毕业后可以从事什么职业?前景如何?-程序员宅基地

计算机专业,从多年前到如今一直都是一个申请的大热门专业,这不是没有道理的。计算机科学专业毕业的你,在学业期间会获得许多专业的技能以及非专业的技能。这二者中的任何一个都会非常受到雇主的重视!无论是你在学业期间所具备的领导能力还是专业能力,都能够成为你就业道路上的一大助力。当下,大数据、人工智能等兴起于发达,更是让计算机科学的应用范围扩展到生活的方方面面,无所不在。在更大的范围内,计算机所发挥的作用也越来越大!这也就是说,计算机专业毕业的你可以在几乎所有的行业中找到适合自己的能够发挥自己专业技能的职