|
@@ -2,6 +2,7 @@ package com.jpsoft.employment.modules.common.utils;
|
|
|
|
|
|
import cn.hutool.core.date.DateTime;
|
|
|
import com.jpsoft.employment.modules.wechat.entity.AccessToken;
|
|
|
+import com.jpsoft.employment.modules.wechat.entity.SessionKey;
|
|
|
import com.jpsoft.employment.modules.wechat.vo.UserInfo;
|
|
|
import net.sf.json.JSONArray;
|
|
|
import net.sf.json.JSONException;
|
|
@@ -16,8 +17,9 @@ import javax.servlet.ServletInputStream;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import javax.xml.parsers.SAXParser;
|
|
|
import javax.xml.parsers.SAXParserFactory;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.UnsupportedEncodingException;
|
|
|
+import java.io.*;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.URL;
|
|
|
import java.security.MessageDigest;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Comparator;
|
|
@@ -32,6 +34,8 @@ import java.util.stream.Collectors;
|
|
|
public class WeixinUtil {
|
|
|
private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);
|
|
|
|
|
|
+ public static final String send_template = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
|
|
|
+
|
|
|
// 获取access_token的接口地址(GET) 限200(次/天),可以在配置文件中修改
|
|
|
public static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
|
|
|
|
|
@@ -52,7 +56,7 @@ public class WeixinUtil {
|
|
|
|
|
|
//通过code换取网页授权access_token
|
|
|
public static String accessTokenurl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
|
|
|
- public static AccessToken getAccessToken(String appid, String appsecret,String code) throws Exception {
|
|
|
+ public static AccessToken getAccessToken(String appid, String appsecret, String code) throws Exception {
|
|
|
AccessToken accessToken = null;
|
|
|
String formatUrl = accessTokenurl.replace("APPID", appid).replace("SECRET",appsecret).replace("CODE", code);
|
|
|
JSONObject json = HttpConnectionUtil.httpRequest(formatUrl, "GET", null);
|
|
@@ -69,7 +73,8 @@ public class WeixinUtil {
|
|
|
log.error("获取token失败,返回结果result={}", json);
|
|
|
if (json.getString("errcode").equals("40163")){
|
|
|
throw new Exception("请重新扫码");
|
|
|
-
|
|
|
+ }else{
|
|
|
+ throw new Exception(json.getString("errcode"));
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -77,6 +82,26 @@ public class WeixinUtil {
|
|
|
return accessToken;
|
|
|
}
|
|
|
|
|
|
+ //通过code换取网页授权access_token
|
|
|
+ public static String sessionKeyUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";
|
|
|
+ public static SessionKey getSessionKey(String appid, String appsecret, String code) throws Exception {
|
|
|
+ SessionKey sessionKey = null;
|
|
|
+ String formatUrl = sessionKeyUrl.replace("APPID", appid).replace("SECRET",appsecret).replace("JSCODE", code);
|
|
|
+ JSONObject json = HttpConnectionUtil.httpRequest(formatUrl, "GET", null);
|
|
|
+ if (!json.isNullObject() && !json.isEmpty()) {
|
|
|
+ try {
|
|
|
+ sessionKey = new SessionKey();
|
|
|
+ sessionKey.setSessionKey(json.getString("session_key"));
|
|
|
+ //sessionKey.setUnionid(json.getString("unionid"));
|
|
|
+ sessionKey.setOpenid(json.getString("openid"));
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 获取token失败
|
|
|
+ log.error("获取token失败,返回结果result={}", json);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sessionKey;
|
|
|
+ }
|
|
|
+
|
|
|
public static String jsAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
|
|
|
public static String getJsAPI(String accessToken){
|
|
|
String formatUrl = jsAccessTokenUrl.replace("ACCESS_TOKEN", accessToken);
|
|
@@ -125,10 +150,27 @@ public class WeixinUtil {
|
|
|
// 获取用户信息
|
|
|
public static String user_info_url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
|
|
|
public static String subscribe_user_info_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN ";
|
|
|
+ public static String custom_message_url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
|
|
|
+
|
|
|
+ public static void sendCustomMessage(String accessToken,String openId,String message){
|
|
|
+ String url = custom_message_url.replace("ACCESS_TOKEN", accessToken);
|
|
|
+
|
|
|
+ JSONObject requestBody = new JSONObject();
|
|
|
+ JSONObject textJson = new JSONObject();
|
|
|
+ textJson.put("content", message);
|
|
|
+
|
|
|
+ requestBody.put("touser",openId);
|
|
|
+ requestBody.put("msgtype","text");
|
|
|
+ requestBody.put("text",textJson);
|
|
|
+
|
|
|
+ JSONObject jsonObject = HttpConnectionUtil.httpRequest(url, "POST", requestBody.toString());
|
|
|
+
|
|
|
+ log.warn(jsonObject.toString());
|
|
|
+ }
|
|
|
|
|
|
public static UserInfo getUserInfo(String openid, String accessToken) {
|
|
|
// 拼装url
|
|
|
- String url = user_info_url.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);;
|
|
|
+ String url = user_info_url.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);
|
|
|
|
|
|
JSONObject jsonObject = HttpConnectionUtil.httpRequest(url, "GET", null);
|
|
|
|
|
@@ -151,6 +193,24 @@ public class WeixinUtil {
|
|
|
return userInfo;
|
|
|
}
|
|
|
|
|
|
+ public static String checkSubscribe(String openid, String accessToken) {
|
|
|
+ // 拼装url
|
|
|
+ String url = subscribe_user_info_url.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);;
|
|
|
+
|
|
|
+ JSONObject jsonObject = HttpConnectionUtil.httpRequest(url, "GET", null);
|
|
|
+
|
|
|
+ String subscribe = "";
|
|
|
+ if (null != jsonObject) {
|
|
|
+ try {
|
|
|
+ subscribe = jsonObject.getString("subscribe").replaceAll("\"", "");
|
|
|
+ } catch (JSONException e) {
|
|
|
+ // 获取token失败
|
|
|
+ log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return subscribe;
|
|
|
+ }
|
|
|
+
|
|
|
public static boolean checkSignature(String token,String signature, String timestamp, String nonce) {
|
|
|
String[] arr = new String[] { token, timestamp, nonce };
|
|
|
|
|
@@ -314,4 +374,86 @@ public class WeixinUtil {
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ public static String sendTemplateMessage(String appId,String appSecret,String templateId, String openId,JSONObject sendData,String urlPath) {
|
|
|
+ String result = "";
|
|
|
+
|
|
|
+ try {
|
|
|
+ AccessToken accessToken = WeixinUtil.getAccessToken(appId, appSecret);
|
|
|
+
|
|
|
+ if (accessToken == null) {
|
|
|
+ throw new Exception("token无法获取");
|
|
|
+ }
|
|
|
+
|
|
|
+ //发送模版内容
|
|
|
+ String sendTemplateUrl = send_template.replace("ACCESS_TOKEN", accessToken.getToken());
|
|
|
+
|
|
|
+ JSONObject sendTemplateData = new JSONObject();
|
|
|
+
|
|
|
+ sendTemplateData.put("touser", openId);
|
|
|
+ sendTemplateData.put("template_id", templateId);
|
|
|
+ sendTemplateData.put("url", urlPath);
|
|
|
+ sendTemplateData.put("data", sendData);
|
|
|
+
|
|
|
+ URL url = new URL(sendTemplateUrl);
|
|
|
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
|
+ conn.setRequestMethod("POST");
|
|
|
+ conn.setDoOutput(true);
|
|
|
+ conn.setDoInput(true);
|
|
|
+ conn.setUseCaches(false);
|
|
|
+ conn.setRequestProperty("Connection", "Keep-Alive");
|
|
|
+ conn.setRequestProperty("Charset", "UTF-8");
|
|
|
+
|
|
|
+ // 设置文件类型:
|
|
|
+ conn.setRequestProperty("Content-Type","application/json; charset=UTF-8");
|
|
|
+
|
|
|
+ // 设置接收类型否则返回415错误
|
|
|
+ //conn.setRequestProperty("accept","*/*")此处为暴力方法设置接受所有类型,以此来防范返回415;
|
|
|
+ conn.setRequestProperty("accept","application/json");
|
|
|
+ conn.setConnectTimeout(5000);
|
|
|
+ conn.setReadTimeout(5000);
|
|
|
+
|
|
|
+ String dataStr = sendTemplateData.toString();
|
|
|
+
|
|
|
+ log.warn("发送数据:" + dataStr);
|
|
|
+ // 往服务器里面发送数据
|
|
|
+ byte[] buffer = dataStr.getBytes("UTF-8");
|
|
|
+
|
|
|
+ // 设置文件长度
|
|
|
+ conn.setRequestProperty("Content-Length", String.valueOf(buffer.length));
|
|
|
+ OutputStream output = conn.getOutputStream();
|
|
|
+ output.write(buffer);
|
|
|
+ output.flush();
|
|
|
+ output.close();
|
|
|
+
|
|
|
+ if (conn.getResponseCode() == 200) {
|
|
|
+ BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
|
|
|
+
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ String line = "";
|
|
|
+
|
|
|
+ while ((line = reader.readLine()) != null) {
|
|
|
+ sb.append(line);
|
|
|
+ }
|
|
|
+
|
|
|
+ result = sb.toString();
|
|
|
+
|
|
|
+ log.warn("接收数据:" + result);
|
|
|
+
|
|
|
+ reader.close();
|
|
|
+ }
|
|
|
+ } catch (Exception ex) {
|
|
|
+ log.error(ex.getMessage(),ex);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ JSONObject sendData = JSONObject.fromObject("{\"first\":{\"value\":\"尊敬的用户,本次充电已结束!\",\"color\":\"#173177\"},\"keyword1\":{\"value\":\"地下停车场充电桩\",\"color\":\"#173177\"},\"keyword2\":{\"value\":\"2022-03-08 17:37:50至2022-03-08 17:44:41\",\"color\":\"#173177\"},\"keyword3\":{\"value\":\"6分钟\"},\"keyword4\":{\"value\":\"0.25元(账户余额:98.5元)\"}}");
|
|
|
+
|
|
|
+ sendTemplateMessage("wx7e70eb62a8459869",
|
|
|
+ "909d17e353268da57c4f18cc09798049",
|
|
|
+ "4gI6WtuROmqdnWEo0J9a6PO2sOrWIRr3_jqPcqbyhRM","oHjCawsxTJkxixR74OVp7aCKahj8",sendData,null);
|
|
|
+ }
|
|
|
}
|