?

应 Solon 技术交流群里小伙伴的要求,我分享下在 Solon 中使用 WxJava 的经验、类库。


具体实现

  1. 提供统一的 Yaml 配置
package cn.edu.hnuahe.mountain.common.providers;

import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Init;
import org.noear.solon.core.Aop;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml; /**
* @author 颖
*/
@Component
public class YamlProvider extends ServiceProvider { @Init
@Override
public void bootstrap() {
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
options.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
Aop.wrapAndPut(Yaml.class, new Yaml(options));
} }
  1. 提供 WxService 统一管理器
package cn.edu.hnuahe.mountain.common.utils;

import me.chanjar.weixin.cp.api.WxCpService;
import org.noear.solon.annotation.Component; import java.util.concurrent.ConcurrentHashMap; /**
* @author 颖
*/
@Component
public class WxCpClient extends ConcurrentHashMap<String, WxCpService> { public WxCpService get() {
return this.get("default");
} }
  1. WxConfigDefault 注入提供器
package cn.edu.hnuahe.mountain.common.providers;

import cn.edu.hnuahe.mountain.common.utils.WxCpClient;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Init;
import org.noear.solon.annotation.Inject;
import org.noear.solon.cloud.CloudClient;
import org.noear.solon.cloud.model.Config;
import org.noear.solon.core.Aop;
import org.yaml.snakeyaml.Yaml; import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; /**
* @author 颖
*/
@Component
public class WxCpServiceProvider extends ServiceProvider { @Inject
Yaml yaml;
@Inject
WxCpClient wxCpClient; public static class WxCpConfig extends ConcurrentHashMap<String, WxCpDefaultConfigImpl> {} @Init
@Override
public void bootstrap() {
Config rawConfig = CloudClient.config().pull(Solon.cfg().appGroup(), "wxCp.yaml");
WxCpConfig configs = this.yaml.loadAs(rawConfig.value(), WxCpConfig.class); configs.forEach((name, config) -> {
WxCpService service = new WxCpServiceImpl();
service.setWxCpConfigStorage(config);
// 注册到企业微信客户端管理器
this.wxCpClient.put(name, service);
}); WxCpMessageRouter router = new WxCpMessageRouter(
this.wxCpClient.get()
);
Aop.wrapAndPut(WxCpMessageRouter.class, router);
} }

[scode type="blue"]步骤2与步骤3共同解决了一个大问题,就是一个企业微信小程序可能需要拥有多种身份的问题。比如,访问企业微信通讯录就需要基于 通讯录同步 小程序的身份进行操作。[/scode]

  1. 一个 Test,用于生成需要的 wxCp.yaml 配置
package cn.edu.hnuahe.mountain.common.providers;

import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import me.chanjar.weixin.cp.config.impl.WxCpRedissonConfigImpl;
import org.junit.jupiter.api.Test;
import org.noear.solon.core.Aop;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml; import static org.junit.jupiter.api.Assertions.*; class WxCpServiceProviderTest { @Test
void generateConfig() {
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
options.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
Yaml yaml = new Yaml(options); WxCpDefaultConfigImpl defaultConfig = new WxCpDefaultConfigImpl();
defaultConfig.setCorpId("123");
defaultConfig.setCorpSecret("456");
defaultConfig.setAgentId(789);
WxCpDefaultConfigImpl contactsConfig = new WxCpDefaultConfigImpl();
contactsConfig.setCorpId("987");
contactsConfig.setCorpSecret("654"); WxCpServiceProvider.WxCpConfig config = new WxCpServiceProvider.WxCpConfig();
config.put("default", defaultConfig);
config.put("contacts", contactsConfig); System.out.println(yaml.dump(config));
} }
  1. 一个简单的使用案例
package cn.edu.hnuahe.mountain.gateway.http.controller;

import cn.edu.hnuahe.mountain.common.entities.models.User;
import cn.edu.hnuahe.mountain.common.http.controller.BaseController;
import cn.edu.hnuahe.mountain.common.mappers.UserMapper;
import cn.edu.hnuahe.mountain.common.utils.WxCpClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.Gender;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.article.NewArticle;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.MethodType; import java.util.List; /**
* @author 颖
*/
@Controller
@Mapping(value = "/wechat")
public class WeChatController { @Inject
WxCpClient wxCpClient; @Mapping(value = "sendMessage", method = MethodType.ALL)
public WxCpMessageSendResult sendMessage() throws WxErrorException {
NewArticle part1 = new NewArticle();
part1.setUrl("https://www.baidu.com/");
part1.setPicUrl("https://pc-index-skin.cdn.bcebos.com/hiphoto/56868369122.jpg?x-bce-process=image/crop,x_0,y_0,w_1728,h_1080");
part1.setDescription("Is Really A Happy Day");
part1.setTitle("Happy Day"); WxCpMessage message = WxCpMessage.NEWS()
.agentId(this.wxCpClient.get().getWxCpConfigStorage().getAgentId())
.toUser("2102160202008")
.addArticle(part1)
.build(); return this.wxCpClient.get()
.getMessageService()
.send(message); } }

散花~

