微信公众号开发:明确什么是openid,推送模板消息java代码实现

第一次做微信推送消息这一块,所以整理出来供大家参考,有不对或不完善的地方,希望大家多多指教。

先附上官方的开发文档https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

然后,有几个我遇到的问题,如果各位在开发的过程中遇到了,请一定要注意。

一、做微信相关的开发,一定会和openId打交道,这里需要说明一下,openId只是一个公众号和一个微信用户之间唯一存在的id,而不是微信用户的唯一id,举个栗子:你关注了公众号A以后,公众号A会得到一个你的openid,你关注公众号B,公众号B也会拿到你的openId,但是,需要注意的是,这两个openId,不是一样的。

    我在开发的时候,做的是一个公众号里嵌套一个微信小程序,需要注意的是,微信小程序获取到的openid和我这个公众号产生的openId也是不一样的。

话不多说,上代码:

首先,根据微信官方api文档,建立一个传输数据类型类

public class Data_style {

    private String value;

    private String color;

    public String getValue() {
            return value;
        }

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

    public String getColor() {
            return color;
        }

    public void setColor(String color) {
            this.color = color;
        }

}

接下来就是创建你要在模板中传输的数据

public class Data {
    
    private Data_style first;

    private Data_style keyword1;

    private Data_style keyword2;
    
    private Data_style remark;

   public Data_style getFirst() {
      return first;
   }

   public void setFirst(Data_style first) {
      this.first = first;
   }

   public Data_style getKeyword1() {
      return keyword1;
   }

   public void setKeyword1(Data_style keyword1) {
      this.keyword1 = keyword1;
   }

   public Data_style getKeyword2() {
      return keyword2;
   }

   public void setKeyword2(Data_style keyword2) {
      this.keyword2 = keyword2;
   }

   public Data_style getRemark() {
      return remark;
   }

   public void setRemark(Data_style remark) {
      this.remark = remark;
   }
    

}

然后是模板

public class NewOrdersTemplate {
    private String touser; //用户OpenID
    
    private String template_id; //模板消息ID
    
    private String url; //URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
    
    private String topcolor; //标题颜色
    
    private Data 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 templateId) {
        template_id = templateId;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getTopcolor() {
        return topcolor;
    }

    public void setTopcolor(String topcolor) {
        this.topcolor = topcolor;
    }

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }
}

接下来就进入正题了


public class Template {

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

   /**
    * 发送模板消息
    * appId 公众账号的唯一标识
    * appSecret 公众账号的密钥
    * openId 用户标识
    */
   public static void send_template_message(String appId, String appSecret, String openId,String userName,Long weChatId,Long userId,String format1) {
//因为我申请的模板是需要填写当前时间戳的,所以在这里我获取了当前的时间
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH时mm分");
      String format = simpleDateFormat.format(new Date());
      Token token = CommonUtil.getToken(appId, appSecret);//这里要注意,如果你是申请的正式公众号的话,获取token的时候,一定要在后台加上你的ip,不然获取token的时候会报错
      String access_token = token.getAccessToken();
      String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+access_token;
      String templateId = "";//填写申请的模板id
      String goUrl = "";//填写点击推送的消息需跳转到的url

      Data_style first = new Data_style();
      Data_style keyword1 = new Data_style();
      Data_style keyword2 = new Data_style();
      Data_style remark = new Data_style();

      NewOrdersTemplate temp = new NewOrdersTemplate();
      Data data = new Data();

      first.setValue(format);
      first.setColor("#173177");

      keyword1.setValue("绑定成功");
      keyword1.setColor("#173177");

      keyword2.setValue(userName);
      keyword2.setColor("#173177");

      remark.setValue("");
      remark.setColor("#173177");

      data.setFirst(first);
      data.setKeyword1(keyword1);
      data.setKeyword2(keyword2);
      data.setRemark(remark);

      temp.setTouser(openId);
      temp.setTemplate_id(templateId);
      temp.setUrl(goUrl);
      temp.setTopcolor("#173177");
      temp.setData(data);

      String jsonString = JSONObject.fromObject(temp).toString().replace("day", "Day");
      JSONObject jsonObject = CommonUtil.httpsRequest(url, "POST", jsonString);
      System.out.println(jsonObject);
      int result = 0;
      if (null != jsonObject) {  
         if (0 != jsonObject.getInt("errcode")) {  
            result = jsonObject.getInt("errcode");  
            log.error("错误 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));  
         }  
      }
      log.info("模板消息发送结果:"+result);
   }

}

工具类

public class CommonUtil {
    
    private static Logger log = LoggerFactory.getLogger(CommonUtil.class);
    
    // 凭证获取(GET)
    public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    
    /**
     * 发送 https 请求
     * 
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式(GET、POST)
     * @param outputStr 提交的数据
     * @return JSONObject(通过 JSONObject.get(key) 的方式获取 JSON 对象的属性值)
     */
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        
        JSONObject jsonObject = null;
        
        try {
            // 创建 SSLContext 对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述 SSLContext 对象中得到 SSLSocketFactory 对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            
            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            
            // 设置请求方式(GET/POST)
            conn.setRequestMethod(requestMethod);
            
            // 当 outputStr 不为 null 时,向输出流写数据
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                
                // 注意编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            
            // 从输入流读取返回内容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            
            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error(" 连接超时:{}", ce);
        } catch (Exception e) {
            log.error("https 请求异常:{}", e);
        }
        
        return jsonObject;
    }

    /**
     * 获取接口访问凭证
     * 
     * @param appid 凭证
     * @param appsecret 密钥
     * @return
     */
    public static Token getToken(String appid, String appsecret) {
        Token token = null;
        String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
        // 发起GET请求获取凭证
        JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);

        if (null != jsonObject) {
            try {
                token = new Token();
                token.setAccessToken(jsonObject.getString("access_token"));
                token.setExpiresIn(jsonObject.getInt("expires_in"));
            } catch (JSONException e) {
                token = null;
                // 获取token失败
                log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }
        return token;
    }

}

token类

public class Token {
    //接口访问凭证
    private String accessToken;
    //接口有效期,单位:秒
    private int expiresIn;
    
    public String getAccessToken() {
        return accessToken;
    }
    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }
    public int getExpiresIn() {
        return expiresIn;
    }
    public void setExpiresIn(int expiresIn) {
        this.expiresIn = expiresIn;
    }
}

MyX509TrustManager类

public class MyX509TrustManager implements X509TrustManager{

    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

    }

    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

    }

    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值