欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)公眾號(hào)功能、關(guān)注及消息推送實(shí)例代碼

 更新時(shí)間:2023年11月25日 15:07:39   作者:夕四丶  
公眾號(hào)開(kāi)發(fā)近些年是一個(gè)比較熱門(mén)的方向,下面這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)公眾號(hào)功能、關(guān)注及消息推送的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

描述

 使用Java實(shí)現(xiàn)公眾號(hào)功能的接入,配合業(yè)務(wù)實(shí)現(xiàn):

     用戶關(guān)注、取消關(guān)注、推送數(shù)據(jù)服務(wù)、用戶在公眾號(hào)信息轉(zhuǎn)發(fā)人工服務(wù)等功能

     本文章說(shuō)明公眾號(hào)代碼配置實(shí)現(xiàn),公眾號(hào)申請(qǐng),注冊(cè)方式,自行查看官網(wǎng)說(shuō)明

引入依賴(lài)

		<!--微信公眾號(hào)(包括訂閱號(hào)和服務(wù)號(hào))-->
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-mp</artifactId>
            <version>4.4.2.B</version>
        </dependency>

注冊(cè)公眾號(hào)配置

@Slf4j
@Configuration
@RequiredArgsConstructor
@ConditionalOnClass(WxMpService.class)
@EnableConfigurationProperties()
public class WxMpConfiguration {
    private final MpConfigMapper mpConfigMapper;
    private final LogHandler logHandler;
    private final SubscribeHandler subscribeHandler;
    private final UnsubscribeHandler unsubscribeHandler;
    private final TextMsgHandler textMsgHandler;

    /**
     * 用戶配置(獲取用戶客戶代碼)
     */
    private static Map<String, Integer> MP_USER_CONF = new HashMap<>();

    public static Long getCustomId(String appid) {
        return Long.valueOf(MP_USER_CONF.getOrDefault(appid, 0));
    }

    /**
     * 加載公眾號(hào)配置,注冊(cè)Bean對(duì)象
     */
	@Bean
    public WxMpService wxMpService() {
    	//這個(gè)是數(shù)據(jù)庫(kù)公眾號(hào)信息配置表
        List<MpConfig> mpConfigs = mpConfigMapper.selectList(Wrappers.emptyWrapper());
        if (CollectionUtil.isEmpty(mpConfigs)) {
            log.error("讀取配置為空,公眾號(hào)配置類(lèi)加載失??!");
            return new WxMpServiceImpl();
        }
        log.info("公眾號(hào)的配置:{}", JSON.toJSONString(mpConfigs));
        Map<String, WxMpConfigStorage> multiConfigStorages = new HashMap<>(16);
        for (MpConfig mpConfig : mpConfigs) {
            WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
            configStorage.setAppId(mpConfig.getAppid());
            configStorage.setSecret(mpConfig.getSecret());
            configStorage.setToken(mpConfig.getToken());
            configStorage.setAesKey(mpConfig.getAeskey());
            multiConfigStorages.put(mpConfig.getCustomerCode(), configStorage);
            MP_USER_CONF.put(mpConfig.getAppid(), mpConfig.getCustomerId());
        }
        WxMpService mpService = new WxMpServiceImpl();
        mpService.setMultiConfigStorages(multiConfigStorages);
        return mpService;
    }
    
     /**
     * 配置公眾號(hào)個(gè)事件路由,分類(lèi)處理:關(guān)注、取消關(guān)注、用戶發(fā)送消息
     */
    @Bean
    public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
        final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
        // 記錄所有事件的日志 (異步執(zhí)行)
        newRouter.rule().handler(this.logHandler).next();
        // 關(guān)注事件
        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).
                event(WxConsts.EventType.SUBSCRIBE).handler(this.subscribeHandler).end();
        //取消關(guān)注事件
        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).
 event(WxConsts.EventType.UNSUBSCRIBE).handler(this.unsubscribeHandler).end();
 		//用戶往公眾號(hào)發(fā)送消息事件處理
        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.TEXT).
                handler(this.textMsgHandler).end();
        return newRouter;
    }
 }

公眾號(hào)各事件處理

實(shí)現(xiàn)公眾號(hào)事件處理類(lèi)

