一、獲取access_token
官方文檔:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
可使用微信公衆平臺接口調試工具進行調試(登錄公衆號後,在左側導航欄可找到“開發者工具”,選擇第二項“在線接口調試工具”即可進行接口調試。):https://mp.weixin.qq.com/debug?token=1803714957&lang=zh_CN
首先我們需要獲取access_token,有效期7200s,一天獲取上限爲2000次
代碼實例:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.json.JSONObject;
public class xiaoqiang {
public static final String appid = "xxxxxxxxxxxxxxxxxx";
public static final String appsecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static Logger loger = LoggerFactory.getLogger(xiaoqiang.class);
public static void main(String args[]) {
System.out.println(getWXAccessToken());
}
public static String getWXAccessToken() {
String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?" +
"grant_type=client_credential" +
// 此處填寫你自己的appid
"&appid=" + appid +
// 此處填寫你自己的appsecret
"&secret=" + appsecret;
JSONObject jsonObject = httpsRequest(accessTokenUrl, "GET", null);
return (String) jsonObject.get("access_token");
}
/**
* 發送https請求
* @param requestUrl 請求地址
* @param requestMethod 請求方式(GET、POST)
* @param data 提交的數據
* @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值)
*/
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String data) {
JSONObject jsonObject = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 設置請求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.connect();
// 當data不爲null時向輸出流寫數據
if (null != data) {
// getOutputStream方法隱藏了connect()方法
OutputStream outputStream = conn.getOutputStream();
// 注意編碼格式
outputStream.write(data.getBytes("UTF-8"));
outputStream.close();
}
// 從輸入流讀取返回內容
inputStream = conn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "utf-8");
bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
conn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
return jsonObject;
} catch (Exception e) {
loger.error("發送https請求失敗,失敗", e);
return null;
} finally {
// 釋放資源
try {
if(null != inputStream) {
inputStream.close();
}
if(null != inputStreamReader) {
inputStreamReader.close();
}
if(null != bufferedReader) {
bufferedReader.close();
}
} catch (IOException e) {
loger.error("釋放資源失敗,失敗", e);
}
}
}
}
注意:你可能會出現如下圖所示“org.apache.commons.lang.exception.NestableRuntimeException”的報錯
參考:https://blog.csdn.net/gu_gu_/article/details/50551775
解決:在pom.xml文件中加入下面的配置
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.1</version>
</dependency>
注意:我們需要現在微信公衆平臺設置 IP白名單,也就是本機的外網IP地址,否則無法獲取access_token
二、獲取微信公衆號二維碼
說明:可以和上一篇文章“事件推送”配合使用。爲了滿足用戶渠道推廣分析的需要,公衆平臺提供了生成帶參數二維碼的接口。使用該接口可以獲得多個帶不同場景值的二維碼,用戶掃描後,公衆號可以接收到事件推送。
目前有2種類型的二維碼,分別是臨時二維碼和永久二維碼,前者有過期時間,最大爲1800秒,但能夠生成較多數量,後者無過期時間,數量較少(目前參數只支持1–100000)。兩種二維碼分別適用於帳號綁定、用戶來源統計等場景。
用戶掃描帶場景值二維碼時,可能推送以下兩種事件:
如果用戶還未關注公衆號,則用戶可以關注公衆號,關注後微信會將帶場景值關注事件推送給開發者。
如果用戶已經關注公衆號,在用戶掃描後會自動進入會話,微信也會將帶場景值掃描事件推送給開發者。
獲取帶參數的二維碼的過程包括兩步,首先創建二維碼ticket,然後憑藉ticket到指定URL換取二維碼。
官方文檔:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542
代碼實例:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import net.sf.json.JSONObject;
public class xiaoqiang {
public static final String appid = "xxxxxxxxxxxxxxxxxx";
public static final String appsecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static Logger loger = LoggerFactory.getLogger(xiaoqiang.class);
public static void main(String args[]) throws UnsupportedEncodingException {
// System.out.println(getWXAccessToken());
getWXPublicQRCode("1",123,"hehe");
}
/**
* 獲取微信公衆號二維碼
* @param codeType 二維碼類型 "1": 臨時二維碼 "2": 永久二維碼
* @param sceneId 場景值ID
* scene_id 場景值ID,臨時二維碼時爲32位非0整型,永久二維碼時最大值爲100000(目前參數只支持1--100000)
* scene_str 場景值ID(字符串形式的ID),字符串類型,長度限制爲1到64
* @param fileName 圖片名稱
* @throws UnsupportedEncodingException
*/
public static void getWXPublicQRCode(String codeType, Integer sceneId, String fileName) throws UnsupportedEncodingException {
// String wxAccessToken = getWXAccessToken(); // 這裏爲了省略代碼,可參考第一步獲取access_token
Map<String, Object> map = new HashMap<>();
if ("1".equals(codeType)) { // 臨時二維碼
map.put("expire_seconds", 604800);
map.put("action_name", "QR_SCENE");
Map<String, Object> sceneMap = new HashMap<>();
Map<String, Object> sceneIdMap = new HashMap<>();
sceneIdMap.put("scene_id", sceneId);
sceneMap.put("scene", sceneIdMap);
map.put("action_info", sceneMap);
} else if ("2".equals(codeType)) { // 永久二維碼
map.put("action_name", "QR_LIMIT_SCENE");
Map<String, Object> sceneMap = new HashMap<>();
Map<String, Object> sceneIdMap = new HashMap<>();
sceneIdMap.put("scene_id", sceneId);
sceneMap.put("scene", sceneIdMap);
map.put("action_info", sceneMap);
}
String data = JSON.toJSONString(map);
// 得到ticket票據,用於換取二維碼圖片
JSONObject jsonObject = httpsRequest("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + wxAccessToken, "POST", data);
String ticket = (String) jsonObject.get("ticket");
// WXConstants.QRCODE_SAVE_URL: 填寫存放圖片的路徑
httpsRequestPicture("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" +
URLEncoder.encode(ticket, "UTF-8"), //URLEncoder.encode(ticket)已不建議使用
"GET", null, "C:\\Users\\Administrator\\Desktop", fileName, "png");
}
/**
* 發送https請求,返回二維碼圖片
* @param requestUrl 請求地址
* @param requestMethod 請求方式(GET、POST)
* @param data 提交的數據
* @param savePath 圖片保存路徑
* @param fileName 圖片名稱
* @param fileType 圖片類型
*/
public static void httpsRequestPicture(String requestUrl, String requestMethod, String data, String savePath, String fileName, String fileType) {
InputStream inputStream = null;
try {
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
//設置請求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.connect();
//當data不爲null時向輸出流寫數據
if (null != data) {
//getOutputStream方法隱藏了connect()方法
OutputStream outputStream = conn.getOutputStream();
//注意編碼格式
outputStream.write(data.getBytes("UTF-8"));
outputStream.close();
}
// 從輸入流讀取返回內容
inputStream = conn.getInputStream();
loger.info("開始生成微信二維碼...");
inputStreamToMedia(inputStream, savePath, fileName, fileType);
loger.info("微信二維碼生成成功!!!");
conn.disconnect();
} catch (Exception e) {
loger.error("發送https請求失敗,失敗", e);
}finally {
//釋放資源
try {
if(null != inputStream) {
inputStream.close();
}
} catch (IOException e) {
loger.error("釋放資源失敗,失敗", e);
}
}
}
/**
* 將輸入流轉換爲圖片
* @param input 輸入流
* @param savePath 圖片需要保存的路徑
* @param fileType 圖片類型
*/
public static void inputStreamToMedia(InputStream input, String savePath, String fileName, String fileType) throws Exception {
String filePath = savePath + "/" + fileName + "." + fileType;
File file = new File(filePath);
FileOutputStream outputStream = new FileOutputStream(file);
int length;
byte[] data = new byte[1024];
while ((length = input.read(data)) != -1) {
outputStream.write(data, 0, length);
}
outputStream.flush();
outputStream.close();
}
}
參考:
https://blog.csdn.net/goodbye_youth/article/details/80653132