WxJava for Solon - 咱也不知道为啥要写的更多相关文章

  1. 一个用消息队列 的人,不知道为啥用 MQ,这就有点尴尬

    消息队列 为什么写这篇文章? 博主有两位朋友分别是小A和小B: 小A,工作于传统软件行业(某社保局的软件外包公司),每天工作内容就是和产品聊聊需求,改改业务逻辑.再不然就是和运营聊聊天,写几个SQL, ...

  2. 天天都用消息队列,却不知道为啥要用MQ,这就有点尴尬了

    1.为什么要使用消息队列? 分析:一个用消息队列的人,不知道为啥用,有点尴尬.没有复习这点,很容易被问蒙,然后就开始胡扯了. 回答:这个问题,咱只答三个最主要的应用场景(不可否认还有其他的,但是只答三 ...

  3. idea的maven项目不知道为啥下载不下来jar包,看本地仓库只是下载了一下xml文件,没有jar包问题

    确认了私服上的jar包能直接下载下来,而且jar包是正常的:但是就是不能通过idea下载,通过idea下载到本地仓库的只生成了.lastUpdated文件,检查了setting.xml文件.网络,私服 ...

  4. 写了shell脚本想一键启动三台虚拟机的Zookeeper,却不知道为啥总是启动不了

    首先,一键启动的shell脚本是这样的 #! /bin/bash case $1 in "start"){ for i in node01 node02 node03 do ssh ...

  5. *****又错一道,不知道为啥。。。 ybt【例5.19】字符串判等

    [题目描述] 判断两个由大小写字母和空格组成的字符串在忽略大小写,且忽略空格后是否相等. [输入] 两行,每行包含一个字符串. [输出] 若两个字符串相等,输出YES,否则输出NO. 代码我觉得没啥问 ...

  6. Floyd | | jzoj[1218] | | [Usaco2009 Dec]Toll 过路费 | | BZOJ 1774 | | 我也不知道该怎么写

    写在前面:老师说这一道题是神题,事实上确实如此,主要是考察对Floyd的理解 ******************************题目.txt************************* ...

  7. web中的——作者也不知道这里面写的啥

    1.使用超链接<a href="/Default/Index">添加</a><a href="#">返回显示信息</a ...

  8. 学习Swift的点点滴滴

    1.类型标注 之前不知道为啥别人写的Swift语言的时候,定义常量或者变量的格式是 常量: let 常量名: 常量类型 = 常量值  或者 变量: var 变量名: 变量类型 = 初始值 原来书上有记 ...

  9. 合同主体列表添加两条合同主体,返回合并支付页面,支付总弹"请选择合同主体",删除后,竟然还能支付(改合并支付页面的字段状态)

    bug描述: 操作步骤:1.进入"商标续展"产品详情页面,点击立即购买(数量设为2),进入合并订单界面,选择合同主体,点击全部,清空所有合同主体2.新建合同主体保存,设置该合同主体 ...

  10. QLPreViewController的初步实用

    前一阵项目需要添加一个文档文件的查看功能,于是就各种找资料,一开始想实用webView,然而webView有的格式不支持,而且占内存太大了.找着找着就找到QLPreViewController.用了一 ...

随机推荐

  1. MySQL防止被黑,通过跳板机ssh隧道访问

    更新了另外一篇,比这篇的方法更好:[https://www.cnblogs.com/scottyzh/p/17745527.html](服务器没有开放3306端口 远程访问MySQL数据库方法) 一. ...

  2. ez_sql

    打开界面是查询界面 点击不同的查询页面返回的内容不同,然后url的地址发生变化,毫无疑问注入点在id处 这里直接进行测试 单引号无回显 双引号回显id不存在 初步判断为字符型注入且为单引号包裹 因为双 ...

  3. go 上下文:context.Context

    Go语言中的上下文(Context)是一种用于在 Goroutines 之间传递取消信号.截止时间和其他请求范围值的标准方式.context 包提供了 Context 类型和一些相关的函数,用于在并发 ...

  4. 四载磨砺,一群青年“识瘤者”以AI助力医疗创新

    ​​本文分享自华为云社区<[先锋开发者云上说]四载磨砺,一群青年"识瘤者"以AI助力医疗创新>,作者:Gauss松鼠会小助手2 . 一群青年"识瘤者" ...

  5. GUI界面实现小学生口算题卡功能(一)| 简要了解GUI

    上课没认真听,下课不好好写. 关于GUI,首先了解了一下什么是GUI: GUI(Graphical User Interface),图形用户界面.采用图形方式显示的计算机操作用户接口.与早期计算机使用 ...

  6. 【GIT】学习day04 | 将本地代码推送到码云仓库中进行管理【外包杯】

    仓库代码页 将本能仓库和码云仓库进行关联 代码组成 git remote add origin 加上下面的地址 将本地仓库的代码推送到码云仓库上 git push -u origin master 之 ...

  7. 使用 anasible 搭建一个多 master 多 worker 的 k8s 集群

    使用 ansible 搭建一个多 master 多 worker 的 k8s 集群 kubernetes + istio 是目前最强大,也是最易于使用的服务网格方案.要使用kubernetes + i ...

  8. LeetCode1806:还原排列的最少操作步数(置换群 or 模拟)

    题意:题目的意思是,给定一个初始状态perm,然后对perm的每个元素按照上述的规则进行变换操作.问:perm经过多少次这种操作能够变回初始的perm. 解题思路:第一种方法就是模拟,一直变换,直到变 ...

  9. 将Abp默认事件总线改造为分布式事件总线

    @ 目录 原理 创建分布式事件总线 实现自动订阅和事件转发 使用 启动Redis服务 配置 传递Abp默认事件 传递自定义事件 项目地址 原理 本地事件总线是通过Ioc容器来实现的. IEventBu ...

  10. 微软官方发布的C#开源、免费、实用的Windows工具箱

    前言 今天分享一款由微软官方发布的C#开源.免费.实用的Windows工具箱(帮助用户调整和简化Windows系统的体验,从而提高工作效率):Microsoft PowerToys. 项目介绍 Mic ...