微信公众号分享的坑

2023-05-16

记一次微信公众号分享sdk

这里我的脚本是用jquery写的,不带框架源码

首先创建jsp引入JavaScript微信分享js

<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

引入jquery

<script type="text/javascript" src="../script/jquery.js"></script>

这里是使用的是http请求,以下贡献http请求工具类

package com.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

/**
 * http get post
 * @author 为中华之崛起而编程
 *
 */
@SuppressWarnings("all")
public class HttpUtil {

	/**
	 * 执行HTTP GET请求,返回请求响应的内容
	 * @param url
	 *            请求的URL地址
	 * @return 
	 * 			     返回请求响应的内内容
	 * @throws IOException
	 * @throws ClientProtocolException
	 */
	public static String doGet(String url) throws IOException {
		StringBuffer sb = new StringBuffer();
		HttpClient httpClient = new HttpClient();
		httpClient.getHttpConnectionManager().getParams()
				.setConnectionTimeout(2000);
		GetMethod getMethod = new GetMethod(url);
		try {
			getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,
					2000);
			httpClient.executeMethod(getMethod);
			if (getMethod.getStatusCode() == HttpStatus.SC_OK) {
				BufferedReader in = new BufferedReader(new InputStreamReader(
						getMethod.getResponseBodyAsStream()));
				String ln;
				while ((ln = in.readLine()) != null) {
					sb.append(ln);
				}
				try {
					in.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			getMethod.releaseConnection();
		}
		return null;
	}

	/**
	 * 执行HTTP POST请求,返回请求响应的内容
	 * 
	 * @param url
	 *            请求的URL地址
	 * @param params
	 *            请求的查询的参数可以为null
	 * @return 	      返回请求响应的内容
	 * @throws IOException
	 */
	public static String doPost(String url, Map<String, String> map)
			throws IOException {
		StringBuffer sb = new StringBuffer();
		HttpClient httpClient = new HttpClient();
		httpClient.getHttpConnectionManager().getParams()
				.setConnectionTimeout(2000);
		PostMethod postMethod = new PostMethod(url);
		postMethod.setRequestHeader("Content-Type",
				"application/x-www-form-urlencoded");

		int i = 0;
		NameValuePair[] data = new NameValuePair[map.size()];
		for (Map.Entry<String, String> entry : map.entrySet()) {
			data[i++] = new NameValuePair(entry.getKey(), entry.getValue());
		}
		postMethod.setRequestBody(data);

		try {
			postMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,
					2000);
			postMethod.getParams().setParameter(
					HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
			httpClient.executeMethod(postMethod);
			if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
				BufferedReader in = new BufferedReader(new InputStreamReader(
						postMethod.getResponseBodyAsStream(), "UTF-8"));
				String ln;
				while ((ln = in.readLine()) != null) {
					sb.append(ln);
				}
				try {
					in.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			postMethod.releaseConnection();
		}
		return null;
	}

	/**
	 * 执行HTTP POST请求,返回请求响应的内容
	 * 
	 * @param url
	 *            请求的URL地址
	 * @param params
	 *            请求的查询参数可以为null
	 * @return 返回请求响应的内容
	 * @throws IOException
	 */
	public static String doPost(String url, String body) throws IOException {
		StringBuffer sb = new StringBuffer();
		HttpClient httpClient = new HttpClient();
		httpClient.getHttpConnectionManager().getParams()
				.setConnectionTimeout(2000);
		PostMethod postMethod = new PostMethod(url);
		postMethod.setRequestHeader("Content-Type",
				"application/x-www-form-urlencoded");
		postMethod.setRequestBody(body);

		try {
			postMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,
					2000);
			postMethod.getParams().setParameter(
					HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
			httpClient.executeMethod(postMethod);
			if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
				BufferedReader in = new BufferedReader(new InputStreamReader(
						postMethod.getResponseBodyAsStream(), "UTF-8"));
				String ln;
				while ((ln = in.readLine()) != null) {
					sb.append(ln);
				}
				try {
					in.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			postMethod.releaseConnection();
		}
		return null;
	}

}

创建一个servlet,在servlet初始化时获取access_token

1.获取access_token地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=

2.获取ticket地址:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=&type=jsapi

创建servlet初始化

public class InitServlet extends HttpServlet{
    //这里创建一个线程2小时调用一次循环调用,预防access_token过期
    private static ScheduledExecutorService POOL = Executors.newScheduledThreadPool(1);
    //创建一个map存ticket
    public static Map<String,String> map = new HashMap<String,String>();
    
    public void init() throws ServletException {
        
        POOL.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				try {
					String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=&secret=d51ff270c9d161fd6065a0c5891ca802";
					String json = HttpUtil.doGet(url);
					Map mapss = JSON.parseObject(json, Map.class);
					String access_token = (String)mapss.get("access_token");
					url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
					json = HttpUtil.doGet(url);
					Map mapOne = JSON.parseObject(json, Map.class);
					System.out.println(JSON.toJSONString(mapOne));
					String jsapi_ticket = (String)mapOne.get("ticket");
					map.put("ticket", jsapi_ticket);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, 0, 2 * 60 * 59 * 1000, TimeUnit.MILLISECONDS);
    }
}

web.xml调用servlet初始化

  <servlet>  
   <servlet-name>InitServlet</servlet-name>  
   <servlet-class>com.servlet.InitServlet</servlet-class>  
   <load-on-startup>1</load-on-startup>  
  </servlet> 

下面创建jsp获取全域名,第一次就是在全域名这里栽跟头,因为没有动态获取所以sdk验签一直失败,一定要确保url参数跟你访问的页面的url保持一致

<%	
    //访问页的url
	String strBackUrl = "http://" + request.getServerName() + ":"+ request.getServerPort() + request.getContextPath()  + request.getServletPath(); 
    //参数 
	if(request.getQueryString() != null){
		strBackUrl = strBackUrl + "?" + (request.getQueryString());
	}
    //获取项目启动时初始化好的ticket
    String ticket = InitServlet.map.get("ticket");
    //调用签名算法,存入返回参数
	Map<String,String> map = Sha1.sign(ticket, strBackUrl);
%>

加入微信签名算法Sha1

package com.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

public class Sha1 {
	public static 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;
        System.out.println(string1);

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

        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);
    }
	
	public static String getRandomString(int length){
	    //产生随机数
	    Random random=new Random();
	    StringBuffer sb=new StringBuffer();
	    //循环length次
	    for(int i=0; i<length; i++){
	      //产生0-2个随机数,既与a-z,A-Z,0-9三种可能
	      int number=random.nextInt(3);
	      long result=0;
	      switch(number){
	      //如果number产生的是数字0;
	      case 0:
	        //产生A-Z的ASCII码
	        result=Math.round(Math.random()*25+65);
	        //将ASCII码转换成字符
	        sb.append(String.valueOf((char)result));
	        break;
	        case 1:
	          //产生a-z的ASCII码
	        result=Math.round(Math.random()*25+97);
	          sb.append(String.valueOf((char)result));
	        break;
	        case 2:
	          //产生0-9的数字
	                   sb.append(String.valueOf
	                          (new Random().nextInt(10)));
	        break; 
	      }
	    }
	    return sb.toString();
	  }
}

执行脚本

<script type="text/javascript">
$(function() {
	wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: '', // 必填,企业号的唯一标识,此处填写企业号corpid
        timestamp: '<%=map.get("timestamp")%>', // 必填,生成签名的时间戳
         nonceStr: '<%=map.get("nonceStr")%>', // 必填,生成签名的随机串
        signature: '<%=map.get("signature")%>',// 必填,签名,见附录1
        jsApiList: [
            'onMenuShareAppMessage',
            'scanQRCode'
        ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });
	wx.ready(function () {   //需在用户可能点击分享按钮前就先调用
	    
	    var url = '自定义跳转url';
		wx.onMenuShareAppMessage({
			title: '', // 分享标题
		    desc: '', // 分享描述
		    link: url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
		    imgUrl: '', // 分享图标
			success: function () {
			// 用户点击了分享后执行的回调函数
			}
		});
	});
	wx.error(function(res){
	    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
	});
	
});

