Java微信公众平台开发之生成带参二维码
2017-06-26 09:52
447 查看
一定说明,这种方法我还没有测试,如果有疑问欢迎在评论区域讨论.
....................
...................
谢谢.
微信官方提供的生成二维码接口得到的是当前公众号的二维码。
目前有2种类型的二维码:
1、临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量,主要用于帐号绑定等不要求二维码永久保存的业务场景
2、永久二维码,是无过期时间的,但数量较少(目前为最多10万个),主要用于适用于帐号绑定、用户来源统计等场景
参考文档详见https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542&token=&lang=zh_CN
获取带参数的二维码的过程包括两步,首先创建二维码ticket,然后凭借ticket到指定URL换取二维码,但是得到ticket之前首先获取到access_token。
可以不写,因为我是每小时定时获取一次token存储到数据库或者直接存到application
[java] view
plain copy
print?
public class AccessToken {
// 获取到的凭证
private String token;
// 凭证有效时间,单位:秒
private int expiresIn;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
}
调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,否则将无法调用成功
[java] view
plain copy
print?
/**
* 获取access_token
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static String getAccessToken(String appid, String appsecret) {
String result = HttpRequestUtil.getAccessToken(appid,appsecret);
JSONObject jsonObject = JSONObject.fromObject(result);
if (null != jsonObject) {
try {
result = jsonObject.getString("access_token");
} catch (JSONException e) {
logger.info("获取token失败 errcode:"+jsonObject.getInt("errcode") +",errmsg:"+ jsonObject.getString("errmsg"));
}
}
return result;
}
[java] view
plain copy
print?
// 临时二维码
private final static String QR_SCENE = "QR_SCENE";
// 永久二维码
private final static String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";
// 永久二维码(字符串)
private final static String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";
// 创建二维码
private String create_ticket_path = "https://api.weixin.qq.com/cgi-bin/qrcode/create";
// 通过ticket换取二维码
private String showqrcode_path = "https://mp.weixin.qq.com/cgi-bin/showqrcode";
/**
* 创建临时带参数二维码
* @param accessToken
* @expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
* @param sceneId 场景Id
* @return
*/
public String createTempTicket(String accessToken, String expireSeconds, int sceneId) {
WeiXinQRCode wxQRCode = null;
TreeMap<String,String> params = new TreeMap<String,String>();
params.put("access_token", accessToken);
Map<String,Integer> intMap = new HashMap<String,Integer>();
intMap.put("scene_id",sceneId);
Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
mapMap.put("scene", intMap);
//
Map<String,Object> paramsMap = new HashMap<String,Object>();
paramsMap.put("expire_seconds", expireSeconds);
paramsMap.put("action_name", QR_SCENE);
paramsMap.put("action_info", mapMap);
String data = new Gson().toJson(paramsMap);
data = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
try {
wxQRCode = new Gson().fromJson(data, WeiXinQRCode.class);
} catch (JsonSyntaxException e) {
wxQRCode = null;
e.printStackTrace();
}
return wxQRCode==null?null:wxQRCode.getTicket();
}
/**
* 创建永久二维码(数字)
* @param accessToken
* @param sceneId 场景Id
* @return
*/
public String createForeverTicket(String accessToken, int sceneId) {
TreeMap<String,String> params = new TreeMap<String,String>();
params.put("access_token", accessToken);
//output data
Map<String,Integer> intMap = new HashMap<String,Integer>();
intMap.put("scene_id",sceneId);
Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
mapMap.put("scene", intMap);
//
Map<String,Object> paramsMap = new HashMap<String,Object>();
paramsMap.put("action_name", QR_LIMIT_SCENE);
paramsMap.put("action_info", mapMap);
String data = new Gson().toJson(paramsMap);
data = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
WeiXinQRCode wxQRCode = null;
try {
wxQRCode = new Gson().fromJson(data, WeiXinQRCode.class);
} catch (JsonSyntaxException e) {
wxQRCode = null;
e.printStackTrace();
}
return wxQRCode==null?null:wxQRCode.getTicket();
}
/**
* 创建永久二维码(字符串)
*
* @param accessToken
* @param sceneStr 场景str
* @return
*/
public String createForeverStrTicket(String accessToken, String sceneStr){
TreeMap<String,String> params = new TreeMap<String,String>();
params.put("access_token", accessToken);
//output data
Map<String,String> intMap = new HashMap<String,String>();
intMap.put("scene_str",sceneStr);
Map<String,Map<String,String>> mapMap = new HashMap<String,Map<String,String>>();
mapMap.put("scene", intMap);
Map<String,Object> paramsMap = new HashMap<String,Object>();
paramsMap.put("action_name", QR_LIMIT_STR_SCENE);
paramsMap.put("action_info", mapMap);
String data = new Gson().toJson(paramsMap);
data = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
WeiXinQRCode wxQRCode = null;
try {
wxQRCode = new Gson().fromJson(data, WeiXinQRCode.class);
} catch (JsonSyntaxException e) {
wxQRCode = null;
}
return wxQRCode==null?null:wxQRCode.getTicket();
}
强烈建议用测试号生成永久的
[java] view
plain copy
print?
/**
* 获取二维码ticket后,通过ticket换取二维码图片展示
* @param ticket
* @return
*/
public String showQrcode(String ticket){
Map<String,String> params = new TreeMap<String,String>();
params.put("ticket", HttpRequestUtil.urlEncode(ticket, HttpRequestUtil.DEFAULT_CHARSET));
try {
showqrcode_path = HttpRequestUtil.setParmas(params,showqrcode_path,"");
} catch (Exception e) {
e.printStackTrace();
}
return showqrcode_path;
}
/**
* 获取二维码ticket后,通过ticket换取二维码图片
* @param ticket
* @param savePath 保存的路径,例如 F:\\test\test.jpg
* @return Result.success = true 表示下载图片下载成功
*/
public WeiXinResult showQrcode(String ticket,String savePath) throws Exception{
TreeMap<String,String> params = new TreeMap<String,String>();
params.put("ticket", HttpRequestUtil.urlEncode(ticket, HttpRequestUtil.DEFAULT_CHARSET));
WeiXinResult result = HttpRequestUtil.downMeaterMetod(params,HttpRequestUtil.GET_METHOD,showqrcode_path,savePath);
return result;
}
如果没有关注的话,用户可以关注公众号,并且会这个场景值就是所谓的参数推送给开发者,参数是EventKey,直接用request获取即可,注意qrscene_的之后才是二维码的参数值
如果已经关注,微信会直接把场景值的扫描事件直接推送给开发者
WeiXinResult.Java
[java] view
plain copy
print?
/**
* 返回的结果对象
* @author fjing
*
*/
public class WeiXinResult {
public static final int NEWSMSG = 1; //图文消息
private boolean isSuccess;
private Object obj;
private int type;
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
HttpRequestUtil.java
[java] view
plain copy
print?
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import com.dingshu.model.result.WeiXinResult;
public class HttpRequestUtil {
//private static Logger logger = Logger.getLogger(HttpRequestUtil.class);
public static final String GET_METHOD = "GET";
public static final String POST_METHOD = "POST";
public static final String DEFAULT_CHARSET = "utf-8";
private static int DEFAULT_CONNTIME = 5000;
private static int DEFAULT_READTIME = 5000;
// 获取access_token的路径
private static String token_path = "https://api.weixin.qq.com/cgi-bin/token";
/**
* http请求
*
* @param method
* 请求方法GET/POST
* @param path
* 请求路径
* @param timeout
* 连接超时时间 默认为5000
* @param readTimeout
* 读取超时时间 默认为5000
* @param data 数据
* @return
*/
public static String defaultConnection(String method, String path, int timeout, int readTimeout, String data)
throws Exception {
String result = "";
URL url = new URL(path);
if (url != null) {
HttpURLConnection conn = getConnection(method, url);
conn.setConnectTimeout(timeout == 0 ? DEFAULT_CONNTIME : timeout);
conn.setReadTimeout(readTimeout == 0 ? DEFAULT_READTIME : readTimeout);
if (data != null && !"".equals(data)) {
OutputStream output = conn.getOutputStream();
output.write(data.getBytes(DEFAULT_CHARSET));
output.flush();
output.close();
}
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream input = conn.getInputStream();
result = inputToStr(input);
input.close();
conn.disconnect();
}
}
return result;
}
/**
* 根据url的协议选择对应的请求方式 例如 http://www.baidu.com 则使用http请求,https://www.baidu.com
* 则使用https请求
*
* @param method
* 请求的方法
* @return
* @throws IOException
*/
private static HttpURLConnection getConnection(String method, URL url) throws IOException {
HttpURLConnection conn = null;
if ("https".equals(url.getProtocol())) {
SSLContext context = null;
try {
context = SSLContext.getInstance("SSL", "SunJSSE");
context.init(new KeyManager[0], new TrustManager[] { new MyX509TrustManager() },
new java.security.SecureRandom());
} catch (Exception e) {
throw new IOException(e);
}
HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
connHttps.setSSLSocketFactory(context.getSocketFactory());
connHttps.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
conn = connHttps;
} else {
conn = (HttpURLConnection) url.openConnection();
}
conn.setRequestMethod(method);
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
return conn;
}
/**
* 将输入流转换为字符串
*
* @param input
* 输入流
* @return 转换后的字符串
*/
public static String inputToStr(InputStream input) {
String result = "";
if (input != null) {
byte[] array = new byte[1024];
StringBuffer buffer = new StringBuffer();
try {
for (int index; (index = (input.read(array))) > -1;) {
buffer.append(new String(array, 0, index, DEFAULT_CHARSET));
}
result = buffer.toString();
} catch (IOException e) {
e.printStackTrace();
result = "";
}
}
return result;
}
/**
* 设置参数
*
* @param map
* 参数map
* @param path
* 需要赋值的path
* @param charset
* 编码格式 默认编码为utf-8(取消默认)
* @return 已经赋值好的url 只需要访问即可
*/
public static String setParmas(Map<String, String> map, String path, String charset) throws Exception {
String result = "";
boolean hasParams = false;
if (path != null && !"".equals(path)) {
if (map != null && map.size() > 0) {
StringBuilder builder = new StringBuilder();
Set<Entry<String, String>> params = map.entrySet();
for (Entry<String, String> entry : params) {
String key = entry.getKey().trim();
String value = entry.getValue().trim();
if (hasParams) {
builder.append("&");
} else {
hasParams = true;
}
if(charset != null && !"".equals(charset)){
//builder.append(key).append("=").append(URLDecoder.(value, charset));
builder.append(key).append("=").append(urlEncode(value, charset));
}else{
builder.append(key).append("=").append(value);
}
}
result = builder.toString();
}
}
return doUrlPath(path, result).toString();
}
/**
* 设置连接参数
*
* @param path
* 路径
* @return
*/
private static URL doUrlPath(String path, String query) throws Exception {
URL url = new URL(path);
if (org.apache.commons.lang.StringUtils.isEmpty(path)) {
return url;
}
if (org.apache.commons.lang.StringUtils.isEmpty(url.getQuery())) {
if (path.endsWith("?")) {
path += query;
} else {
path = path + "?" + query;
}
} else {
if (path.endsWith("&")) {
path += query;
} else {
path = path + "&" + query;
}
}
return new URL(path);
}
/**
* 默认的http请求执行方法,返回
*
* @param method
* 请求的方法 POST/GET
* @param path
* 请求path 路径
* @param map
* 请求参数集合
* @param data
* 输入的数据 允许为空
* @return
*/
public static String HttpDefaultExecute(String method, String path, Map<String, String> map, String data) {
String result = "";
try {
String url = setParmas((TreeMap<String, String>) map, path, "");
result = defaultConnection(method, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 默认的https执行方法,返回
*
* @param method
* 请求的方法 POST/GET
* @param path
* 请求path 路径
* @param map
* 请求参数集合
* @param data
* 输入的数据 允许为空
* @return
*/
public static String HttpsDefaultExecute(String method, String path, Map<String, String> map, String data) {
String result = "";
try {
String url = setParmas((TreeMap<String, String>) map, path, "");
result = defaultConnection(method, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 获取授权token
*
* @param key 应用key
* @param secret 应用密匙
* @return json格式的字符串
*/
public static String getAccessToken(String key, String secret) {
TreeMap<String, String> map = new TreeMap<String, String>();
map.put("grant_type", "client_credential");
map.put("appid", key);
map.put("secret", secret);
String result = HttpDefaultExecute(GET_METHOD, token_path, map, "");
return result;
}
/**
* 默认的下载素材方法
*
* @param method http方法 POST/GET
* @param apiPath api路径
* @param savePath 素材需要保存的路径
* @return 是否下载成功 Reuslt.success==true 表示下载成功
*/
public static WeiXinResult downMeaterMetod(TreeMap<String, String> params, String method, String apiPath, String savePath) {
WeiXinResult result = new WeiXinResult();
try {
apiPath = setParmas(params, apiPath, "");
URL url = new URL(apiPath);
HttpURLConnection conn = getConnection(method, url);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
String contentType = conn.getContentType();
result = ContentType(contentType, conn, savePath);
} else {
result.setObj(conn.getResponseCode() + " " + conn.getResponseMessage());
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 根据返回的头信息返回具体信息
*
* @param contentType
* ContentType请求头信息
* @return Result.type==1 表示文本消息,
*/
private static WeiXinResult ContentType(String contentType, HttpURLConnection conn, String savePath) {
WeiXinResult result = new WeiXinResult();
try {
if (conn != null) {
InputStream input = conn.getInputStream();
if (contentType.equals("image/gif")) { // gif图片
result = InputStreamToMedia(input, savePath, "gif");
} else if (contentType.equals("image/jpeg")) { // jpg图片
result = InputStreamToMedia(input, savePath, "jpg");
} else if (contentType.equals("image/jpg")) { // jpg图片
result = InputStreamToMedia(input, savePath, "jpg");
} else if (contentType.equals("image/png")) { // png图片
result = InputStreamToMedia(input, savePath, "png");
} else if (contentType.equals("image/bmp")) { // bmp图片
result = InputStreamToMedia(input, savePath, "bmp");
} else if (contentType.equals("audio/x-wav")) { // wav语音
result = InputStreamToMedia(input, savePath, "wav");
} else if (contentType.equals("audio/x-ms-wma")) { // wma语言
result = InputStreamToMedia(input, savePath, "wma");
} else if (contentType.equals("audio/mpeg")) { // mp3语言
result = InputStreamToMedia(input, savePath, "mp3");
} else if (contentType.equals("text/plain")) { // 文本信息
String str = inputToStr(input);
result.setObj(str);
} else if (contentType.equals("application/json")) { // 返回json格式的数据
String str = inputToStr(input);
result.setObj(str);
} else { // 此处有问题
String str = inputToStr(input);
result.setObj(str);
}
} else {
result.setObj("conn is null!");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
/**
* 将字符流转换为图片文件
*
* @param input 字符流
* @param savePath 图片需要保存的路径
* @param 类型 jpg/png等
* @return
*/
private static WeiXinResult InputStreamToMedia(InputStream input, String savePath, String type) {
WeiXinResult result = new WeiXinResult();
try {
File file = null;
file = new File(savePath);
String paramPath = file.getParent(); // 路径
String fileName = file.getName(); //
String newName = fileName.substring(0, fileName.lastIndexOf(".")) + "." + type;// 根据实际返回的文件类型后缀
savePath = paramPath + "\\" + newName;
if (!file.exists()) {
File dirFile = new File(paramPath);
dirFile.mkdirs();
}
file = new File(savePath);
FileOutputStream output = new FileOutputStream(file);
int len = 0;
byte[] array = new byte[1024];
while ((len = input.read(array)) != -1) {
output.write(array, 0, len);
}
output.flush();
output.close();
result.setSuccess(true);
result.setObj("save success!");
} catch (FileNotFoundException e) {
e.printStackTrace();
result.setSuccess(false);
result.setObj(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
result.setSuccess(false);
result.setObj(e.getMessage());
}
return result;
}
public static String urlEncode(String source, String encode) {
String result = source;
try {
result = URLEncoder.encode(source, encode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
}
信任管理器MyX509TrustManager,实现方法自己定义(反正我没写)
[java] view
plain copy
print?
/**
* 信任管理器
* @author fjing
*
*/
public class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
....................
...................
谢谢.
微信官方提供的生成二维码接口得到的是当前公众号的二维码。
目前有2种类型的二维码:
1、临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量,主要用于帐号绑定等不要求二维码永久保存的业务场景
2、永久二维码,是无过期时间的,但数量较少(目前为最多10万个),主要用于适用于帐号绑定、用户来源统计等场景
参考文档详见https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542&token=&lang=zh_CN
获取带参数的二维码的过程包括两步,首先创建二维码ticket,然后凭借ticket到指定URL换取二维码,但是得到ticket之前首先获取到access_token。
1.创建access_token的bean
可以不写,因为我是每小时定时获取一次token存储到数据库或者直接存到application[java] view
plain copy
print?
public class AccessToken {
// 获取到的凭证
private String token;
// 凭证有效时间,单位:秒
private int expiresIn;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
}
2.创建获取accessToken的方法
调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,否则将无法调用成功[java] view
plain copy
print?
/**
* 获取access_token
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static String getAccessToken(String appid, String appsecret) {
String result = HttpRequestUtil.getAccessToken(appid,appsecret);
JSONObject jsonObject = JSONObject.fromObject(result);
if (null != jsonObject) {
try {
result = jsonObject.getString("access_token");
} catch (JSONException e) {
logger.info("获取token失败 errcode:"+jsonObject.getInt("errcode") +",errmsg:"+ jsonObject.getString("errmsg"));
}
}
return result;
}
3.获取二维码的Ticket
[java] viewplain copy
print?
// 临时二维码
private final static String QR_SCENE = "QR_SCENE";
// 永久二维码
private final static String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";
// 永久二维码(字符串)
private final static String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";
// 创建二维码
private String create_ticket_path = "https://api.weixin.qq.com/cgi-bin/qrcode/create";
// 通过ticket换取二维码
private String showqrcode_path = "https://mp.weixin.qq.com/cgi-bin/showqrcode";
/**
* 创建临时带参数二维码
* @param accessToken
* @expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
* @param sceneId 场景Id
* @return
*/
public String createTempTicket(String accessToken, String expireSeconds, int sceneId) {
WeiXinQRCode wxQRCode = null;
TreeMap<String,String> params = new TreeMap<String,String>();
params.put("access_token", accessToken);
Map<String,Integer> intMap = new HashMap<String,Integer>();
intMap.put("scene_id",sceneId);
Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
mapMap.put("scene", intMap);
//
Map<String,Object> paramsMap = new HashMap<String,Object>();
paramsMap.put("expire_seconds", expireSeconds);
paramsMap.put("action_name", QR_SCENE);
paramsMap.put("action_info", mapMap);
String data = new Gson().toJson(paramsMap);
data = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
try {
wxQRCode = new Gson().fromJson(data, WeiXinQRCode.class);
} catch (JsonSyntaxException e) {
wxQRCode = null;
e.printStackTrace();
}
return wxQRCode==null?null:wxQRCode.getTicket();
}
/**
* 创建永久二维码(数字)
* @param accessToken
* @param sceneId 场景Id
* @return
*/
public String createForeverTicket(String accessToken, int sceneId) {
TreeMap<String,String> params = new TreeMap<String,String>();
params.put("access_token", accessToken);
//output data
Map<String,Integer> intMap = new HashMap<String,Integer>();
intMap.put("scene_id",sceneId);
Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
mapMap.put("scene", intMap);
//
Map<String,Object> paramsMap = new HashMap<String,Object>();
paramsMap.put("action_name", QR_LIMIT_SCENE);
paramsMap.put("action_info", mapMap);
String data = new Gson().toJson(paramsMap);
data = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
WeiXinQRCode wxQRCode = null;
try {
wxQRCode = new Gson().fromJson(data, WeiXinQRCode.class);
} catch (JsonSyntaxException e) {
wxQRCode = null;
e.printStackTrace();
}
return wxQRCode==null?null:wxQRCode.getTicket();
}
/**
* 创建永久二维码(字符串)
*
* @param accessToken
* @param sceneStr 场景str
* @return
*/
public String createForeverStrTicket(String accessToken, String sceneStr){
TreeMap<String,String> params = new TreeMap<String,String>();
params.put("access_token", accessToken);
//output data
Map<String,String> intMap = new HashMap<String,String>();
intMap.put("scene_str",sceneStr);
Map<String,Map<String,String>> mapMap = new HashMap<String,Map<String,String>>();
mapMap.put("scene", intMap);
Map<String,Object> paramsMap = new HashMap<String,Object>();
paramsMap.put("action_name", QR_LIMIT_STR_SCENE);
paramsMap.put("action_info", mapMap);
String data = new Gson().toJson(paramsMap);
data = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
WeiXinQRCode wxQRCode = null;
try {
wxQRCode = new Gson().fromJson(data, WeiXinQRCode.class);
} catch (JsonSyntaxException e) {
wxQRCode = null;
}
return wxQRCode==null?null:wxQRCode.getTicket();
}
强烈建议用测试号生成永久的
4.通过ticket凭证直接获取二维码
[java] viewplain copy
print?
/**
* 获取二维码ticket后,通过ticket换取二维码图片展示
* @param ticket
* @return
*/
public String showQrcode(String ticket){
Map<String,String> params = new TreeMap<String,String>();
params.put("ticket", HttpRequestUtil.urlEncode(ticket, HttpRequestUtil.DEFAULT_CHARSET));
try {
showqrcode_path = HttpRequestUtil.setParmas(params,showqrcode_path,"");
} catch (Exception e) {
e.printStackTrace();
}
return showqrcode_path;
}
/**
* 获取二维码ticket后,通过ticket换取二维码图片
* @param ticket
* @param savePath 保存的路径,例如 F:\\test\test.jpg
* @return Result.success = true 表示下载图片下载成功
*/
public WeiXinResult showQrcode(String ticket,String savePath) throws Exception{
TreeMap<String,String> params = new TreeMap<String,String>();
params.put("ticket", HttpRequestUtil.urlEncode(ticket, HttpRequestUtil.DEFAULT_CHARSET));
WeiXinResult result = HttpRequestUtil.downMeaterMetod(params,HttpRequestUtil.GET_METHOD,showqrcode_path,savePath);
return result;
}
5.用户扫描带参数的二维码的处理
如果没有关注的话,用户可以关注公众号,并且会这个场景值就是所谓的参数推送给开发者,参数是EventKey,直接用request获取即可,注意qrscene_的之后才是二维码的参数值如果已经关注,微信会直接把场景值的扫描事件直接推送给开发者
6.参考类
WeiXinResult.Java[java] view
plain copy
print?
/**
* 返回的结果对象
* @author fjing
*
*/
public class WeiXinResult {
public static final int NEWSMSG = 1; //图文消息
private boolean isSuccess;
private Object obj;
private int type;
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
HttpRequestUtil.java
[java] view
plain copy
print?
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import com.dingshu.model.result.WeiXinResult;
public class HttpRequestUtil {
//private static Logger logger = Logger.getLogger(HttpRequestUtil.class);
public static final String GET_METHOD = "GET";
public static final String POST_METHOD = "POST";
public static final String DEFAULT_CHARSET = "utf-8";
private static int DEFAULT_CONNTIME = 5000;
private static int DEFAULT_READTIME = 5000;
// 获取access_token的路径
private static String token_path = "https://api.weixin.qq.com/cgi-bin/token";
/**
* http请求
*
* @param method
* 请求方法GET/POST
* @param path
* 请求路径
* @param timeout
* 连接超时时间 默认为5000
* @param readTimeout
* 读取超时时间 默认为5000
* @param data 数据
* @return
*/
public static String defaultConnection(String method, String path, int timeout, int readTimeout, String data)
throws Exception {
String result = "";
URL url = new URL(path);
if (url != null) {
HttpURLConnection conn = getConnection(method, url);
conn.setConnectTimeout(timeout == 0 ? DEFAULT_CONNTIME : timeout);
conn.setReadTimeout(readTimeout == 0 ? DEFAULT_READTIME : readTimeout);
if (data != null && !"".equals(data)) {
OutputStream output = conn.getOutputStream();
output.write(data.getBytes(DEFAULT_CHARSET));
output.flush();
output.close();
}
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream input = conn.getInputStream();
result = inputToStr(input);
input.close();
conn.disconnect();
}
}
return result;
}
/**
* 根据url的协议选择对应的请求方式 例如 http://www.baidu.com 则使用http请求,https://www.baidu.com
* 则使用https请求
*
* @param method
* 请求的方法
* @return
* @throws IOException
*/
private static HttpURLConnection getConnection(String method, URL url) throws IOException {
HttpURLConnection conn = null;
if ("https".equals(url.getProtocol())) {
SSLContext context = null;
try {
context = SSLContext.getInstance("SSL", "SunJSSE");
context.init(new KeyManager[0], new TrustManager[] { new MyX509TrustManager() },
new java.security.SecureRandom());
} catch (Exception e) {
throw new IOException(e);
}
HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
connHttps.setSSLSocketFactory(context.getSocketFactory());
connHttps.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
conn = connHttps;
} else {
conn = (HttpURLConnection) url.openConnection();
}
conn.setRequestMethod(method);
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
return conn;
}
/**
* 将输入流转换为字符串
*
* @param input
* 输入流
* @return 转换后的字符串
*/
public static String inputToStr(InputStream input) {
String result = "";
if (input != null) {
byte[] array = new byte[1024];
StringBuffer buffer = new StringBuffer();
try {
for (int index; (index = (input.read(array))) > -1;) {
buffer.append(new String(array, 0, index, DEFAULT_CHARSET));
}
result = buffer.toString();
} catch (IOException e) {
e.printStackTrace();
result = "";
}
}
return result;
}
/**
* 设置参数
*
* @param map
* 参数map
* @param path
* 需要赋值的path
* @param charset
* 编码格式 默认编码为utf-8(取消默认)
* @return 已经赋值好的url 只需要访问即可
*/
public static String setParmas(Map<String, String> map, String path, String charset) throws Exception {
String result = "";
boolean hasParams = false;
if (path != null && !"".equals(path)) {
if (map != null && map.size() > 0) {
StringBuilder builder = new StringBuilder();
Set<Entry<String, String>> params = map.entrySet();
for (Entry<String, String> entry : params) {
String key = entry.getKey().trim();
String value = entry.getValue().trim();
if (hasParams) {
builder.append("&");
} else {
hasParams = true;
}
if(charset != null && !"".equals(charset)){
//builder.append(key).append("=").append(URLDecoder.(value, charset));
builder.append(key).append("=").append(urlEncode(value, charset));
}else{
builder.append(key).append("=").append(value);
}
}
result = builder.toString();
}
}
return doUrlPath(path, result).toString();
}
/**
* 设置连接参数
*
* @param path
* 路径
* @return
*/
private static URL doUrlPath(String path, String query) throws Exception {
URL url = new URL(path);
if (org.apache.commons.lang.StringUtils.isEmpty(path)) {
return url;
}
if (org.apache.commons.lang.StringUtils.isEmpty(url.getQuery())) {
if (path.endsWith("?")) {
path += query;
} else {
path = path + "?" + query;
}
} else {
if (path.endsWith("&")) {
path += query;
} else {
path = path + "&" + query;
}
}
return new URL(path);
}
/**
* 默认的http请求执行方法,返回
*
* @param method
* 请求的方法 POST/GET
* @param path
* 请求path 路径
* @param map
* 请求参数集合
* @param data
* 输入的数据 允许为空
* @return
*/
public static String HttpDefaultExecute(String method, String path, Map<String, String> map, String data) {
String result = "";
try {
String url = setParmas((TreeMap<String, String>) map, path, "");
result = defaultConnection(method, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 默认的https执行方法,返回
*
* @param method
* 请求的方法 POST/GET
* @param path
* 请求path 路径
* @param map
* 请求参数集合
* @param data
* 输入的数据 允许为空
* @return
*/
public static String HttpsDefaultExecute(String method, String path, Map<String, String> map, String data) {
String result = "";
try {
String url = setParmas((TreeMap<String, String>) map, path, "");
result = defaultConnection(method, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 获取授权token
*
* @param key 应用key
* @param secret 应用密匙
* @return json格式的字符串
*/
public static String getAccessToken(String key, String secret) {
TreeMap<String, String> map = new TreeMap<String, String>();
map.put("grant_type", "client_credential");
map.put("appid", key);
map.put("secret", secret);
String result = HttpDefaultExecute(GET_METHOD, token_path, map, "");
return result;
}
/**
* 默认的下载素材方法
*
* @param method http方法 POST/GET
* @param apiPath api路径
* @param savePath 素材需要保存的路径
* @return 是否下载成功 Reuslt.success==true 表示下载成功
*/
public static WeiXinResult downMeaterMetod(TreeMap<String, String> params, String method, String apiPath, String savePath) {
WeiXinResult result = new WeiXinResult();
try {
apiPath = setParmas(params, apiPath, "");
URL url = new URL(apiPath);
HttpURLConnection conn = getConnection(method, url);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
String contentType = conn.getContentType();
result = ContentType(contentType, conn, savePath);
} else {
result.setObj(conn.getResponseCode() + " " + conn.getResponseMessage());
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 根据返回的头信息返回具体信息
*
* @param contentType
* ContentType请求头信息
* @return Result.type==1 表示文本消息,
*/
private static WeiXinResult ContentType(String contentType, HttpURLConnection conn, String savePath) {
WeiXinResult result = new WeiXinResult();
try {
if (conn != null) {
InputStream input = conn.getInputStream();
if (contentType.equals("image/gif")) { // gif图片
result = InputStreamToMedia(input, savePath, "gif");
} else if (contentType.equals("image/jpeg")) { // jpg图片
result = InputStreamToMedia(input, savePath, "jpg");
} else if (contentType.equals("image/jpg")) { // jpg图片
result = InputStreamToMedia(input, savePath, "jpg");
} else if (contentType.equals("image/png")) { // png图片
result = InputStreamToMedia(input, savePath, "png");
} else if (contentType.equals("image/bmp")) { // bmp图片
result = InputStreamToMedia(input, savePath, "bmp");
} else if (contentType.equals("audio/x-wav")) { // wav语音
result = InputStreamToMedia(input, savePath, "wav");
} else if (contentType.equals("audio/x-ms-wma")) { // wma语言
result = InputStreamToMedia(input, savePath, "wma");
} else if (contentType.equals("audio/mpeg")) { // mp3语言
result = InputStreamToMedia(input, savePath, "mp3");
} else if (contentType.equals("text/plain")) { // 文本信息
String str = inputToStr(input);
result.setObj(str);
} else if (contentType.equals("application/json")) { // 返回json格式的数据
String str = inputToStr(input);
result.setObj(str);
} else { // 此处有问题
String str = inputToStr(input);
result.setObj(str);
}
} else {
result.setObj("conn is null!");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
/**
* 将字符流转换为图片文件
*
* @param input 字符流
* @param savePath 图片需要保存的路径
* @param 类型 jpg/png等
* @return
*/
private static WeiXinResult InputStreamToMedia(InputStream input, String savePath, String type) {
WeiXinResult result = new WeiXinResult();
try {
File file = null;
file = new File(savePath);
String paramPath = file.getParent(); // 路径
String fileName = file.getName(); //
String newName = fileName.substring(0, fileName.lastIndexOf(".")) + "." + type;// 根据实际返回的文件类型后缀
savePath = paramPath + "\\" + newName;
if (!file.exists()) {
File dirFile = new File(paramPath);
dirFile.mkdirs();
}
file = new File(savePath);
FileOutputStream output = new FileOutputStream(file);
int len = 0;
byte[] array = new byte[1024];
while ((len = input.read(array)) != -1) {
output.write(array, 0, len);
}
output.flush();
output.close();
result.setSuccess(true);
result.setObj("save success!");
} catch (FileNotFoundException e) {
e.printStackTrace();
result.setSuccess(false);
result.setObj(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
result.setSuccess(false);
result.setObj(e.getMessage());
}
return result;
}
public static String urlEncode(String source, String encode) {
String result = source;
try {
result = URLEncoder.encode(source, encode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
}
信任管理器MyX509TrustManager,实现方法自己定义(反正我没写)
[java] view
plain copy
print?
/**
* 信任管理器
* @author fjing
*
*/
public class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
相关文章推荐
- Java微信公众平台开发之生成带参二维码
- Java微信公众平台开发之生成带参二维码
- 微信公众平台开发 批量生成及下载带参二维码图片
- 生成带参二维码--微信公众平台开发(二)
- 生成带参二维码--微信公众平台开发(二)
- 微信公众平台开发(83) 生成带参数二维码
- 微信公众平台开发(83) 生成带参数二维码
- 微信公众平台开发(83) 生成带参数二维码
- java开发_生成/解析自己的QRCode二维码
- java开发_生成/解析自己的QRCode二维码
- 微信公众平台开发(83) 生成带参数二维码(转)
- 微信公众平台开发(83) 生成带参数二维码
- JAVA开发--[二维码名片生成系统]
- 微信公众平台开发(83) 生成带参数二维码
- 微信公众平台开发文档 生成带参数的二维码
- 微信公众号开发---生成带参二维码
- 微信公众平台 ---------java实现二维码带参生成本地图片(2017/11/10更新版)
- 毛超帅 使用 jquery.qrcode.js 生成网站地址url二维码图片______软件开发-JAVA
- 微信公众平台开发(83) 生成带参数二维码
- 微信公众平台开发文档 生成带参数的二维码