微信发送模板消息-通过反射和泛型实现公共方法
实际业务中会发送多个模板消息,每个模板消息的字段数量不一致,发多个不同的模板就要修改代码或者新增方法来实现。
每次编写加班形影不离,打工人誓不加班!!!
通过反射和泛型实现一次编写多次调用。
package ;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author shiyi on 2022/3/22 9:32
*/
@Slf4j
@Component
public class WechatMessage<T> {
public static final String TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 微信模板消息,通用
*/
public void sendPublicMessage(String templateId, String openId, T t) {
// 获取access_token
String accessToken = getAccessToken();
// 设置模板消息基本参数
Map<String, Object> map = getStringObjectMap(templateId, openId);
// 获取实例
Class<?> tClass = t.getClass();
try {
sendMessage(WechatMessage.TEMPLATE_URL + accessToken, tClass, map, t);
} catch (IllegalAccessException | InstantiationException e) {
log.error("发送模板消息异常:{}", e.getMessage());
e.printStackTrace();
}
}
@NotNull
private Map<String, Object> getStringObjectMap(String templateId, String openId) {
Map<String, Object> map = new HashMap<>();
map.put("touser", openId);
map.put("template_id", templateId);
map.put("appid", "xxx");
map.put("url", "http://www.tshuide.com/wechatyy/");
return map;
}
/**
* 发送消息
* @param url 微信模板消息url
*/
private void sendMessage(String url, Class<?> aClass, Map<String, Object> map, T t) throws IllegalAccessException, InstantiationException {
// 通过反射拿到多个参数设置,然后发送模板消息
Map<String, Object> valueBean = new HashMap<>();
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String name = field.getName();
Map<Object, Object> colorBean = new HashMap<>();
colorBean.put("color","#009100");
colorBean.put("value",field.get(t));
valueBean.put(name, colorBean);
}
map.put("data", valueBean);
String msg = JSON.toJSONString(map);
log.error("发送模板消息体:{}", msg);
String post = HttpUtil.post(url, msg);
log.error("发送结果:{}", post);
}
/**
* 获取微信access_token
*/
private String getAccessToken() {
Map<String, Object> map = new HashMap<>();
map.put("appid", "xxx");
map.put("secret", "xxx");
String accessToken = (String) redisTemplate.opsForValue().get("access_token");
if (StringUtils.isEmpty(accessToken)) {
String s = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential", map);
JSONObject jsonObject = JSONObject.parseObject(s);
accessToken = (String) jsonObject.get("access_token");
redisTemplate.opsForValue().set("access_token", accessToken, 30, TimeUnit.MINUTES);
}
return accessToken;
}
}
调用示例。
1. 创建模板消息实体。
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author shiyi on 2022/3/22 11:17
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperationTempVO {
private String first;
private String keyword1;
private String keyword2;
private String keyword3;
private String remark;
}
2. 调用公共发消息的方法。
OperationTempVO tempVO = new OperationTempVO("您好,您有一个运维订单状态更新", entity.getOperationId(),entity.getReview() == 1 ? "通过" : "驳回",DateHelper.dateToString(new Date()), rejecteReason);
wechatMessage.sendPublicMessage("755BWMFm_6f73yWwdt94LRzO", "o8g6Ww_GQmaoS", tempVO);