Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >jfinal-weixin是如何支持多公众号配置的

jfinal-weixin是如何支持多公众号配置的

原创
作者头像
Java旅途
修改于 2020-07-08 02:05:07
修改于 2020-07-08 02:05:07
8950
举报
文章被收录于专栏:Java旅途Java旅途

spring-boot-starter-weixin是jfinal-weixin的spring boot版本,以前一直在用jfinal-weixin做为开发工具包,也一直没有尝试过支持多公众号,最近正好有需求要求支持多公众号,就来研究一番它是如何支持多公众号的。

找到源码,打开后发现有个拦截器,我们看看拦截器做了什么。

微信后台如何配置来支持多公众号

在preHandle中有比较重要的几行代码,我们拿出来单独分析一下。

代码语言:txt
AI代码解释
复制
String appId = request.getParameter(weixinProperties.getAppIdKey());
代码语言:txt
AI代码解释
复制
// weixinProperties类
private String appIdKey = "appId"; 

这一行代码重要是获取参数的,也就是在我们微信后台配置开发者url的时候添加的参数,参数名是appId。

代码语言:txt
AI代码解释
复制
// 判断是否多公众号,将 appId 与当前线程绑定,以便在后续操作中方便获取ApiConfig对象:
Object bean = handlerMethod.getBean();
boolean isWx = bean instanceof MsgController;
String token;
if (isWx) {
    if (StringUtils.hasText(appId)) {
        ApiConfigKit.setThreadLocalAppId(appId);
        token = ApiConfigKit.getApiConfig(appId).getToken();
    } else {
        token = ApiConfigKit.getApiConfig().getToken();
    }
} else {
    token = WxaConfigKit.getWxaConfig().getToken();
}

这一段代码主要是根据微信后台传过来的appId来获取对应微信公众号的token,来跟微信后台传过来的token进行匹配。

公众号后台配置如下:

如何支持多公众号

在MsgInterceptor中有用到ApiConfigKit.getApiConfig(),我们打开这个类看一下,他具体做了什么工作。