/**
 * 微信公眾號(hào)AbstractHandler
 */
public abstract class AbstractHandler implements WxMpMessageHandler {
    protected Logger logger = LoggerFactory.getLogger(getClass());
}

實(shí)現(xiàn)公眾號(hào)日志記錄處理器

/**
 * 微信公眾號(hào)日志記錄處理器
 */
@Component
public class LogHandler extends AbstractHandler {
    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
                                    Map<String, Object> context, WxMpService wxMpService,
                                    WxSessionManager sessionManager) {
        this.logger.info("【公眾號(hào)】-記錄請(qǐng)求日志,內(nèi)容:{}", JSON.toJSONString(wxMessage));
        return null;
    }
}

實(shí)現(xiàn)公眾號(hào)用戶關(guān)注處理器

/**
 * 微信公眾號(hào)用戶關(guān)注
 */
@Component
@RequiredArgsConstructor
public class SubscribeHandler extends AbstractHandler {
	//公眾號(hào)用戶表
    private final MpUserParentMapper mpUserParentMapper;
    //小程序用戶表(一般公眾號(hào)和小程序配套使用)
    private final MiniappUserParentMapper miniappUserParentMapper;
    //公眾號(hào)配置表
    private final MpConfigMapper mpConfigMapper;

	@Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
                                    Map<String, Object> context, WxMpService wxMpService,
                                    WxSessionManager sessionManager) throws WxErrorException {

        this.logger.info("【公眾號(hào)-關(guān)注功能】-新關(guān)注用戶 OPENID: " + wxMessage.getFromUser());

        // 獲取微信用戶基本信息
        try {
            WxMpUser userWxInfo = wxMpService.getUserService()
                    .userInfo(wxMessage.getFromUser(), null);
            String appId = wxMpService.getWxMpConfigStorage().getAppId();
            Long customerId = WxMpConfiguration.getCustomId(appId);
            logger.info("userWxInfo:{}", userWxInfo);
            if (userWxInfo != null) {
            	//查詢(xún)數(shù)據(jù)庫(kù),公眾號(hào)用戶表,是否有這個(gè)用戶
                MpUserParent existMpUser = mpUserParentMapper.selectOneByOpenId(userWxInfo.getOpenId());
                //不存在則新增一條公眾號(hào)用戶記錄
                if (existMpUser == null) {
                    MpUserParent mpUser = new MpUserParent();
                    mpUser.setOpenId(userWxInfo.getOpenId());
                    mpUser.setUnionId(userWxInfo.getUnionId());
                    mpUser.setAvatarUrl(userWxInfo.getHeadImgUrl());
                    mpUser.setNickName(userWxInfo.getNickname());
                    mpUser.setCustomerId(customerId);
                    mpUserParentMapper.insert(mpUser);
                    //檢測(cè)是否有跟小程序賬號(hào)關(guān)聯(lián)
                    MiniappUserParent maUserParent = miniappUserParentMapper.selectOneByUnionId(mpUser.getUnionId(), customerId);
                    if (maUserParent != null && StringUtil.isBlank(maUserParent.getMpOpenId())) {
                        maUserParent.setMpOpenId(mpUser.getOpenId());
                        maUserParent.setUpdateTime(new Date());
                        miniappUserParentMapper.updateById(maUserParent);
                        this.logger.info("【公眾號(hào)-關(guān)注功能】-公眾號(hào)賬號(hào)和小程序綁定成功!unionId:{},mpOpenId:{} ", mpUser.getUnionId(), mpUser.getOpenId());
                    }
                } else {
                    //之前有關(guān)注過(guò)的,無(wú)需重復(fù)寫(xiě)入,更改關(guān)注狀態(tài)即可
                    MpUserParent updateUser = new MpUserParent();
                    updateUser.setMpId(existMpUser.getMpId());
                    updateUser.setFollowStatus(1);
                    updateUser.setUpdateTime(new Date());
                    updateUser.setCustomerId(customerId);
                    updateUser.setUnionId(userWxInfo.getUnionId());
                    mpUserParentMapper.updateById(updateUser);
                }
			}
        } catch (WxErrorException e) {
            if (e.getError().getErrorCode() == 48001) {
                this.logger.error("【公眾號(hào)-關(guān)注功能】-該公眾號(hào)沒(méi)有獲取用戶信息權(quán)限!");
            }
            logger.error("【公眾號(hào)-關(guān)注功能異常】-異常信息:{}", e);
        }
		WxMpXmlOutMessage responseResult = null;
        try {
            responseResult = this.handleSpecial(wxMessage);
        } catch (Exception e) {
            this.logger.error(e.getMessage(), e);
        }
        if (responseResult != null) {
            return responseResult;
        }
        String appId = wxMpService.getWxMpConfigStorage().getAppId();
        try {
            logger.info("獲取公眾號(hào)appid:{}", appId);
            MpConfig miniappConfig = mpConfigMapper.selectByAppid(appId);
            //關(guān)注公眾號(hào),發(fā)送消息給用戶
            return new TextBuilder().build("感謝關(guān)注,將持續(xù)為您推送信息", wxMessage, wxMpService);
        } catch (Exception e) {
            this.logger.error(e.getMessage(), e);
        }
		return null;
    }
    
    /**
     * 處理特殊請(qǐng)求,比如如果是掃碼進(jìn)來(lái)的,可以做相應(yīng)處理
     */
    private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage) throws Exception {
        //TODO
        return null;
    }
}