</script>

打开调试模式,返回config:ok就算是成功了,这里拿分享举例

还有一个就是,想多个页面都使用同一个自定义分享,把分享的sdk单独出来,要使用的页面去引用此页面就可以了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微信公众号分享的坑 的相关文章

  • IDEI打开主动引入功能,并排除一些包的自动引入

    欧尅了
  • dubbo

    dubbo通过官网学习 http dubbo apache org en us 一 陌生的名词解释 xff1a SPI xff1a service provider interface 服务提供机制 Hessian 是一个轻量级的RPC框架
  • 2020-09-04

    构造器 private SystemStatus try this sysStatus 61 0 transManager 61 new TransactionManager try DBTableSQL dbTable 61 new DB
  • 人脸匹配(face matching)

    以下是人脸匹配 xff08 face matching xff09 的实验报告 xff0c 实验中采用ldlib xff0c facenet xff0c arcface三种算法 xff0c 简单对比了三种算法的效果 xff0c 源代码见文章
  • 登录功能逻辑分析及部分代码实现

    1 代码书写顺序 xff1a login jsp LoginServlet LoginService LoginDao login jsp 2 loginservlet 1首先获取页面传的值 username password 2 调用us
  • mysql中可以查询英文却查不了中文或数字

    啊啊啊啊真的是阔怕 想用js 43 ajax写一个智能搜索 遇到了很多问题哦 不过这次让我很熟练的用debug了 哈哈哈哈开心 刚开始连接数据库一直没有返回值觉得好奇怪 xff01 后来大神就说是因为数据库和Java文件编码格式不一样 我试
  • springboot+JPA- - - -项目基本结构(包含ResultVOUtil自定义错误信息)

    springboot项目的整体结构 1 entity package com lz palmscore entity import javax persistence Entity import javax persistence Gene
  • TCP四次挥手

    挥手是为了终止连接 过程解释 xff1a
  • Idea上传项目到Git分支--解决Git pull failed问题

    就是上面这张图上的字 xff0c 困扰的我好苦好苦 今天我终于战败它了啊啊啊啊啊啊啊啊啊啊啊啊啊 xff01 xff01 上面这个呢 xff0c 大概就是说本地的文件和远程Git上的代码有冲突了 xff0c 可能会把你的替换掉 xff0c
  • Arch linux系统安装及顺手安装deepin桌面

    现在arch系统很多人都学着安装 xff0c 虽然手动性强但还是很好安装的 安装方式有两种 xff0c 一种是使用archinstall xff0c 可以说是个半自动 安装方法 xff0c 只要能上网 xff0c 前期设置好了 xff0c
  • 【C++服务器入门基础------4.IPC进程间通信--管道】

    大学生寒假在家过于无聊 xff0c 整理一下以前学过的知识 xff0c 顺便复习一下 xff0c 水平较低 xff0c 专业性差 xff0c 仅供参考 xff0c 不喜勿喷 xff08 反正也没人看 xff09 连续一周多出去泡妞了 xff
  • 浅谈Binder

    参考文章 xff1a https blog csdn net ly0724ok article details 117566381 ps xff1a 强烈推荐这篇文章 xff0c 写得很仔细 xff0c 图文结合 xff0c 一看就懂 xf
  • git或svn查看远程源地址

    git查看 xff1a git remote v svn 查看 svn info 转载 git或svn查看远程源地址 https www cnblogs com jiwd p 12504815 html
  • Linux登录一直报login incorrect问题及我的解决方案

    Linux登录一直报login incorrect问题及我的解决方案 打开VMware xff0c 启动虚拟机 xff0c Linux登录 xff0c 输入用户名和密码 xff0c 报Login incorrect 难道我输错了 xff1f
  • Spring-依赖注入(IOC)

    SPRING 一 依赖注入 xff08 IOC xff09 1 什么是依赖注入 xff08 1 xff09 我们经常说的控制反转 xff08 Inversion of Control IOC xff09 和依赖注入 xff08 Depend
  • 使用Vmware虚拟机无法ping通开发板

    文章同时发布于个人博客https www shui2000 top posts 76f723b3 html 问题详细描述 嵌入式课程中 xff0c 本人使用Vmware虚拟机运行Ubuntu22 04操作系统 xff0c 无法与开发版pin
  • 深入浅析MyBatis源码

    MyBatis 1 SqlSessionFactoryBuilder 通过build方法去解析xml配置文件 通过调用XMLConfigBuilder的parse方法将配置文件封装成一个Configuration对象 Xml节点解析 封装好
  • java 无需SSL验证的HTTP请求

    实例 如果有用请给我个赞好吗 public static Map lt String Object gt doPost String url Map lt String String gt paramaters HttpPost httpR
  • Kafta原理

    消息队列通信的模式 通过上面的例子我们引出了消息中间件 xff0c 并且介绍了消息队列出现后的好处 xff0c 这里就需要介绍消息队列通信的两种模式了 xff1a 一 点对点模式 如上图所示 xff0c 点对点模式通常是基于拉取或者轮询的消
  • MapStruct简介简单应用

    1 MapStruct 是什么 xff1f 1 1 JavaBean 的困扰 对于代码中 code JavaBean code 之间的转换 xff0c 一直是困扰我很久的事情 在开发的时候我看到业务代码之间有很多的 code JavaBea

