SpringBoot集成微信小程序
- 前言
- 一、前置工作
- 1、获取appId和appSecret核心参数
- 二、SpringBoot集成微信小程序
- 1、引入pom依赖
- 2、yml配置
- 3、java代码文件
- 3.1、Properties 配置类
- 3.2 Configuration 服务类
- 4、使用示例
- 4.1、获取登录后的session信息:openId
- 4.2、获取当前用户手机号
- 5、更多接口使用请参考
前言
本文内容参考于“binarywang”,感谢大佬的开源
源码参考:https://github.com/Wechat-Group/WxJava
demo参考:https://github.com/binarywang/weixin-java-miniapp-demo
一、前置工作
1、获取appId和appSecret核心参数
二、SpringBoot集成微信小程序
1、引入pom依赖
<!-- 小程序依赖 -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-common</artifactId>
<version>4.3.0</version>
</dependency>
<!--<dependency>-->
<!--<groupId>commons-fileupload</groupId>-->
<!--<artifactId>commons-fileupload</artifactId>-->
<!--</dependency>-->
<!--emoji处理-->
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>5.1.1</version>
</dependency>
2、yml配置
wx:
miniapp:
configs:
- appid: wxa3760c4bd118deb3
secret: e426f8e0b6c692c8e8410708ae114e9c
token: #微信小程序消息服务器配置的token
aesKey: #微信小程序消息服务器配置的EncodingAESKey
msgDataFormat: JSON
3、java代码文件
3.1、Properties 配置类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* @author tm
* date 2023/5/15
* @version 1.0
*/
@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxMaProperties {
private List<Config> configs;
@Data
public static class Config {
/**
* 设置微信小程序的appid
*/
private String appid;
/**
* 设置微信小程序的Secret
*/
private String secret;
/**
* 设置微信小程序消息服务器配置的token
*/
private String token;
/**
* 设置微信小程序消息服务器配置的EncodingAESKey
*/
private String aesKey;
/**
* 消息格式,XML或者JSON
*/
private String msgDataFormat;
}
}
3.2 Configuration 服务类
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import org.jeecg.modules.fag.properties.WxMaProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author tm
* date 2023/5/15
* @version 1.0
*/
@Slf4j
@Configuration
@EnableConfigurationProperties(WxMaProperties.class)
public class WxMaConfiguration {
private final WxMaProperties properties;
private static final Map<String, WxMaMessageRouter> routers = Maps.newHashMap();
private static Map<String, WxMaService> maServices;
@Autowired
public WxMaConfiguration(WxMaProperties properties) {
this.properties = properties;
}
@Bean
public WxMaService defaultWxMaService() {
return WxMaConfiguration.getMaService();
}
public static WxMaService getMaService() {
String appId = null;
for (String appIdKey : maServices.keySet()) {
appId = appIdKey;
}
return getMaService(appId);
}
public static WxMaService getMaService(String appid) {
WxMaService wxService = maServices.get(appid);
if (wxService == null) {
throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
}
return wxService;
}
public static WxMaMessageRouter getRouter(String appid) {
return routers.get(appid);
}
@PostConstruct
public void init() {
List<WxMaProperties.Config> configs = this.properties.getConfigs();
if (configs == null) {
throw new WxRuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
}
maServices = configs.stream()
.map(a -> {
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
// WxMaDefaultConfigImpl config = new WxMaRedisConfigImpl(new JedisPool());
// 使用上面的配置时,需要同时引入jedis-lock的依赖,否则会报类无法找到的异常
config.setAppid(a.getAppid());
config.setSecret(a.getSecret());
config.setToken(a.getToken());
config.setAesKey(a.getAesKey());
config.setMsgDataFormat(a.getMsgDataFormat());
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(config);
routers.put(a.getAppid(), this.newRouter(service));
return service;
}).collect(Collectors.toMap(s -> s.getWxMaConfig().getAppid(), a -> a));
}
private WxMaMessageRouter newRouter(WxMaService service) {
final WxMaMessageRouter router = new WxMaMessageRouter(service);
router
.rule().handler(logHandler).next()
.rule().async(false).content("订阅消息").handler(subscribeMsgHandler).end()
.rule().async(false).content("文本").handler(textHandler).end()
.rule().async(false).content("图片").handler(picHandler).end()
.rule().async(false).content("二维码").handler(qrcodeHandler).end();
return router;
}
private final WxMaMessageHandler subscribeMsgHandler = (wxMessage, context, service, sessionManager) -> {
service.getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
.templateId("此处更换为自己的模板id")
.data(Lists.newArrayList(
new WxMaSubscribeMessage.MsgData("keyword1", "339208499")))
.toUser(wxMessage.getFromUser())
.build());
return null;
};
private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {
log.info("收到消息:" + wxMessage.toString());
service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
.toUser(wxMessage.getFromUser()).build());
return null;
};
private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {
service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
.toUser(wxMessage.getFromUser()).build());
return null;
};
private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {
try {
WxMediaUploadResult uploadResult = service.getMediaService()
.uploadMedia("image", "png",
ClassLoader.getSystemResourceAsStream("tmp.png"));
service.getMsgService().sendKefuMsg(
WxMaKefuMessage
.newImageBuilder()
.mediaId(uploadResult.getMediaId())
.toUser(wxMessage.getFromUser())
.build());
} catch (WxErrorException e) {
e.printStackTrace();
}
return null;
};
private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {
try {
final File file = service.getQrcodeService().createQrcode("123", 430);
WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
service.getMsgService().sendKefuMsg(
WxMaKefuMessage
.newImageBuilder()
.mediaId(uploadResult.getMediaId())
.toUser(wxMessage.getFromUser())
.build());
} catch (WxErrorException e) {
e.printStackTrace();
}
return null;
};
}
4、使用示例
4.1、获取登录后的session信息:openId
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.fag.configuration.WxMaConfiguration;
import org.springframework.stereotype.Service;
/**
* Author: tm
* Version: 1.0
*/
@Slf4j
@Service
public class TestServiceImpl {
public Result login(String code) {
final WxMaService wxService = WxMaConfiguration.getMaService();
try {
WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
if (session == null) {
return Result.error("获取小程序用户失败");
}
log.info(session.getSessionKey());
log.info(session.getOpenid());
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error(e.getLocalizedMessage());
}
}
}
4.2、获取当前用户手机号
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.fag.configuration.WxMaConfiguration;
import org.springframework.stereotype.Service;
import javax.validation.constraints.NotEmpty;
/**
* Author: tm
* Version: 1.0
*/
@Slf4j
@Service
public class TestServiceImpl {
public Result userPhone(@NotEmpty(message = "code不能为空") String code) {
final WxMaService wxService = WxMaConfiguration.getMaService();
try {
WxMaPhoneNumberInfo newPhoneNoInfo = wxService.getUserService().getNewPhoneNoInfo(code);
if (newPhoneNoInfo == null) {
return Result.error("获取手机号失败");
}
log.info("请求结果:{}", newPhoneNoInfo);
String phoneNumber = newPhoneNoInfo.getPhoneNumber();
return Result.ok("获取手机号成功", phoneNumber);
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error(e.getLocalizedMessage());
}
}
}
5、更多接口使用请参考
cn.binarywang.wx.miniapp.api.WxMaService