實(shí)現(xiàn)公眾號(hào)用戶取消關(guān)注處理器

/**
 * 微信公眾號(hào)用戶取消關(guān)注
 */
@Component
@RequiredArgsConstructor
public class UnsubscribeHandler extends AbstractHandler {
    private final MpUserParentMapper mpUserParentMapper;
    private final MpConfigMapper mpConfigMapper;
	@Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
                                    Map<String, Object> context, WxMpService wxMpService,
                                    WxSessionManager sessionManager) {
        String openId = wxMessage.getFromUser();
        this.logger.info("取消關(guān)注用戶 OPENID: " + openId);
        //更新關(guān)注狀態(tài)為取消關(guān)注狀態(tài)
        UpdateWrapper<MpUserParent> updateWrapper = new UpdateWrapper();
        updateWrapper.eq("openId", openId);
        updateWrapper.eq("followStatus", 1);
        MpUserParent updateMpUser = new MpUserParent();
        updateMpUser.setFollowStatus(2);
        //不刪除公眾號(hào)用戶信息,修改關(guān)注狀態(tài)值即可
        mpUserParentMapper.update(updateMpUser, updateWrapper);
        String appId = wxMpService.getWxMpConfigStorage().getAppId();
        logger.info("獲取公眾號(hào)appid:{}",appId);
        MpConfig miniappConfig = mpConfigMapper.selectByAppid(appId);
        //取消關(guān)注,發(fā)送信息給用戶
        return new TextBuilder().build("已退訂", wxMessage, wxMpService);
    }
}

實(shí)現(xiàn)公眾號(hào)用戶發(fā)送消息處理器

@Slf4j
@Component
@RequiredArgsConstructor
public class TextMsgHandler extends AbstractHandler {

    private final static Integer TEXT_TYPE = 1;
    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {
        String content = wxMessage.getContent();
        log.info("【公眾號(hào)-消息】-用戶:{} , 發(fā)送消息:{}, ", wxMessage.getFromUser(), content);
        // 獲取微信用戶基本信息
        try {
            String appId = wxMpService.getWxMpConfigStorage().getAppId();
            Long customerId = WxMpConfiguration.getCustomId(appId);
            //自動(dòng)回復(fù)匹配的關(guān)鍵字
            MpAutoReplyDTO autoReply = InitConfDataUtil.getAutoReply(customerId, content);
            if (autoReply != null) {
                Integer replyType = autoReply.getReplyType();
                String reply = autoReply.getReply();
                if (TEXT_TYPE.equals(replyType)) {
                	//文字處理
                    return new TextBuilder().build(reply, wxMessage, wxMpService);
                } else {
                	//圖片處理
                    return new ImageBuilder().build(reply, wxMessage, wxMpService);
                }
            } else {
                //自動(dòng)回復(fù)沒(méi)有匹配的就轉(zhuǎn)到人工
                WxMpXmlOutMessage build = new TextBuilder().build(wxMessage.getContent(), wxMessage, wxMpService);
                //msgType設(shè)置固定值就轉(zhuǎn)到人工:transfer_customer_service
                build.setMsgType("transfer_customer_service");
                return build;
            }
        } catch (Exception e) {
            log.info("回復(fù)失敗e:{}", e);
        }
        return null;
    }
}

