?

应 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. [Python急救站课程]斐波那契数列的计算吧

    斐波那契数列的计算 a, b = 0, 1 while a < 1000: # 输出不大于1000 的序列.while表示循环 print(a, end=',') a, b = b, a + b

  2. RK3588-MPP解码详解

    一. 简介 [RK3588从入门到精通] 专栏总目录 本篇文章进行RK3588-MPP解码的详细解析 二. 环境介绍 硬件环境: ArmSoM-W3 RK3588开发板 软件版本: OS:ArmSoM ...

  3. Android学习day02【页面布局的练习】

    在网上找了一些图片,只用最简单的颜色进行区分,目的是熟悉线性布局和相对布局 下面是我找到的简单的Android页面,你也可以尝试以下' 下面是我的实现代码 第一个

  4. 2019牛客国庆集训派对day3 G排列(状压dp)

    题目传送门 一道很好的状压DP,状态是当前的占位情况,排序操作和第21次CSP认证的第四题作用类似. #include<cstdio> #include<vector> #in ...

  5. Windows服务器,通过Nginx部署VUE+Django前后端分离项目

    目录 基本说明 安装 Nginx 部署 VUE 前端 部署 Django 后端 Django admin 静态文件(CSS,JS等)丢失的问题 1. 基本说明 本文介绍了在 windows 服务器下, ...

  6. lua完整学习笔记

    lua注释 -- 单行注释 --[[ 多行注释 ]]-- lua数据结构 nil          无效值与Java的Null类似,但是在条件表示中是false boolean      布尔值,tu ...

  7. [cnn][julia]Flux实现卷积神经网络cnn预测手写MNIST

    julia_Flux 1.导入Flux.jl和其他所需工具包 using Flux, MLDatasets, Statistics using Flux: onehotbatch, onecold, ...

  8. Head First Java学习:第八章-接口和抽象类

    第八章:接口和抽象类 深入多态 1.抽象类:有些类不应该被初始化 在类声明前面加上抽象类的关键字,abstract. 防止类被初始化,即不能被"new"创建该类的实例(要求) 还是 ...

  9. 10、goto语句

    1.goto语句的概念 goto语句:可以无条件的转移到运行中指定的行 这个用的比较少,了解一下即可 2.语法结构和用法 /** * @author ly (个人博客:https://www.cnbl ...

  10. MybatisPlus查询时过滤不需要的字段~

    解释一下:乍一看标题可能有点懵~,其实就是想查询的时候过滤掉某些字段 例如: select name,email,password from user; --改为-> select name,e ...