使用微信公众号给指定微信用户发送信息

  1.编写接口验证微信方是否接入成功

    /*参数	    描述
      signature	微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
      timestamp	时间戳
      nonce	    随机数
      echostr	    随机字符串*/
    @ApiOperation("验证微信方是否接入成功")
    @GetMapping("/weChat") //get方法是为了验证微信方是否接入成功
    public String validate(String signature,String timestamp,String nonce,String echostr)
    {
        //1)将token、timestamp、nonce三个参数进行字典序排序
        String[] arr = {WeChatUtils.TOKEN,timestamp,nonce};
        Arrays.sort(arr);

        //2)将三个参数字符串拼接成一个字符串进行sha1加密
        String str = arr[0]+arr[1]+arr[2];
        String mySignature = sha1(str);

        //获得自己加密的签名
        //3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
        if(StringUtils.equals(mySignature,signature))
        {
            //原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败
            return echostr;
        }
        return null;
    }

 注意:token要与配置的token一致

package com.guigusuqi.commonutils.utils;

public class WeChatUtils
{
    public static final String TOKEN = "guigusuqi7";
}

2.配置接口信息,为了验证微信方是否接入成功

 前提是需要用nginx把80端口的URL代理到项目中的接口路径

upstream questionnaire
    {
        server 127.0.0.1:8002;
    }
server
    {
        listen 80;
        server_name suqiqaq.cn;
       
        location ~ /officialAccount/weChat
        {
          proxy_pass http://questionnaire;
        }
    }

3.开始使用微信公众平台的测试号来调用接口

微信测试号配置测试号

4.配置yaml:

weChat:
  appID: wx6dda2178c44e613a
  appsecret: 0ea9dc58811790c5115e4d44f86ed5f2
  templateID: lcNTMFxkf0TlhOVryVHSadjgBG9G5nXaVefkyZ8O9es	 # 模板id
  getAccessTokenUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${weChat.appID}&secret=${weChat.appsecret} # 获取accessTokenUrl
  url: https://wj.qq.com/s2/9294970/8014 # 用户点击信息 跳转的url

5.编写接口,发送用户请求

 @Override
    public Result sendTemplateInfo(JSONObject jsonData) throws Exception
    {
        //获取小程序accessToken
        String accessToken = obtainAccessTokenUtils.obtainAccessToken();

        //消息推送接口
        String path = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;

        String result = HttpClientUtils.doPost(path, jsonData.toJSONString());
        //将微信返回结果解析成json对象
        //判断发送模板消息结果
        JSONObject obj = JSONObject.parseObject(result);
        //将json对象赋值给map
        Map<String, Object> map = obj;

        //获取错误码 如果code为0,errmsg为ok 代表成功
        Integer code = (Integer)map.get("errcode");

        String msg = map.get("errmsg").toString();
        if (0  != code  ||  !"ok".equals(msg))
        {
            return Result.fail().code(code).message("消息推送失败,"+msg);
        }
        return Result.success().message("消息推送成功!");
    }

5.1编写接口,通过发送请求getAccessTokenUrl获取access_token

公众号获得access_token需要添加白名单

package com.guigusuqi.commonutils.utils;

import com.alibaba.fastjson.JSONObject;
import com.guigusuqi.commonutils.exceptionHandler.GlobalExceptionHandler;
import com.guigusuqi.commonutils.exceptionHandler.HospitalException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import java.io.IOException;
import java.util.Map;

/**
 * 公众号发送模板信息给用户所需要的access_token
 */
@Component
public class ObtainAccessTokenUtils
{
    @Value("${weChat.getAccessTokenUrl}")
    String getAccessTokenUrl;

    /**
     * 获取AccessToken
     * @return
     */
    public String obtainAccessToken() throws IOException
    {
        // 返回的用户信息json字符串
        String result  = HttpClientUtils.doPost(getAccessTokenUrl, "");

        JSONObject obj = JSONObject.parseObject(result);
        Map<String, Object> map =obj;
        try {
            //从结果中取出access_token
            String  access_token  = map.get("access_token").toString();
            return access_token;
        }catch (Exception e){
            //如果返回的结果中有errcode和errmsg,说明接口调用失败
            Integer errCode = (Integer) map.get("errcode");
            String errMsg = map.get("errmsg").toString();
            throw new HospitalException(errCode,"微信公众平台获得access_token失败,"+errMsg);
        }
    }
}

HttpClientUtils:

package com.guigusuqi.commonutils.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

public class HttpClientUtils
{
    //发起一个get请求,返回数据是以json格式返回
    public static JSONObject doGet(String url) throws IOException
    {
        JSONObject jsonObject = null;

        CloseableHttpClient client = HttpClients.createDefault();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();

        if(entity != null)
        {
            String result = EntityUtils.toString(entity,"UTF-8");
            jsonObject = JSONObject.parseObject(result);
        }
        httpGet.releaseConnection();;
        return jsonObject;
    }

    //发起一个post请求,返回数据是以json格式返回
    public static String doPost(String url,String jsonParam) throws IOException
    {
        System.out.println(jsonParam);

        // 获取连接客户端工具
        CloseableHttpClient httpClient = HttpClients.createDefault();

        String entityStr = null;
        CloseableHttpResponse response = null;

        try {
            // 创建POST请求对象s
            HttpPost httpPost = new HttpPost(url);
            if (!"".equals(jsonParam)){
                // 创建请求参数
                StringEntity s = new StringEntity(jsonParam, "utf-8");
                //设置参数到请求对象中
                httpPost.setEntity(s);
            }
            //添加请求头信息
            httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
            httpPost.addHeader("Content-Type", "application/json");
            // 执行请求
            response = httpClient.execute(httpPost);
            // 获得响应
            HttpEntity entity = response.getEntity();
            // 将响应结果转换成字符串
            entityStr = EntityUtils.toString(entity, "UTF-8");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放连接
            if (null != response) {
                try {
                    response.close();
                    httpClient.close();
                } catch (IOException e) {
                    System.out.println("释放连接出错");
                    e.printStackTrace();
                }
            }
        }
        // 打印响应内容
        System.out.println("打印响应内容:"+entityStr);
        return entityStr;
    }
}

5.2 获得access_token之后,请求消息推送接口,获得发送的结果

 @Override
    public Result sendTemplateInfo(JSONObject jsonData) throws Exception
    {
        //获取小程序accessToken
        String accessToken = obtainAccessTokenUtils.obtainAccessToken();

        //消息推送接口
        String path = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;

        String result = HttpClientUtils.doPost(path, jsonData.toJSONString());
        //将微信返回结果解析成json对象
        //判断发送模板消息结果
        JSONObject obj = JSONObject.parseObject(result);
        //将json对象赋值给map
        Map<String, Object> map = obj;

        //获取错误码 如果code为0,errmsg为ok 代表成功
        Integer code = (Integer)map.get("errcode");

        String msg = map.get("errmsg").toString();
        if (0  != code  ||  !"ok".equals(msg))
        {
            return Result.fail().code(code).message("消息推送失败,"+msg);
        }
        return Result.success().message("消息推送成功!");
    }

5.3 得到access_token了,url也有了,下一步就是看看发送模板消息需要哪些入参了

 {
           "touser":"oLiuN6Z8zlX-ONrjPFsW8FoKKtdI",
           "template_id":"lcNTMFxkf0TlhOVryVHSadjgBG9G5nXaVefkyZ8O9es",         
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }

touser这个参数必须是关注了这个公众号的: 

 模板id就是yaml文件指定的templateID

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值