随机推荐

  • SpringBoot入门案例

    基础项目该包含哪些东西 Swagger在线接口文档 CodeGenerator 代码生成器 统一返回 通用的分页对象 常用工具类 全局异常拦截 错误枚举 自定义异常 多环境配置文件 Maven多环境配置 日志配置 JenkinsFile S
  • Spring事务管理机制

    一 Spring事务管理的几种方式 xff1a Spring事务在具体使用方式上可分为两大类 xff1a 1 声明式 基于 TransactionProxyFactoryBean的声明式事务管理 基于 lt tx gt 和 lt aop g
  • SpringBoot 注解大全

    一 注解 annotations 列表 1 64 SpringBootApplication 包含了 64 ComponentScan 64 Configuration和 64 EnableAutoConfiguration注解 其中 64
  • Spring 中的bean 是否线程安全

    结论 xff1a 不是线程安全的 Spring容器中的Bean是否线程安全 xff0c 容器本身并没有提供Bean的线程安全策略 xff0c 因此可以说Spring容器中的Bean本身不具备线程安全的特性 xff0c 但是具体还是要结合具体
  • SpringBoot使用PageHelper分页

    一 开发准备 1 开发工具 IntelliJ IDEA 2020 2 3 2 开发环境 Red Hat Open JDK 8u256 Apache Maven 3 6 3 3 开发依赖 SpringBoot lt dependency gt
  • Windows Server 出现多个匿名登陆用户的问题解决

    1 起因 工作中需要在同一台 windows server的机器上多个用户同时使用 xff0c 遂建立多个账号 xff0c 供大家进行使用 2 问题 一段时间后发现系统特别卡顿并会死机 xff0c 查询原因后发现 xff0c 如图所示 xf
  • java锁 synchronized的使用及原理剖析

    synchronized用法有三个 修饰实例方法 修饰静态方法 修饰代码块 1 修饰实例方法 synchronized关键词作用在方法的前面 xff0c 用来锁定方法 xff0c 其实默认锁定的是this对象 public class Th
  • 面试HashMap的原理

    一般来说 xff0c java面试必不可少的菜品 xff0c 那就是 来 xff0c 讲一下HashMap的原理 那么今天就来讲一下HashMap的原理 先说一下JDK1 7跟JDK1 8对它的改变 JDK1 7之前使用的是数组加链表 xf
  • JAVA开发环境配置

    1 自己在网上下载JDK xff0c 本教程使用JDK1 6 下载好JDK后双击运行 xff0c 然后根据提示进行安装 安装好JDK后 bin xff1a 存放java可执行文件 如 xff1a javac exe java exe等等 d
  • MyEcplise_Maven搭建SSM框架

    Maven源码 链接 xff1a https pan baidu com s 1eTQMJQy 密码 xff1a 8j1q 博文中的MyEcplise 链接 xff1a https pan baidu com s 1dEdQYa 密码 xf
  • 怎么使用Linux常用命令大全

    系统信息 arch 显示机器的处理器架构 1 uname m 显示机器的处理器架构 2 uname r 显示正在使用的内核版本 dmidecode q 显示硬件系统部件 SMBIOS DMI hdparm i dev hda 罗列一个磁盘的
  • MySQL常用语句详解

    Winfrom连接网页 第一种方法 xff1a 调用本地浏览器System Diagnostics Process Start 34 https www microsoft com zh cn 34 第二种方法 xff1a 连接 strin
  • Maven搭建SSH连接Oracle数据库

    Maven工程搭建SSH连接Oracle数据库 首先在pom xml里引入jar lt project xmlns 61 34 http maven apache org POM 4 0 0 34 xmlns xsi 61 34 http
  • MyBatis简介与运用

    1 Mybatis简介 1 1 Mybatis是什么 Mybatis是一个java的持久层框架 xff0c 保存到数据库 持久化 xff1a 保存到本地文件 1 2 Mybatis的作用 操作数据库 1 3 为什么要学习mybatis 1
  • SpringMVC入门原理

    1 Springmvc原理 1 1 什么是springmvc SpringMVC是一个Spring框架内置的对MVC模式的实现 xff0c 就spring的一个子模块 1 2 什么是mvc Model view controller 模型
  • MyBatis逆向工程建立实体

    下面是用MyEcplise开发工具 为例 使用Ecplise操作步骤雷同于MyEcplise 1 第一步 2 搜索MyBatis 等待装载完成 xff0c 完成后 3 创建一个web项目 创建包 xff0c 创建generatorConfi
  • python apscheculer 报错 skipped: maximum number of running instances reached (1)

    apscheduler定时任务报错skipped maximum number of running instances reached 1 原因是默认max instances最大定时任务是1个 xff0c 可以通过在add job中调m
  • java 反射很重要

    1 创建一个User类 public class User private String username private String password private String name public User public Use
  • Netty入门案例教程

    1 首先导入netty all 5 0 0 Alpha1 jar 2 创建一个NettyConfig 整个工程的全局配置 package websocketcom netty import io netty channel group Ch
  • 微信公众号分享的坑

    记一次微信公众号分享sdk 这里我的脚本是用jquery写的 xff0c 不带框架源码 首先创建jsp引入JavaScript微信分享js lt script type 61 34 text javascript 34 src 61 34