您的位置:首页 > 移动开发 > 微信开发

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。


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] 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();

}

强烈建议用测试号生成永久的


4.通过ticket凭证直接获取二维码

[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;

}


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;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: