一、依赖
https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-miniapp
<dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-miniapp</artifactId> <version>4.3.0</version> </dependency>
二、配置
application.yml
wx: miniapp: configs: - appid: #微信小程序的appid secret: #微信小程序的Secret token: #微信小程序消息服务器配置的token aesKey: #微信小程序消息服务器配置的EncodingAESKey msgDataFormat: JSON
package com.github.binarywang.demo.wx.miniapp.config; 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.config.impl.WxMaRedisConfigImpl; import cn.binarywang.wx.miniapp.message.WxMaMessageHandler; import cn.binarywang.wx.miniapp.message.WxMaMessageRouter; import com.google.common.collect.Lists; 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.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 redis.clients.jedis.JedisPool; import java.io.File; import java.util.List; import java.util.stream.Collectors; /** * @author <a href="https://github.com/binarywang">Binary Wang</a> */ @Slf4j @Configuration @EnableConfigurationProperties(WxMaProperties.class) public class WxMaConfiguration { private final WxMaProperties properties; @Autowired public WxMaConfiguration(WxMaProperties properties) { this.properties = properties; } @Bean public WxMaService wxMaService() { List<WxMaProperties.Config> configs = this.properties.getConfigs(); if (configs == null) { throw new WxRuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!"); } WxMaService maService = new WxMaServiceImpl(); maService.setMultiConfigs( 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()); return config; }).collect(Collectors.toMap(WxMaDefaultConfigImpl::getAppid, a -> a, (o, n) -> o))); return maService; } @Bean public WxMaMessageRouter wxMaMessageRouter(WxMaService wxMaService) { final WxMaMessageRouter router = new WxMaMessageRouter(wxMaService); 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; }; }
package com.github.binarywang.demo.wx.miniapp.config; import java.util.List; import org.springframework.boot.context.properties.ConfigurationProperties; import lombok.Data; /** * @author <a href="https://github.com/binarywang">Binary Wang</a> */ @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; } }
三、使用
package com.github.binarywang.demo.wx.miniapp.controller; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.constant.WxMaConstants; import cn.binarywang.wx.miniapp.util.WxMaConfigHolder; import com.google.common.collect.Lists; import com.google.common.io.Files; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import me.chanjar.weixin.common.error.WxErrorException; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.List; /** * <pre> * 小程序临时素材接口 * Created by BinaryWang on 2017/6/16. * </pre> * * @author <a href="https://github.com/binarywang">Binary Wang</a> */ @RestController @AllArgsConstructor @Slf4j @RequestMapping("/wx/media/{appid}") public class WxMaMediaController { private final WxMaService wxMaService; /** * 上传临时素材 * * @return 素材的media_id列表,实际上如果有的话,只会有一个 */ @PostMapping("/upload") public List<String> uploadMedia(@PathVariable String appid, HttpServletRequest request) throws WxErrorException { if (!wxMaService.switchover(appid)) { throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); } CommonsMultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext()); if (!resolver.isMultipart(request)) { WxMaConfigHolder.remove();//清理ThreadLocal return Lists.newArrayList(); } MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; Iterator<String> it = multiRequest.getFileNames(); List<String> result = Lists.newArrayList(); while (it.hasNext()) { try { MultipartFile file = multiRequest.getFile(it.next()); File newFile = new File(Files.createTempDir(), file.getOriginalFilename()); log.info("filePath is :" + newFile.toString()); file.transferTo(newFile); WxMediaUploadResult uploadResult = wxMaService.getMediaService().uploadMedia(WxMaConstants.KefuMsgType.IMAGE, newFile); log.info("media_id : " + uploadResult.getMediaId()); result.add(uploadResult.getMediaId()); } catch (IOException e) { log.error(e.getMessage(), e); } } WxMaConfigHolder.remove();//清理ThreadLocal return result; } /** * 下载临时素材 */ @GetMapping("/download/{mediaId}") public File getMedia(@PathVariable String appid, @PathVariable String mediaId) throws WxErrorException { if (!wxMaService.switchover(appid)) { throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); } File media = wxMaService.getMediaService().getMedia(mediaId); WxMaConfigHolder.remove();//清理ThreadLocal return media; } }
注意事项:配置小程序appid等正确,WxMaConfiguration可以被启动了扫描;