用戶消息事件分類(lèi)處理Builder

定義處理抽象類(lèi)

//該類(lèi)定義處理標(biāo)準(zhǔn),后續(xù)根據(jù)業(yè)務(wù)自行擴(kuò)展
public abstract class AbstractBuilder {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    public abstract WxMpXmlOutMessage build(String content,
                                            WxMpXmlMessage wxMessage, WxMpService service);
}

實(shí)現(xiàn)處理抽象類(lèi)–子類(lèi)–文本消息

public class TextBuilder extends AbstractBuilder {
    @Override
    public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
                                   WxMpService service) {
        return WxMpXmlOutMessage.TEXT().content(content)
                .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
                .build();
    }
}

實(shí)現(xiàn)處理抽象類(lèi)–子類(lèi)–圖片消息

public class ImageBuilder extends AbstractBuilder {
    @Override
    public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
                                   WxMpService service) {
        return WxMpXmlOutMessage.IMAGE().mediaId(content)
                .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
                .build();
    }
}

公眾號(hào)模板消息推送

以上實(shí)現(xiàn)了Java整合公眾號(hào),后續(xù)業(yè)務(wù)擴(kuò)展,需要往關(guān)注公眾號(hào)的用戶進(jìn)行相關(guān)的消息推送,消息推送前,

需要在微信公眾號(hào)申請(qǐng)推送模板,拿到對(duì)應(yīng)的模板ID,這個(gè)有用,生成推送消息時(shí),需要往模板填充信息,

如何申請(qǐng)公眾號(hào)模板,自行參考下官網(wǎng)說(shuō)明

/**
 * 微信公眾號(hào)信息推送
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class MpMsgPush {
	//微信的公眾號(hào)推送處理類(lèi)
    private final WxMpService wxMpAgentService;
    //數(shù)據(jù)庫(kù)公眾號(hào)模板消息表
    private final MpTemplateManage mpTemplateManage;

 	/**
     * 發(fā)送微信模板信息
     *
     * @param mpPushDTO 推送信息實(shí)體類(lèi)
     * @return 是否推送成功
     */
    @Async
    public Boolean sendTemplateMsg(MpPushDTO mpPushDTO) {
        log.info("【公眾號(hào)告警模板信息推送】-推送信息:{}", JSONObject.toJSONString(mpPushDTO));
        Long customerId = mpPushDTO.getCustomerId();
        String name = mpPushDTO.getMpName();
        //選擇往哪個(gè)公眾號(hào)發(fā)送模板消息,這個(gè)上面注冊(cè)公眾號(hào)的Bean的時(shí)候已經(jīng)注入
        WxMpService wxMpService = wxMpAgentService.switchoverTo(mpPushDTO.getCustomerCode());
        //自己搞的一個(gè)枚舉,根據(jù)當(dāng)前的消息實(shí)體類(lèi)信息,來(lái)判斷使用哪個(gè)模板ID
        String templateId = TemplateConfConstant.getWXTemplateConf(customerId, mpPushTypeEnum.getValue());
        // 獲取模板消息接口
        WxMpTemplateMessage templateMessage = mpTemplateManage.getWarnTemplate(mpPushDTO, templateId, name);
        if (templateMessage != null) {
            log.info("發(fā)送消息:{}", JSONObject.toJSONString(templateMessage));
        } else {
            log.error("獲取消息模板為空!");
            return false;
        }
        String msgId = null;
        try {
            Long parentId = mpPushDTO.getParentId();
            String imeiNo = mpPushDTO.getImeiNo();
            // 發(fā)送模板消息
            msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
        } catch (Exception e) {
            log.error("【公眾號(hào)模板信息推送】-推送失敗,異常信息:", e);
        }
        log.warn("·==++--·推送公眾號(hào)模板信息:{}·--++==·", msgId != null ? "成功" : "失敗");
        return msgId != null;
    }
    
	/**
     * 獲取提醒模板
     *
     * @param mpPushDTO
     * @return
     */
    public WxMpTemplateMessage getWarnTemplate(MpPushDTO mpPushDTO, String templateId, String name) {
        // 發(fā)送模板消息接口
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                // 接收者openid
                .toUser(mpPushDTO.getOpenId())
                // 模板id
                .templateId(templateId)
                .build();
        StringBuilder keyword1 = new StringBuilder();
        keyword1.append(mpPushDTO.getStudentName()).
                append("(").append(mpPushDTO.getImeiNo()).append(")");
        // 添加模板數(shù)據(jù)
        templateMessage.addData(new WxMpTemplateData("first", "您好,你有一條新的提醒"))
                .addData(new WxMpTemplateData("keyword1", keyword1.toString()))
                .addData(new WxMpTemplateData("keyword2", mpPushDTO.getTemplateType()))
                .addData(new WxMpTemplateData("remark", name + "智能推送系統(tǒng)"));
        return templateMessage;
    }


}

