前言
在项目中,发送微信模板消息的场景十分常见,本文通过两个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();
}
}
写的都挺清楚的,没啥总结的。。。不对,我女朋友超级可爱!!!!