七、微信小程序Java后台完成消息推送
最后说明,通过appid和appSecret可以获取accessToken,然后拼接消息推送的url,然后发送请求就可以了。这里setData 的keyword1这些多少个是取决于你小程序选用的模板,我期中的mark判断是判断是给用户还是给商家推送消息,因为这两个消息模板不一样;另外,我获取的accessToken是存入数据库的,第一次获取会添加,后续获取会直接查询数据库,但是要判断是否过期,过期时间是微信订的7200秒,业务就这样,上面的每一步的注释都比较清楚的。
一、必须 需要前端传入的数据:
template_id
form_id
openid(或者userid:通过userid获取已经存入数据库中的用户openid)
我这里根据自己的一些业务创建了两个入参实体:
1、
/**
* 说明:
*
* @author panhh
* @date 2019/7/18 10:32
*/
@Data
public class MsgPushRequest {
/**
* 用户id :用户查询活用的openid
*/
@ApiModelProperty(value = "用户id")
@NotEmpty(message = "userId不能为空")
private Long userId;
/**
* form_id 前端
*/
@ApiModelProperty(value = "必须的请求参数")
@NotEmpty(message = "formId不能为空")
private String formId;
/**
* 模板id 前台
*/
@ApiModelProperty(value = "template_id")
@NotEmpty(message = "templateId不能为空")
private String templateId;
/**
* 判断要推送的消息是推送给用户还是给商户
* 1:对用户 ;2:对商家
*/
@ApiModelProperty(value = "推送的消息面对商户还是用户")
@NotNull(message = "mark不能为空")
private Integer mark;
}
2、
/**
* 说明:
*
* @author panhh
* @date 2019/7/18 15:23
*/
@Data
public class OrderMsgRequest implements Serializable {
/**
* 订单编号
*/
@ApiModelProperty(value = "订单编号")
@NotEmpty(message = "订单编号不能为空")
private String orderId;
/**
* 取餐时间
*/
@ApiModelProperty(value = "取餐时间")
@NotEmpty(message = "取餐时间不能为空")
private String eatTime;
/**
* 就餐类型
*/
@ApiModelProperty(value = "就餐类型")
@NotEmpty(message = "就餐类型不能为空")
private String eatStatus;
/**
* 下单时间
*/
@ApiModelProperty(value = "下单时间")
@NotEmpty(message = "下单时间不能为空")
private String orderCreateTime;
/**
* 取餐码
*/
@ApiModelProperty(value = "取餐码")
@NotEmpty(message = "取餐码不能为空")
private String diningCode;
/**
* 温馨提示
*/
@ApiModelProperty(value = "温馨提示")
@NotEmpty(message = "\'温馨提示\'不能为空")
private String tips;
/**
* 商户名称,给用户推送消息需要,商户则不需要
* 1:对用户 ;2:对商家
*/
@ApiModelProperty(value = "商户名称,给用户推送消息需要,商户则不需要")
private String shopName ;
}
二、定义接口
/**
* 说明:消息推送相关接口
*
* @author panhh
* @date 2019/7/18 10:27
*/
@RestController
@Api(value = "message",description = "消息推送相关接口")
@RequestMapping("/msg/")
public class MsgController {
@Autowired
private MsgService msgService;
/**
* 向用户推送消息
* @param msgPushRequest
* @return
*/
@PostMapping("/pushMessage")
public ResultVo msgPush2User(MsgPushRequest msgPushRequest, OrderMsgRequest orderMsgRequest){
System.out.println("msgPushRequest:"+msgPushRequest);
System.out.println("orderMsgRequest:"+orderMsgRequest);
String returnBody = msgService.msgPush2User(msgPushRequest, orderMsgRequest);
JSONObject bodyJson = JSONObject.parseObject(returnBody);
Set<String> keySet = bodyJson.keySet();
for (String key : keySet) {
if ("errcode".equals(key)){
return Result.error(ExceptionMsg.FAILED,returnBody);
}
}
return Result.success(returnBody);
}
}
三、业务层:
/**
* 说明:
*
* @author panhh
* @date 2019/7/18 10:29
*/
@Service
public class MsgService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private IdWorkerUtils idWorkerUtils;
@Autowired
private MsgMapper msgMapper;
@Value("${message.appid}")
private String appid;
@Value("${message.appSecret}")
private String appSecret;
private int unique1 = 7;
private String accessToken;
/**
* 向用户推送消息
* @param msgPushRequest
*/
public String msgPush2User(MsgPushRequest msgPushRequest, OrderMsgRequest orderMsgRequest) {
AccessTokenEntity accessTokenEntity = new AccessTokenEntity();
// 1、通过用户id查询用户的openid
String openid = "testOpenId";
//2、从数据库中获取access_token,并判断是否失效,失效的话重新获取
//2.1、从数据库中查询并判断
accessTokenEntity.setUnique1(unique1);
accessTokenEntity = this.msgMapper.getAccessToken(accessTokenEntity);
System.out.println("accessTokenEntity--->"+accessTokenEntity);
if (accessTokenEntity == null){
//为null-->获取后添加
System.out.println("为null~~~~~~");
String accessTokenJson = getAccessToken();
//解析
JSONObject jsonObject = JSONObject.parseObject(accessTokenJson);
accessToken = (String) jsonObject.get("access_token");
Integer expiresIn = (Integer) jsonObject.get("expires_in");
System.out.println("access_token:"+accessToken);
System.out.println("expires_in:"+expiresIn);
//进行添加
saveAccessToken(accessToken, expiresIn);
}else {
//不为null-->则判断是否过期
Long expiresTime = Long.valueOf(accessTokenEntity.getExpiresTime());
System.out.println("expiresTime---"+expiresTime);
long nowTime = System.currentTimeMillis();
System.out.println("nowTime---"+nowTime);
if (nowTime > expiresTime){
//已失效,重新获取,然后更新
System.out.println("不为null 但~过期!~~~~~~");
String accessTokenJson = getAccessToken();
JSONObject jsonObject = JSONObject.parseObject(accessTokenJson);
accessToken = (String) jsonObject.get("access_token");
Integer expiresIn = (Integer) jsonObject.get("expires_in");
//更新
expiresTime = System.currentTimeMillis()+expiresIn;
accessTokenEntity.setExpiresTime(expiresTime+"");
accessTokenEntity.setAccessToken(accessToken);
//执行更新
if (this.msgMapper.updateAccessToken(accessTokenEntity) < 1){
throw new GlobalException(ExceptionMsg.FAILED);
};
}
}
//拼接url,和设置推送消息
WxmsgPushVo wxmsgPushVo = new WxmsgPushVo();
wxmsgPushVo.setTouser(openid);
wxmsgPushVo.setForm_id(msgPushRequest.getFormId());;
wxmsgPushVo.setTemplate_id(msgPushRequest.getTemplateId());
//封装miniprogram对象
Miniprogram miniprogram = new Miniprogram();
miniprogram.setAppid(appid);
wxmsgPushVo.setMiniprogram(miniprogram);
//封装data,需要判断本条消息是给用户还是给商户 mark--> 1:对用户;2:对商家
HashMap<String, TemplateData> map = new HashMap<>();
if (msgPushRequest.getMark() == 2){
//订单号
TemplateData keyword1 = new TemplateData(orderMsgRequest.getOrderId());
map.put("keyword1",keyword1);
//就餐时间
TemplateData keyword2 = new TemplateData(orderMsgRequest.getEatTime());
map.put("keyword2",keyword2);
//就餐类型
TemplateData keyword3 = new TemplateData(orderMsgRequest.getEatStatus());
map.put("keyword3",keyword3);
//下单时间
TemplateData keyword4 = new TemplateData(orderMsgRequest.getOrderCreateTime());
map.put("keyword4",keyword4);
//取餐码
TemplateData keyword5 = new TemplateData(orderMsgRequest.getDiningCode());
map.put("keyword5",keyword5);
//温馨提示
TemplateData keyword6 = new TemplateData(orderMsgRequest.getTips());
map.put("keyword6",keyword6);
}else {
//取餐号
TemplateData keyword1 = new TemplateData(orderMsgRequest.getDiningCode());
map.put("keyword1",keyword1);
//门店名称
TemplateData keyword2 = new TemplateData(orderMsgRequest.getShopName());
map.put("keyword2",keyword2);
//下单时间
TemplateData keyword3 = new TemplateData(orderMsgRequest.getOrderCreateTime());
map.put("keyword3",keyword3);
//温馨提示 tips
TemplateData keyword4 = new TemplateData(orderMsgRequest.getTips());
map.put("keyword4",keyword4);
}
//setData
wxmsgPushVo.setData(map);
Object wxVoJson = JSONObject.toJSON(wxmsgPushVo);
System.out.println("wxVoJson--"+wxVoJson);
//发起请求
String pushUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
System.out.println("pushUrl---"+pushUrl);
//返回值为推送结果
ResponseEntity<String> entity = restTemplate.postForEntity(pushUrl, wxVoJson, String.class);
String body = entity.getBody();
System.out.println("body---"+body);
return body;
}
/**
* 保存accessToken
* @param accessToken
* @param expiresIn
*/
private void saveAccessToken(String accessToken, Integer expiresIn) {
long id = idWorkerUtils.nextId();
long expiresTime = System.currentTimeMillis()+expiresIn * 1000 - 600 * 1000;
AccessTokenEntity accessTokenEntitySave = new AccessTokenEntity();
accessTokenEntitySave.setId(id);
accessTokenEntitySave.setAccessToken(accessToken);
accessTokenEntitySave.setExpiresTime(expiresTime+"");
accessTokenEntitySave.setUnique1(unique1);
//执行保存
if (msgMapper.saveAccessToken(accessTokenEntitySave) < 1){
throw new GlobalException(ExceptionMsg.FAILED);
};
}
/**
* 请求获取accessToken
* @return
*/
private String getAccessToken() {
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+appSecret;
System.out.println("获取access_token的url---"+url);
return restTemplate.getForObject(url, String.class);
}
}
四、通过appid和appSecret可以获取accessToken,直接定义了一个方法
五、去除我自己的业务 ,简要的步骤说明:1、通过appid和Appsecret发起请求获取accessToken,2、设置模板的值;3、使用accessToken拼接请求链接,携带参数发起请求完成推送;4、处理推送的返回值。
六、最后说明,通过appid和appSecret可以获取accessToken,然后拼接消息推送的url,然后发送请求就可以了。这里setData 的keyword1这些多少个是取决于你小程序选用的模板,我期中的mark判断是判断是给用户还是给商家推送消息,因为这两个消息模板不一样;另外,我获取的accessToken是存入数据库的,第一次获取会添加,后续获取会直接查询数据库,但是要判断是否过期,过期时间是微信订的7200秒,业务就这样,上面的每一步的注释都比较清楚的。
希望你不忘初心,保持努力,掌握自己我命运!