微信模板消息发送

前言

在项目中,发送微信模板消息的场景十分常见,本文通过两个demo,分别展示了微信发送的原理和在实际项目中如何发送微信模板消息,demo代码粘贴即可使用。

1、微信原生方法发送消息

1.1、获取发送模板消息关键信息

关键信息:appid,appsecret,templateId,openid

首先 我们打开微信公众号后台管理页面,找到appsecret和appid,并将ip加入白名单

 然后,找到要发送的模板id

 最后,找到要发送人的openid

 1.2、发送模板消息

1.2.1、发送代码

package com.itheima.service;

import com.alibaba.fastjson.JSON;
import com.itheima.util.HttpUtils;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class WxTemplateService {

    //自己的appid
    private String appId ="";
    
    //自己的appsecret
    private String appSecret="";

    //模板消息内容,注意和模板一致
    private String jsonData="{\"touser\":\"oj1Gq6XnFIOKBVuXjeE_vxbRjJIg\",\"template_id\":\"qIXQWnLdV8sfdXx9jlHQxxqp-YZsQKm1hYrwVcrkUlo\",\"data\":{\"first\":{\"value\":\"恭喜你购买成功!\",\"color\":\"#173177\"},\"keyword1\":{\"value\":\"巧克力\",\"color\":\"#173177\"},\"keyword2\":{\"value\":\"39.8元\",\"color\":\"#173177\"},\"keyword3\":{\"value\":\"2014年9月22日\",\"color\":\"#173177\"},\"remark\":{\"value\":\"欢迎再次购买!\",\"color\":\"#173177\"}}}";



    public void sendMessage(){
        //获取token
        String url ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
        String result = HttpUtils.doGet(url, "");
        Map<String,String> map = (Map<String, String>) JSON.parse(result);
        String token = map.get("access_token");
        //发送模板消息
        String postUrl ="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+token;
        HttpUtils.doPost(postUrl,jsonData);
    }





}

1.2.2 http工具类

package com.itheima.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;



public class HttpUtils {

    /**
     * 调用对方接口方法
     * @param path 对方或第三方提供的路径
     * @param data ""
     */
    public static String doGet(String path,String data) {
        String result = "";
        try {
            URL url = new URL(path);
            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            PrintWriter out = null;

            /**设置URLConnection的参数和普通的请求属性****start***/

            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

            /**设置URLConnection的参数和普通的请求属性****end***/

            //设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个
            //最常用的Http请求无非是get和post,get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,
            //post与get的 不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。
            conn.setDoOutput(true);
            conn.setDoInput(true);

            conn.setRequestMethod("GET");//GET和POST必须全大写
            /**GET方法请求*****start*/
            /**
             * 如果只是发送GET方式请求,使用connet方法建立和远程资源之间的实际连接即可;
             * 如果发送POST方式的请求,需要获取URLConnection实例对应的输出流来发送请求参数。
             * */
            conn.connect();

            /**GET方法请求*****end*/


            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String str ="";
            while ((str = br.readLine()) != null) {
                str=new String(str.getBytes(),"UTF-8");//解决中文乱码问题
                result =str;
                System.out.println("打印字符串"+str);
            }
            //关闭流
            is.close();
            //断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();
            System.out.println("完整结束");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 调用对方接口方法
     * @param path 对方或第三方提供的路径
     * @param data json字符串
     */
    public static void doPost(String path,String data) {
        try {
            URL url = new URL(path);
            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            PrintWriter out = null;

            /**设置URLConnection的参数和普通的请求属性****start***/

            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

            /**设置URLConnection的参数和普通的请求属性****end***/

            //设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个
            //最常用的Http请求无非是get和post,get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,
            //post与get的 不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。
            conn.setDoOutput(true);
            conn.setDoInput(true);

            conn.setRequestMethod("POST");//GET和POST必须全大写

            /***POST方法请求****start*/

            out = new PrintWriter(conn.getOutputStream());//获取URLConnection对象对应的输出流

            out.print(data);//发送请求参数即数据

            out.flush();//缓冲数据

            /***POST方法请求****end*/

            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str = br.readLine()) != null) {
                str=new String(str.getBytes(),"UTF-8");//解决中文乱码问题
                System.out.println(str);
            }
            //关闭流
            is.close();
            //断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();
            System.out.println("完整结束");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

1.2.3、测试

package com.itheima.dao;

import com.itheima.service.WxTemplateService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Resource
    private WxTemplateService wxTemplateService;

    @Test
    public void test01(){

        wxTemplateService.sendMessage();

    }

}

1.2.4 测试结果

2、实际项目微信发送消息

在实际项目中,一般不会直接调用http请求发送消息,而是使用已经封装好的方法

2.1、导入jar包

<dependency>
   <groupId>com.github.binarywang</groupId>
   <artifactId>weixin-java-mp</artifactId>
   <version>2.9.8.BETA</version>
</dependency>

2.2、配置类实例化WxMpService对象(注意填充自己的appid和appsecret)

package com.wpg.config;

import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WxConfig {

    // 微信号的appid
    private String appId="";
    // 微信号的appSecret 
    private String appSecret ="";
    

    /**
     * 微信服务装载
     * @return
     */
    @Bean
    public WxMpService wxMpService() {
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
        return wxMpService;
    }

    /**
     * 配置温馨的APPID和密码
     * @return
     */
    @Bean
    public WxMpConfigStorage wxMpConfigStorage() {
        WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage();
        wxMpConfigStorage.setAppId(appId);
        wxMpConfigStorage.setSecret(appSecret);
        return wxMpConfigStorage;
    }

}

2.3、发送模板消息(注意填充自己的templateid和openid)

package com.wpg.service;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

@Service
public class WxTemplateService {

    @Autowired
    private WxMpService wxMpService;

    //模板id
    private String templateId = "";

    //用户openid
    private String openId = "";


    public void sendTemplateMsg() {
        //实例化模板对象
        WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();
        //设置模板ID
        wxMpTemplateMessage.setTemplateId(templateId);
        //设置发送给哪个用户
        wxMpTemplateMessage.setToUser(openId);
        //构建消息格式
        List<WxMpTemplateData> list = Arrays.asList(
                new WxMpTemplateData("first", "wen"),
                new WxMpTemplateData("keyword1", "wen"),
                new WxMpTemplateData("keyword2", "wen"),
                new WxMpTemplateData("keyword3", "wen"),
                new WxMpTemplateData("keyword4", "wen"),
                new WxMpTemplateData("remark", "wen")
        );
        //放进模板对象。准备发送
        wxMpTemplateMessage.setData(list);
        try {
            //发送模板
            wxMpService.getTemplateMsgService().sendTemplateMsg(wxMpTemplateMessage);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

    }
}

2.4、测试

package com.wpg.dao;

import com.wpg.QuickApplication;
import com.wpg.service.WxTemplateService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = QuickApplication.class)
public class MyTest extends AbstractJUnit4SpringContextTests {

    @Autowired
    private WxTemplateService wxTemplateService;


    @Test
    public void zegTest(){
        wxTemplateService.sendTemplateMsg();
    }
}

写的都挺清楚的,没啥总结的。。。不对,我女朋友超级可爱!!!!

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值