總結(jié) 

到此這篇關(guān)于Java實(shí)現(xiàn)公眾號(hào)功能、關(guān)注及消息推送的文章就介紹到這了,更多相關(guān)Java公眾號(hào)關(guān)注、消息推送內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于TCP通信丟包原因總結(jié)(推薦)

    基于TCP通信丟包原因總結(jié)(推薦)

    下面小編就為大家?guī)?lái)一篇基于TCP通信丟包原因總結(jié)(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 兩種實(shí)現(xiàn)Java類(lèi)隔離加載的方法

    兩種實(shí)現(xiàn)Java類(lèi)隔離加載的方法

    這篇文章主要介紹了兩種實(shí)現(xiàn)Java類(lèi)隔離加載的方法,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-02-02
  • 詳解Spring Boot中初始化資源的幾種方式

    詳解Spring Boot中初始化資源的幾種方式

    這篇文章主要介紹了詳解Spring Boot中初始化資源的幾種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Spring?Boot自動(dòng)配置源碼實(shí)例解析

    Spring?Boot自動(dòng)配置源碼實(shí)例解析

    Spring Boot作為Java領(lǐng)域最為流行的快速開(kāi)發(fā)框架之一,其核心特性之一就是其強(qiáng)大的自動(dòng)配置機(jī)制,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot自動(dòng)配置源碼的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • Java中的線程生命周期核心概念

    Java中的線程生命周期核心概念

    這篇文章主要介紹了Java中的線程生命周期核心概念,通過(guò)使用一個(gè)快速的圖解展開(kāi)文章內(nèi)容,需要的小伙伴可以參考一下
    2022-06-06
  • Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例

    Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例

    這篇文章主要介紹了Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • MyBatis-Plus 如何單元測(cè)試的實(shí)現(xiàn)

    MyBatis-Plus 如何單元測(cè)試的實(shí)現(xiàn)

    這篇文章主要介紹了MyBatis-Plus 如何單元測(cè)試的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java8中新特性O(shè)ptional、接口中默認(rèn)方法和靜態(tài)方法詳解

    Java8中新特性O(shè)ptional、接口中默認(rèn)方法和靜態(tài)方法詳解

    Java 8 已經(jīng)發(fā)布很久了,很多報(bào)道表明Java 8 是一次重大的版本升級(jí)。下面這篇文章主要給大家介紹了關(guān)于Java8中新特性O(shè)ptional、接口中默認(rèn)方法和靜態(tài)方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-12-12
  • Java實(shí)現(xiàn)在Word中嵌入多媒體(視頻、音頻)文件

    Java實(shí)現(xiàn)在Word中嵌入多媒體(視頻、音頻)文件

    這篇文章主要介紹了Java如何實(shí)現(xiàn)在Word中嵌入多媒體(視頻、音頻)文件,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)java有一定的幫助,感興趣的同學(xué)可以了解一下
    2021-12-12
  • Spring事務(wù)的失效場(chǎng)景你知道多少

    Spring事務(wù)的失效場(chǎng)景你知道多少

    這篇文章主要為大家詳細(xì)介紹了Spring事務(wù)的失效場(chǎng)景,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03

最新評(píng)論