• 原创 微信公众号推送图片实现


    1绑定微信事件

    @RestController
    @RequestMapping(value = "/api/wechat")
    @Api(value = "【微信相关接口】")
    public class ApiWeChatController {
    private static Logger logger = LoggerFactory.getLogger(ApiWeChatController.class);
    private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    @RequestMapping(value = "/checkSignature", produces = "text/html; charset=utf-8")
    public String handlewechatPush(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	boolean isGet = request.getMethod().equalsIgnoreCase("get");
    	if (isGet) {
    		// 微信加密签名
    		String signature = request.getParameter("signature");
    		// 随机字符串
    		String echostr = request.getParameter("echostr");
    		// 时间戳
    		String timestamp = request.getParameter("timestamp");
    		// 随机数
    		String nonce = request.getParameter("nonce");
    		logger.info("wx_check_signstrs:{},{},{},{}", signature, echostr, timestamp, nonce);
    		String[] str = { JsdConstants.WX_CHECKSIGN_TOKEN, timestamp, nonce };
    		Arrays.sort(str); // 字典序排序
    		String bigStr = str[0] + str[1] + str[2];
    		// SHA1加密,我这里用的是common-codec的jar包,你们也可以用java自带的消息消息摘要来写,只不过要多写几行代码,但结果都一样的
    		String digest = DigestUtils.sha1Hex(bigStr);
    		// 确认请求来至微信
    		if (digest.equals(signature)) {
    			return echostr;
    		}
    		return "";
    	} else {
    		// 处理接收消息
    		logger.info("Wechat event comes");
    		return handleWechatPushMessage(request, response);
    	}
    }
    
    
    private String handleWechatPushMessage(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	WechatEventMessage eventMessage = dom4jXMLParse(request.getInputStream());
    
    	WechatMessageType msgType = null;
    	try {
    		msgType = WechatMessageType.valueOf(eventMessage.getMsgType().toUpperCase());
    	} catch (Exception e) {
    		logger.error("cannot resolve the wechat event type: {}", eventMessage.getMsgType(), e);
    	}
    	if (msgType == WechatMessageType.EVENT) {
    		// 处理事件
    		String event = eventMessage.getEvent().toUpperCase();
    		switch (event) {
    		case "CLICK": // 点击事件
    			return wechatClickEventHandler.handle(request, response, eventMessage);
    		case "SUBSCRIBE": // 关注
    			return wechatSubscribeEventHandler.handle(request, response, eventMessage);
    		case "UNSUBSCRIBE": // 取消关注
    			return wechatUnsubscribeEventHandler.handle(request, response, eventMessage);
    		case "SCAN": // 扫码
    			return wechatScanEventHandler.handle(request, response, eventMessage);
    		case "VIEW": // 菜单跳转
    			return JsdConstants.SUCCESS;
    		case "LOCATION": // 位置
    			return JsdConstants.SUCCESS;
    		default:
    			return JsdConstants.SUCCESS;
    		}
    	} else if (msgType == WechatMessageType.TEXT) {
    		return wechatTextAutoHandler.handle(request, response, eventMessage);
    	}
    	return JsdConstants.SUCCESS;
    }
    
    private static String encode(String str) {
    	if (str == null) {
    		return null;
    	}
    	try {
    		MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
    		messageDigest.update(str.getBytes());
    		return getFormattedText(messageDigest.digest());
    	} catch (Exception e) {
    		throw new RuntimeException(e);
    	}
    }
    
    private static String getFormattedText(byte[] bytes) {
    	int len = bytes.length;
    	StringBuilder buf = new StringBuilder(len * 2);
    	// 把密文转换成十六进制的字符串形式
    	for (int j = 0; j < len; j++) {
    		buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
    		buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
    	}
    	return buf.toString();
    }
    }
    

    2点击事件处理器
    @Service
    public class WechatClickEventHandler {
    private static Logger logger = LoggerFactory.getLogger(WechatClickEventHandler.class);
    private ExecutorService pool = Executors.newFixedThreadPool(10);

    @Autowired
    UmsUserMapper userMapper;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    WeiXinUtil weiXinUtil;
    @Autowired
    APIUserService apiUserService;
    @Autowired
    PictureUtil pictureUtil;
    
    
    public String handle(HttpServletRequest request, HttpServletResponse response, WechatEventMessage eventMessage) throws Exception {
    	String eventKey = eventMessage.getEventKey();
    	switch(eventKey){
    	case "DEEP_SAY": // 大道至简
    		pool.execute(new Runnable() {
    			@Override
    			public void run() {
    				try {
    					toSignIn(eventMessage.getFromUserName(), null);
    				} catch (Exception e) {
    					logger.error("toSignIn.error", e);
    				}
    			}
    		});
    		break;
    	}
    		
    	return JsdConstants.SUCCESS;
    }
    
    public String toSignIn(String openid, String info) throws Exception {
    	logger.info("跳转到生成图片[openid]: {}", openid);
    	long nowtime = System.currentTimeMillis();
    	// 获取日期
    	String dateStr = DateFormatUtils.format(nowtime, JsdConstants.YMD2);
    	// 获取用户信息
    	Map<String, Object> param = new HashMap<>();
    	param.put("openid", openid);
    	param.put("subscribe", 1);
    	List<UmsUser> users = userMapper.selectBySelective(param);
    	if (users.isEmpty()) {
    		return JsdConstants.SUCCESS;
    	}
    	String imageTime = redisUtil.getHashKey("times", "image").toString();
    	String time = redisUtil.getHashKey("imageTimes", openid + dateStr);
    	if (time == null) {
    		redisUtil.put("musicTimes", openid + dateStr, "0");
    	} else if (Integer.parseInt(time) >= Integer.parseInt(imageTime)) {
    		weiXinUtil.sendText(openid, "今日已达获取上限");
    		return JsdConstants.SUCCESS;
    	}
    	UmsUser user = users.get(0);
    	long userId = user.getId();
    	// 当天底片
    	String baseUrl = JsdConstants.FILE_PATH + "/user/base/" + dateStr + ".png";
    	// 判断当天是否已有底片
    	File todayBase = new File(baseUrl);
    	if (!todayBase.exists()) {
    		String backUrl = redisUtil.getHashKey("imagebackurl", dateStr); // 获取今日背景图
    		if (backUrl == null) {
    			backUrl = JsdConstants.FILE_PATH + "/back/zhujian.png";
    		}
    		String festival = redisUtil.getHashKey("festivals", dateStr);
    		if (festival == null) {
    			festival = "";
    		}
    		String weekday = DateFormatUtils.format(nowtime, JsdConstants.YMD) + " " + CommonUtils.timeToWeek(nowtime) + " " + festival;
    		String solarTerm = redisUtil.getHashKey("solarTerms", dateStr);
    		if (solarTerm == null) {
    			solarTerm = "";
    		}
    		String lunar = LunarUtil.getLunarString() + " " + solarTerm;
    		logger.info("开始生成今日底片: {}", dateStr);
    		pictureUtil.overlapImage1(JsdConstants.FILE_PATH + "/basic/kb3.png", backUrl, weekday, lunar, baseUrl);
    	}
    	String txUrl = JsdConstants.FILE_PATH + "/basic/circle.jpg"; // 默认头像图片
    	// 头像可做缓存有效期
    	byte[] btImg = GetImageUtil.getImageFromNetByUrl(user.getHeadimgurl());  
    	if (null != btImg && btImg.length > 100) {
    		txUrl = JsdConstants.FILE_PATH + "/user/headimg/" + userId + ".jpg";
    		GetImageUtil.writeImageToDisk(btImg, txUrl);  
    	}
    	// 需要存储到服务器
    	String qrcodeUrl = JsdConstants.FILE_PATH + "/user/qrcode/" + userId + ".jpg";
    	File qrcodeImg = new File(qrcodeUrl);
    	if (!qrcodeImg.exists()) { // 未获取到用户专属二维码
    		qrcodeUrl = JsdConstants.FILE_PATH + "/basic/jsd.jpg";
    	}
    	if (info == null) {
    		info = redisUtil.getHashKey("wordInfos", dateStr);
    		if (info == null) {
    			info = redisUtil.getHashKey("wordInfos", JsdConstants.MAIN_OPENID);
    		}
    	}
    	if (info.length() > 200) {
    		info = info.substring(0, 200);
    	}
    	logger.info("开始生成用户专属图片 ");
    	String sendUrl = JsdConstants.FILE_PATH + "/user/image/" + dateStr + userId + ".png";
    	pictureUtil.overlapImage2(baseUrl, qrcodeUrl, JsdConstants.FILE_PATH + "/basic/xk52.jpg", txUrl, sendUrl, info);
    	JSONObject res = weiXinUtil.uploadFile(sendUrl, dateStr + userId + ".png", "image");
    	if(res != null){
    		JSONObject sendRs = weiXinUtil.sendImage(openid, res.getString("media_id"));
    		if (sendRs.getInt("errcode") != 0) { // 客服消息发送失败
    			weiXinUtil.sendText(JsdConstants.MAIN_OPENID, "客户图片发送失败");
    		} else {
    			redisUtil.increment("imageTimes", openid + dateStr, 1);
    		}
    	}
    	return "SUCCESS";	
    }
    }
    

    简单的实现完成

    化繁为简,极致高效。 所有代码为本人原创,转载请联系本人。
  • 相关阅读:
    FastJson序列化枚举类
    优雅计时StopWatch
    spark算子之aggregateByKey
    scala系列列表
    iOS开发证书不受信任
    .NET Core 中的鉴权授权正确方式
    设置双击直接打开.ipynb文件
    Ubuntu18添加开机启动项
    iOS ObjectC 笔记(二)GCD
    iOS VideoToolBox decoder解码失败(12909和12911)问题解决(二)
  • 原文地址:https://www.cnblogs.com/crissblog/p/14861502.html
Copyright © 2020-2023  润新知