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

Java實(shí)現(xiàn)微信公眾號(hào)發(fā)送模版消息

 更新時(shí)間:2022年01月29日 09:31:33   作者:熱水瓶、  
大家好,本篇文章主要講的是Java實(shí)現(xiàn)微信公眾號(hào)發(fā)送模版消息,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下

微信公眾號(hào)發(fā)送模版消息 背景:如下圖,當(dāng)用戶發(fā)布需求的時(shí)候,公眾號(hào)自定推送消息。例如:微信支付的時(shí)候,公眾號(hào)會(huì)推送支付成功消息

在這里插入圖片描述

前提:發(fā)送模版消息,顧名思義,前提就是需要有模版,那么在哪里配置模版呢?
微信公眾號(hào)平臺(tái)–>廣告與服務(wù)–>模版消息–>我的模版
模版消息是已經(jīng)申請(qǐng)過(guò)的模版,如果里面的模版都不符合自己業(yè)務(wù)的話,可以到模版庫(kù)里找,然后添加到「我的模版」。也可以按照自己的需求申請(qǐng)新的模版,一般第二個(gè)工作日會(huì)審核通過(guò)。

在這里插入圖片描述

在模版詳情可以查看模版的格式,下圖左邊紅框是消息最終展示的效果,
右邊紅框是需要傳的參數(shù)。

在這里插入圖片描述

有了模版之后,模版ID就是我們要放進(jìn)代碼里的,復(fù)制出來(lái)。

消息模版準(zhǔn)備好之后,暫時(shí)不要寫(xiě)代碼奧,查看微信開(kāi)發(fā)文檔,看看發(fā)送模版都需要哪些參數(shù)。
微信開(kāi)發(fā)文檔–>基礎(chǔ)消息能力–>模版消息接口–「發(fā)送模版消息」

在這里插入圖片描述

查看微信開(kāi)發(fā)文檔

發(fā)送模版消息
http請(qǐng)求方式: POST https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN

這里是引用

注:url和miniprogram都是非必填字段,若都不傳則模板無(wú)跳轉(zhuǎn);若都傳,會(huì)優(yōu)先跳轉(zhuǎn)至小程序。開(kāi)發(fā)者可根據(jù)實(shí)際需要選擇其中一種跳轉(zhuǎn)方式即可。當(dāng)用戶的微信客戶端版本不支持跳小程序時(shí),將會(huì)跳轉(zhuǎn)至url。
返回碼說(shuō)明
在調(diào)用模板消息接口后,會(huì)返回JSON數(shù)據(jù)包。
正常時(shí)的返回JSON數(shù)據(jù)包示例:
{
“errcode”:0,
“errmsg”:“ok”,
“msgid”:200228332
}

發(fā)送模版所需參數(shù):
模版ID和openId是必須有的,剩下的就是和自己業(yè)務(wù)有關(guān)了。

上面的內(nèi)容都搞定之后,就可以開(kāi)始擼代碼了

發(fā)送模版微信返回Dto

@Data
public class TemplateMsgResultDto extends ResultState {

    /**
     * 消息id(發(fā)送模板消息)
     */
    private String msgid;

}

發(fā)送模版微信返回狀態(tài)

@Data
public class ResultState implements Serializable {

    /**
     * 狀態(tài)
     */
    private int errcode;

    /**
     * 信息
     */
    private String errmsg;

}

微信模版消息請(qǐng)求參數(shù)實(shí)體類(lèi)

@Data
public class WxTemplateMsg {
    /**
     * 接收者openId
     */
    private String touser;
    /**
     * 模板ID
     */
    private String template_id;
    /**
     * 模板跳轉(zhuǎn)鏈接
     */
    private String url;

    // "miniprogram":{ 未加入
    // "appid":"xiaochengxuappid12345",
    // "pagepath":"index?foo=bar"
    // },

    /**
     * data數(shù)據(jù)
     */
    private TreeMap<String, TreeMap<String, String>> data;

    /**
     * 參數(shù)
     *
     * @param value 值
     * @param color 顏色 可不填
     * @return params
     */
    public static TreeMap<String, String> item(String value, String color) {
        TreeMap<String, String> params = new TreeMap<String, String>();
        params.put("value", value);
        params.put("color", color);
        return params;
    }
}

