(2022) java springMvc 实现微信小程序订阅消息模块

3 篇文章 0 订阅
1 篇文章 0 订阅


前言

微信小程序消息订阅,向微信用户发送消息模块java实现方案。
发送订阅消息步骤:
1.初始化系统用户绑定微信唯一标识openId
2.前端唤起长期订阅通知提示
3.后端用系统用户绑定的微信openId发送消息


提示:以下是本篇文章正文内容,下面案例可供参考

一、需要准备哪些东西

1:微信小程序的APP_ID,APP_SECRET
在这里插入图片描述

2:订阅消息模板id申请
![在这里插入图片描述](https://img-blog.csdnimg.cn/0548806305df4f27bbe1a444011bae5a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZCR552A5byA5Y-R6L-b5pS7,size_20,color_FFFFFF,t_70,g_se,x_16

二、使用步骤

1.系统用户绑定微信

小程序工具类 - 获取微信接口token 的工具类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeeplus.modules.sys.utils.CommonCacheUtils;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;


/**
 * 小程序工具类
 *
 * @author jsy
 * @version 2022/4/7
 **/
public class WeAppUtil {

  public static final String APP_KEY = ""; //小程序AppId
  public static final String APP_SECRET = "";//小程序AppSecret
  public static final String APP_TEMPLATE = "";//订阅模板Id

  /**
   *
   * 小程序获取token类
   * @return 响应token信息体
   */
  public static String getAccessToken() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
    RestTemplate restTemplate = new RestTemplate(factory());
    Map<String, Object> params = new HashMap<>(16);
    params.put("APPID", APP_KEY);
    params.put("APPSECRET", APP_SECRET);
    String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
        "&appid={APPID}&secret={APPSECRET}";
    ResponseEntity<String> responseEntity =
        restTemplate.getForEntity(url, String.class, params);
    String body = responseEntity.getBody();
    JSONObject object = JSON.parseObject(body);
    String accessToken = object.getString("access_token");
    String expiresIn = object.getString("expires_in");
    CommonCacheUtils.putCacheExpire("messageToken",accessToken,Integer.valueOf(expiresIn));
    return accessToken;
  }

  public static HttpComponentsClientHttpRequestFactory factory() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
    //rest忽略证书访问
    HttpComponentsClientHttpRequestFactory factory = new
        HttpComponentsClientHttpRequestFactory();
    factory.setConnectionRequestTimeout(1000);
    factory.setConnectTimeout(1000);
    factory.setReadTimeout(1000);
    // https
    SSLContextBuilder builder = new SSLContextBuilder();
    builder.loadTrustMaterial(null, (X509Certificate[] x509Certificates, String s) -> true);
    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
    Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", new PlainConnectionSocketFactory())
        .register("https", socketFactory).build();
    PoolingHttpClientConnectionManager phccm = new PoolingHttpClientConnectionManager(registry);
    phccm.setMaxTotal(200);
    CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).setConnectionManager(phccm).setConnectionManagerShared(true).build();
    factory.setHttpClient(httpClient);
    return factory;
  }
}

获取小程序的openId处理类
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeeplus.modules.app.push.dto.TemplateData;
import com.jeeplus.modules.app.push.dto.WxMssVo;
import com.jeeplus.modules.sys.utils.CommonCacheUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;


/**
 * app消息处理类
 *
 * @author jsy
 * @version 2022/4/7
 **/
@Service
public class AppMessageService {

  private static final Logger log = LoggerFactory.getLogger(AppMessageService.class);

  /**
   *
   * WeChat-AccessToken获取
   * @return String 响应授权token
   */
  public String getAccessToken() throws Exception {
    //从redis取,取不到重新获取,这里也可以把token存到数据库表里面
    Object messageToken = CommonCacheUtils.getCache("messageToken");
    if(messageToken!=null){
      return messageToken.toString();
    }else {
      return WeAppUtil.getAccessToken();
    }
  }

  /**
   * 消息推送service
   *
   * @param openid          微信标识id
   * @param templateDataMap 模块消息属性对象
   * @param template        模板类型编码
   * @return String 响应体信息
   * @throws Exception 消息异常
   */
  public String pushMessage(String openid, Map<String, TemplateData> templateDataMap, String template) throws Exception {
    RestTemplate restTemplate = new RestTemplate(WeAppUtil.factory());
    String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + this.getAccessToken();
    //拼接推送的模版
    WxMssVo wxMssVo = new WxMssVo();
    wxMssVo.setTouser(openid);
    wxMssVo.setTemplate_id(template);
    wxMssVo.setData(templateDataMap);
    ResponseEntity<String> responseEntity =
        restTemplate.postForEntity(url, wxMssVo, String.class);
    return responseEntity.getBody();
  }

  /**
   * 小程序获取openid
   *
   * @param code 获取openId的参数
   * @return openId
   * @throws NoSuchAlgorithmException 此处指加密算法异常
   * @throws KeyStoreException https构造器异常
   * @throws KeyManagementException 处理密钥管理异常
   */
  public String getOpenId(String code) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
    RestTemplate restTemplate = new RestTemplate(WeAppUtil.factory());
    String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + WeAppUtil.APP_KEY + "&secret=" + WeAppUtil.APP_SECRET + "&js_code=" + code + "&grant_type=authorization_code";
    ResponseEntity<String> responseEntity =
        restTemplate.getForEntity(url, String.class);
    String body = responseEntity.getBody();
    JSONObject object = JSON.parseObject(body);
    String openId = object.getString("openid");
    log.info("用户的openid:{}", openId);
    return openId;
  }
}