代码语言:txt
AI代码解释
复制
public static ApiConfig getApiConfig(String appId) {
    log.debug("appId: " + appId);
    ApiConfig cfg = (ApiConfig)CFG_MAP.get(appId);
    if (cfg == null) {
        throw new IllegalStateException("需事先调用 ApiConfigKit.putApiConfig(apiConfig) 将 			  
             appId对应的 ApiConfig 对象存入,如JFinalConfig.afterJFinalStart()中调用, 才可以使用 			
             ApiConfigKit.getApiConfig() 系列方法");
    } else {
        return cfg;
    }
}

根据自定义的异常信息,我们知道如果想要使用getApiConfig(String appId),则必须先调用putApiConfig(apiConfig),将公众号信息存入。

代码语言:txt
AI代码解释
复制
@Configuration
@AllArgsConstructor
public class WeixinAppConfig implements SmartInitializingSingleton {
	private final DreamWeixinProperties weixinProperties;
	private final SpringAccessTokenCache accessTokenCache;

	@Override
	public void afterSingletonsInstantiated() {
		boolean isdev = weixinProperties.isDevMode();
		ApiConfigKit.setDevMode(isdev);
		ApiConfigKit.setAccessTokenCache(accessTokenCache);
		List<DreamWeixinProperties.ApiConfig> list = weixinProperties.getWxConfigs();
		for (DreamWeixinProperties.ApiConfig apiConfig : list) {
			ApiConfig config = new ApiConfig();
			if (StrKit.notBlank(apiConfig.getAppId())) {
				config.setAppId(apiConfig.getAppId());
			}
			if (StrKit.notBlank(apiConfig.getAppSecret())) {
				config.setAppSecret(apiConfig.getAppSecret());
			}
			if (StrKit.notBlank(apiConfig.getToken())) {
				config.setToken(apiConfig.getToken());
			}
			if (StrKit.notBlank(apiConfig.getEncodingAesKey())) {
				config.setEncodingAesKey(apiConfig.getEncodingAesKey());
			}
			config.setEncryptMessage(apiConfig.isMessageEncrypt());
			ApiConfigKit.putApiConfig(config);
		}
		// 省略小程序配置
	}
}
  • afterSingletonsInstantiated:当所有单例 bean 都初始化完成以后, 容器会回调该接口的方法

这个类的目的就是在项目启动后将配置文件中的微信公众号配置取出来,循环放入ApiConfigKit。

DreamWeixinProperties部分配置如下:

代码语言:txt
AI代码解释
复制
@Getter
@Setter
@ConfigurationProperties("dream.weixin")
public class DreamWeixinProperties {

	/**
	 * 拦截的路由,默认:/weixin/*
	 */
	private String urlPatterns = "/weixin/*";
	/**	
	 * 是否开发模式,默认:false
	 */
	private boolean devMode = false;
	/**
	 * 多公众号url挂参,默认:appId
	 */
	private String appIdKey = "appId";
	/**
	 * 多公众号配置
	 */
	private List<ApiConfig> wxConfigs = new ArrayList<>();

	@Getter
	@Setter
	public static class ApiConfig {
		private String token;
		private String appId;
		private String appSecret;
		private String encodingAesKey;
		// 消息加密与否
		private boolean messageEncrypt = false;
	}
}

数据库获取多公众号配置

我们一般需要来在平台管理公众号,因此从数据库获取公众号配置要远比配置文件获取更加方便,我们只需要实现SmartInitializingSingleton接口,将公众号配置改为从数据库获取就可以了。

代码语言:txt
AI代码解释
复制
@Configuration
@AllArgsConstructor
public class WxConfig implements SmartInitializingSingleton {

    private final SpringAccessTokenCache accessTokenCache;

    @Autowired
    private WexinNoDao wexinNoDao;
    @Override
    public void afterSingletonsInstantiated() {
        ApiConfigKit.setDevMode(true);
        ApiConfigKit.setAccessTokenCache(accessTokenCache);
        /**
         * 数据库查询
         */
        List<WeixinNoBean> list = wexinNoDao.wxNoList();
        for (WeixinNoBean apiConfig : list) {
            ApiConfig config = new ApiConfig();
            if (StrKit.notBlank(apiConfig.getAppid())) {
                config.setAppId(apiConfig.getAppid());
            }
            if (StrKit.notBlank(apiConfig.getAppKey())) {
                config.setAppSecret(apiConfig.getAppKey());
            }
            if (StrKit.notBlank(apiConfig.getToken())) {
                config.setToken(apiConfig.getToken());
            }
            if (StrKit.notBlank(apiConfig.getAeskey())) {
                config.setEncodingAesKey(apiConfig.getAeskey());
            }
            config.setEncryptMessage(false);
            ApiConfigKit.putApiConfig(config);
        }
    }
}

这样,当项目启动以后,就会调用我们自定义的WxConfig来完成多公众号的配置。数据库读取公众号配置比配置文件直接读取更加灵活。因此,我也是比较推荐直接从数据库来读取公众号配置的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
在线问题反馈模块实战(十)​:实现图片预览功能
       接下来的这几期,bug菌想跟大家分享一下自己昨天刚接到一个临时的需求,热乎着呢,想分享一下自己是如何面对临时需求并制定整个开发周期,其中包括从梳理业务到创建业务表再到实现业务逻辑形成闭环再到与前端对接,其中会穿插一些业务拓展及功能性拓展,这一条龙流程在线与大家一起见证,分享给刚入门的小伙伴,希望对你们有所帮助。
bug菌
2023/05/27
3150
在线问题反馈模块实战(十)​:实现图片预览功能
JAVA下载文件代码「建议收藏」
public static HttpServletResponse download(String path, HttpServletResponse response, String fileName) { try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = fileName; if(StringUtils.isEmpty(fileName)){ filename = file.getName(); } // 取得文件的后缀名。 String ext = filename.substring(filename.lastIndexOf(“.”) + 1).toUpperCase();
全栈程序员站长
2022/09/08
5150
Java工具集-文件下载工具类
代码示例 package com.simple.util.http; import com.simple.util.io.IOUtil; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; /** * @program: simple_tools * @descript
cwl_java
2020/06/10
1.5K0
Java小白翻身-基于SpringBoot的文件下载系统 3
这一节的目的是实现文件的打包下载。 有了Hutool,感觉轻松多了呢! 我们还是要导入Hutool,帮我们省去文件操作的麻烦。
剽悍一小兔
2021/07/14
6140
Java小白翻身-基于SpringBoot的文件下载系统 3
JSP文件下载及getOutputStream() has already been的解决 JSPWeblogicExcelWeb.net
JSP文件下载及出现getOutputStream() has already been called for this response的解决方法 http://iamin.blogdriver.com/iamin/1072546.html
阿敏总司令
2019/02/28
1.7K0
Java下载文件的几种方式
以流的方式下载 public HttpServletResponse download(String path, HttpServletResponse response) { try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); /
一觉睡到小时候
2019/09/17
4.1K0
Spring MVC-10循序渐进之文件下载
像静态资源,我们在浏览器中打开正确的URL即可下载,只要该资源不是放在WEB-INF目录下,Servlet/JSP容器就会将该资源发送到浏览器。 然而有的时候静态资源是保存在应用程序目录外或者存在数据库中,或者有的时候需要控制它的访问权限,防止其他网站交叉引用它。 如果出现上述任意一种情况,都必须通过编程来发送资源。
小小工匠
2021/08/17
3820
Gzip压缩文件和压缩字符串,web接口应用
打印输出: testPost发送内容:{"id":"10","name":"zhangliao"} 接口调用返回结果:"json串返回成功"
oktokeep
2024/11/21
1070
【springboot2.x】实现文件下载
简写了几种下载日志的方法。一、方法一 @ApiOperation("日志下载") @GetMapping("/logDownload") public void download(HttpServletResponse response) { try { String mulu = "d:/logs"; ZipUtil.zip(mulu); String path = "d:/logs.zip";
无敌小菜鸟
2023/02/16
8930
浏览器下载压缩包
#需求如下 通过前台传入id数据库查询数据,写入临时文件,再将临时文件存入,压缩包,一起打包下载。 #代码如下
崔笑颜
2020/06/08
1.4K0
web项目中视频的上传和展示
以上步骤视频就通过程序保存到电脑的指定位置了,一般我会新建一个视频类,先用uuid给视频重命名,视频类的路径是视频的名字,取的时候使用视频的名字去请求。
Mshu
2018/10/31
1.2K0
JQuery Uploadify v3.2.1 上传图片并预览(基于spring mvc框架开发)
http://blog.csdn.net/java0311/article/details/44885933
bear_fish
2018/09/19
6830
完整的 Spring Boot 下载文件示例代码
package com.alibaba.alpha.download; import com.alibaba.alpha.mapper.UiTestCaseMapper; import com.alibaba.alpha.model.UiTestCase; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.sp
一个会写诗的程序员
2019/02/26
2.4K0
Java 使用blob对H5视频播放进行加密
1.创建一个H5 <video>标签 <video id="sound" type="video/mp4" controls="controls" autoplay="autoplay" webkit-playsinline="true" playsinline="true" heigth="100%"></video> 2.创建请求获取视频源,并将视频源转为blob对象 //创建XMLHttpRequest对象 var xhr = new XMLHttpReques
用户1518699
2018/09/12
4.7K0
spring-data-mongodb之gridfs
mongodb除了能够存储大量的数据外,还内置了一个非常好用的文件系统。 基于mongodb集群的优势,GridFS当然也是分布式的,而且备份也方便。 当用户把文件上传到GridFS后,文件会被分割成大小为256KB的块,并单独存放。 好处如下: 可以有Replication; 可以利用MongoDB的权限访问控制; 可以利用现成的MongoDB备份方式; 今天主要是学习如何使用data这个框架来操作GridFS,首先配置gridFs的模板类 <!-- Mongodb gridFs的模板 --> <bea
猿天地
2018/04/03
2K0
java 下载文件
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/154241.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/07
4830
Openlayers4+servlet实现切片的本地缓存
本文实现的是结合Openlayers4和java servlet实现公网资源切片的本地缓存。
牛老师讲GIS
2018/10/23
8430
Openlayers4+servlet实现切片的本地缓存
shape文件的生成与打包下载
概述 本文讲述如何结合Geotools实现后端shp文件的生成与打包下载。 实现效果 实现 shp文件生成 如何生成shp文件在前面的相关博文里面已经做过说明,本文不再赘述。 shp文件打包
牛老师讲GIS
2018/10/23
2.9K1
shape文件的生成与打包下载
Java实现pdf和Excel的生成及数据动态插入、导出
作者 | TOM-SHUSHU 来源 | https://cnblogs.com/Tom-shushu/p/14279357.html 一、序言 Excel、PDF的导出、导入是我们工作中经常遇到的一个问题,刚好今天公司业务遇到了这个问题,顺便记个笔记以防下次遇到相同的问题而束手无策。 公司有这么两个需求: 需求一、给了一个表单,让把查出来的数据组装到表单中并且提供以PDF格式的下载功能。 需求二、将数据查出来以Excel表格的形式下载下来。 二、Java实现PDF的生成和数据动态插入、导出功能 1、第一
程序猿DD
2023/04/04
1.7K0
Java实现pdf和Excel的生成及数据动态插入、导出
java 文件下载,中文表名,中文内容
@RequestMapping("userDownloadTemplet") private void userDownloadTemplet(HttpServletRequest request,HttpServletResponse response, String filePath){ try { filePath = request.getSession().getServletContext().getRealPath("/WEB-
微风-- 轻许--
2022/04/13
9420
相关推荐
在线问题反馈模块实战(十)​:实现图片预览功能
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档