Java封裝模版信息代碼

 public TemplateMsgResultDto noticeTemplate(TemplateMsgVo templateMsgVo) {
        // 模版ID
        String templateId="XXX";
        TreeMap<String, TreeMap<String, String>> params = new TreeMap<>();
        //根據(jù)具體模板參數(shù)組裝
        params.put("first", WxTemplateMsg.item("恭喜!您的需求已發(fā)布成功", "#000000"));
        params.put("keyword1", WxTemplateMsg.item(templateMsgVo.getTaskName(), "#000000"));
        params.put("keyword2", WxTemplateMsg.item("需求已發(fā)布", "#000000"));
        params.put("remark", WxTemplateMsg.item("請(qǐng)耐心等待審核", "#000000"));
        WxTemplateMsg wxTemplateMsg = new WxTemplateMsg();
        // 模版ID
        wxTemplateMsg.setTemplate_id(templateId);
        // openId
        wxTemplateMsg.setTouser(templateMsgVo.getOpenId());
        // 關(guān)鍵字賦值
        wxTemplateMsg.setData(params);
        String data = JsonUtils.ObjectToString(wxTemplateMsg);
        return handleSendMsgLog(data);
    }

發(fā)送模版代碼

    private TemplateMsgResultDto handleSendMsgLog(String data) {
        TemplateMsgResultDto resultDto = new TemplateMsgResultDto();
        try {
            resultDto = sendTemplateMsg(data);
        } catch (Exception exception) {
            log.error("發(fā)送模版失敗",  exception);
        }
        // TODO 可以記錄一下發(fā)送記錄的日志
        return resultDto;
    }


 public TemplateMsgResultDto sendTemplateMsg(String data) throws Exception {
        // 獲取token
        String accessToken = getAccessToken();
        // 發(fā)送消息
        HttpResult httpResult = HttpUtils.stringPostJson(ConstantsPath.SEND_MESSAGE_TEMPLATE_URL + accessToken, data);
        return IMJsonUtils.getObject(httpResult.getBody(), TemplateMsgResultDto.class);
    }


 /**
     * 獲取全局token
     */
    public String getAccessToken() {
        String key = ConstantsRedisKey.ADV_WX_ACCESS_TOKEN;
        // 從redis緩存中獲取token
        if (redisCacheManager.get(key) != null) {
            return (String) redisCacheManager.get(key);
        }
        // 獲取access_token
        String url = String.format(ConstantsPath.WX_ACCESS_TOKEN_URL, appid, secret);
        ResponseEntity<String> result = restTemplate.getForEntity(url, String.class);
        if (result.getStatusCode() == HttpStatus.OK) {
            JSONObject jsonObject = JSON.parseObject(result.getBody());
            String accessToken = jsonObject.getString("access_token");
            // Long expires_in = jsonObject.getLong("expires_in");
            redisCacheManager.set(key, accessToken, 1800);
            return accessToken;
        }
        return null;
    }

微信地址常量類(lèi)

public class ConstantsPath {
    /**
     * 微信公眾號(hào)獲取全局token
     */
    public static final String WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
 
    /**
     * 微信發(fā)送模版消息
     */
    public static final String SEND_MESSAGE_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";

}

Json工具類(lèi)

@Slf4j
public class JsonUtils {
    private static ObjectMapper json;
    static {
        json = new ObjectMapper();
        json.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        json.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 序列化為JSON字符串
     */
    public static String ObjectToString(Object object) {
        try {
            return (json.writeValueAsString(object));
        } catch (Exception e) {
            log.error("序列化為JSON字符串出錯(cuò)",e);
        }
        return null;
    }

    public static <T> T getObject(String jsonString, Class<T> clazz) {
        if (StringUtils.isEmpty(jsonString))
            return null;
        try {
            return json.readValue(jsonString, clazz);
        } catch (Exception e) {
            log.error("將JSON字符串轉(zhuǎn)化為Map出錯(cuò)",e);
            return null;
        }
    }

}

Http工具類(lèi)

@Component
@Slf4j
public class HttpUtils {
    private static String sourcePath;

    public static HttpResult stringPostJson(String path, String content) throws Exception{
        return stringPost(path, null, content, "utf-8", "utf-8", "application/json");
    }

    public static HttpResult stringPost(String path, Map<String,String> headerMap, String content, String contentencode, String encode, String contentType) throws Exception{
        StringEntity entity = new StringEntity(content, contentencode);
        entity.setContentType(contentType);
        return post(path, headerMap, entity, encode);
    }