系统用户绑定微信
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;


/**
 *
 * 小程序-公众号-消息模板推送
 * 该接口存在跨域,后端解决
 * @author jsy
 * @version 2022/4/7
 **/
@RequestMapping("${streetAppPath}/wechat")
@Controller
@CrossOrigin(origins = "*", maxAge = 3600)
public class AppTokenController {

  @Autowired
  UserMapper userMapper;
  @Autowired
  AppMessageService messageService;

  /**
   * 初始化用户绑定微信(第一次登陆默认绑定用户信息)
   * @param request 请求体
   * @param code 获取openId的code
   * @return 响应体
   * @throws Exception openId读取异常信息
   */
  @GetMapping("initWeChat")
  @ResponseBody
  public AppJson initWeChat(HttpServletRequest request,@RequestParam(value = "code") String code) throws Exception {
    AppJson appJson = new AppJson();
    User user = userMapper.get(AppUserUtil.getUserId(request));
    if (StringUtils.isEmpty(user.getSign())) {
      //获取到openId
      String openid = messageService.getOpenId(code);
      //业务处理逻辑给用户绑定信息
      //user.setSign(openid);
      //userMapper.updateUserInfo(user);
      //appJson.setMsg("初始化个人信息成功!");
    } else {
      return  AppJson.fail().setMsg("该微信已绑定用户:" + user.getName());
    }
    return appJson;
  }
}

2.后端用系统用户绑定的微信openId发送消息

发送消息Api 准备实体类型:

import java.io.Serializable;


/**
 * 消息模板
 * @author jsy
 * @version 2022/4/8
 **/
public class TemplateData implements Serializable {
    private static final long serialVersionUID = -5520492982028423613L;
    private String value;

    public TemplateData(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}


import java.io.Serializable;
import java.util.Map;


/**
 * 请求参数json
 * @author jsy
 * @version 2022/4/7
 **/
public class WxMssVo implements Serializable {
    private static final long serialVersionUID = -2839791975022233280L;
    private String touser;//用户openid
    private String template_id;//订阅消息模版id 微信api需要这种格式请勿更改
    private String page = "/pages/home/index";//默认跳到小程序首页
    private Map<String, TemplateData> data;//推送文字

    public String getTouser() {
        return touser;
    }

    public void setTouser(String touser) {
        this.touser = touser;
    }

    public String getTemplate_id() {
        return template_id;
    }

    public void setTemplate_id(String template_id) {
        this.template_id = template_id;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public Map<String, TemplateData> getData() {
        return data;
    }

    public void setData(Map<String, TemplateData> data) {
        this.data = data;
    }
}

发送订阅消息Api

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;


/**
 * 小程序-公众号-消息模板推送
 *
 * @author jsy
 * @version 2022/4/7
 **/
@RequestMapping("${adminPath}/push/wechat")
@Controller
public class PushMessageController {

  @Autowired
  private AppMessageService messageService;

  /**
   * 微信小程序-推送消息
   *
   * @return AjaxJson
   * @description 此方法用于提醒用户进行消息通知
   */

  @ResponseBody
  @GetMapping("pushUserMessage")
  public AjaxJson pushUserBirthdayMessage(@RequestParam(value = "userId") String userId,@RequestParam(value = "questionContent") String questionContent) throws Exception {
    AjaxJson ajaxJson = new AjaxJson();
    if (StringUtils.isEmpty(userId)) {
      ajaxJson.setMsg("用户不能为空!");
      ajaxJson.setSuccess(false);
      return ajaxJson;
    }
    if (StringUtils.isEmpty(questionContent)) {
      ajaxJson.setMsg("通知内容不能为空!");
      ajaxJson.setSuccess(false);
      return ajaxJson;
    }
    //获取当前登陆用户
    User user = UserUtils.getUser();
    if (StringUtils.isEmpty(user.getSign())) {
      ajaxJson.setMsg("用户还未绑定微信,无法发送通知!");
      ajaxJson.setSuccess(false);
      return ajaxJson;
    }
    if (questionContent.length() > 20) {
      ajaxJson.setMsg("消息通知内容禁止超过20字!");
      ajaxJson.setSuccess(false);
      return ajaxJson;
    }
    //模板属性
    Map<String, TemplateData> templateDataMap = new HashMap<>(16);
    templateDataMap.put("thing1", new TemplateData(user.getName()));
    templateDataMap.put("thing4", new TemplateData(questionContent));
    templateDataMap.put("thing5", new TemplateData("请您尽快进入系统上报问题"));
    templateDataMap.put("time2", new TemplateData(DateUtils.getMessageDate()));
    String result = messageService.pushMessage(user.getSign(), templateDataMap, WeAppUtil.APP_TEMPLATE);
    Map<String, Object> map = FastJsonUtils.json2Map(result);
    if((int)map.get("errcode") == 0){
      ajaxJson.setMsg("推送成功");
      ajaxJson.setSuccess(true);
    }else {
      ajaxJson.setSuccess(false);
      ajaxJson.setMsg("调用推送接口错误,返回body:"+map.toString());
    }
    return ajaxJson;
  }
}

总结

在这里插入图片描述


收到通知,结束!!!!好评点赞哦


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值