    private static HttpResult post(String path, Map<String,String> headerMap, HttpEntity entity, String encode){
        HttpResult httpResult = new HttpResult();
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        try{
            HttpPost httpPost = new HttpPost(getURI(path));
            LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
            httpClient = HttpClientBuilder.create().setRedirectStrategy(redirectStrategy).build();
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(120000)
                    .setConnectTimeout(120000)
                    .setConnectionRequestTimeout(120000)
                    .setCircularRedirectsAllowed(true)
                    .setRedirectsEnabled(true)
                    .setMaxRedirects(5)
                    .build();
            httpPost.setConfig(requestConfig);

            httpPost.setHeader("User-Agent", header);

            if(headerMap != null && headerMap.size() > 0){
                for(String name:headerMap.keySet()) {
                    httpPost.addHeader(name, headerMap.get(name));
                }
            }
            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);
            httpResult.setStatus(response.getStatusLine().getStatusCode());
            if(httpResult.getStatus() == 200){
                HttpEntity resEntity = response.getEntity();
                httpResult.setBody(EntityUtils.toString(resEntity, encode));
            }
        }catch(Exception ex){
            log.error("post請(qǐng)求出錯(cuò)", ex);
        }finally{
            try{
                if(response != null){
                    response.close();
                }
                if(httpClient != null){
                    httpClient.close();
                }
            }catch(Exception ex) {
                log.error("post請(qǐng)求關(guān)閉資源出錯(cuò)", ex);
            }
        }
        return httpResult;
    }
}

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

相關(guān)文章

  • Java內(nèi)存劃分:運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    Java內(nèi)存劃分:運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    聽(tīng)說(shuō)Java運(yùn)行時(shí)環(huán)境的內(nèi)存劃分是挺進(jìn)BAT的必經(jīng)之路,這篇文章主要給大家介紹了關(guān)于Java運(yùn)行時(shí)數(shù)據(jù)區(qū)域(內(nèi)存劃分)的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • java中容器(頂層容器和中間容器)的布局管理器詳解

    java中容器(頂層容器和中間容器)的布局管理器詳解

    這篇文章主要介紹了java中容器(頂層容器和中間容器)的布局管理器詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(圖文)

    Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(圖文)

    這篇文章主要介紹了Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • java迭代器和for循環(huán)優(yōu)劣詳解

    java迭代器和for循環(huán)優(yōu)劣詳解

    在本篇文章里小編給大家整理的是一篇關(guān)于java迭代器和for循環(huán)優(yōu)劣詳解內(nèi)容,對(duì)此有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-01-01
  • Java 中的 print() 和 println()

    Java 中的 print() 和 println()

    這篇文章主要介紹了Java 中的 print() 和 println(),Java 中的 print()和println()方法用于在控制臺(tái)上顯示文本,下面來(lái)看看它們之間到底有什么區(qū)別吧,需要的朋友也可以參考一下
    2021-11-11
  • 關(guān)于Java中的IO流總結(jié)(推薦)

    關(guān)于Java中的IO流總結(jié)(推薦)

    下面小編就為大家?guī)?lái)一篇關(guān)于Java中的IO流總結(jié)(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • spring boot 項(xiàng)目利用Jenkins實(shí)現(xiàn)自動(dòng)化部署的教程詳解

    spring boot 項(xiàng)目利用Jenkins實(shí)現(xiàn)自動(dòng)化部署的教程詳解

    這篇文章主要介紹了spring boot 項(xiàng)目利用Jenkins實(shí)現(xiàn)自動(dòng)化部署的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-07-07
  • springboot2.3 整合mybatis-plus 高級(jí)功能(圖文詳解)

    springboot2.3 整合mybatis-plus 高級(jí)功能(圖文詳解)

    這篇文章主要介紹了springboot2.3 整合mybatis-plus 高級(jí)功能,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Feign調(diào)用中的兩種Header傳參方式小結(jié)

    Feign調(diào)用中的兩種Header傳參方式小結(jié)

    這篇文章主要介紹了Feign調(diào)用中的兩種Header傳參方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • java讀取properties配置文件的方法

    java讀取properties配置文件的方法

    這篇文章主要介紹了java讀取properties配置文件的方法,涉及java操作properties配置文件的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05

最新評(píng)論