微信官方提供的生成二维码接口得到的是当前公众号的二维码点击查看
目前有2种类型的二维码:
- 临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量,主要用于帐号绑定等不要求二维码永久保存的业务场景
- 永久二维码,是无过期时间的,但数量较少(目前为最多10万个),主要用于适用于帐号绑定、用户来源统计等场景
获取带参数的二维码有两种方法
- 先获取二维码ticket,然后凭借ticket通过接口换取二维码图片,但是得到ticket之前首先得获取微信全局唯一接口调用凭据
- 根据微信返回二维码中url参数自行生成二维码
一、获取微信全局接口调用凭证
package com.phil.wechatauth.entity; import javax.persistence.Column; import com.google.gson.annotations.SerializedName; /** * 微信的access_token * @author phil * @date 2017年7月9日 * */ public class WechatAccessToken { @SerializedName("access_token") private String token; public String getToken() { return token; } public void setToken(String token) { this.token = token; } }
调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,否则将无法调用成功
/** * 获取授权token * @param key 应用key * @param secret 应用密匙 * @return */ public 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 = HttpReqUtil.HttpsDefaultExecute(HttpReqUtil.GET_METHOD, WeChatConfig.TOKEN_PATH, map, null); Gson gson = new Gson(); WechatAccessToken accessToken = gson.fromJson(result, WechatAccessToken.class); gson = null; return accessToken==null?null:accessToken.getToken(); }
二、获取二维码的Ticket
/** * 创建临时带参数二维码 * * @param accessToken * @expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 * @param sceneId 场景Id * @return */ public String createTempTicket(String accessToken, String expireSeconds, int sceneId) { WechatQRCode wechatQRCode = 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", WeChatConfig.QR_SCENE); paramsMap.put("action_info", mapMap); Gson gson = new Gson(); String data = gson.toJson(paramsMap); data = HttpReqUtil.HttpsDefaultExecute(HttpReqUtil.POST_METHOD, WeChatConfig.CREATE_TICKET_PATH, params, data); try { wechatQRCode = gson.fromJson(data, WechatQRCode.class); gson = null; } catch (JsonSyntaxException e) { e.printStackTrace(); } return wechatQRCode == null ? null : wechatQRCode.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", WeChatConfig.QR_LIMIT_SCENE); paramsMap.put("action_info", mapMap); Gson gson = new Gson(); String data = gson.toJson(paramsMap); data = HttpReqUtil.HttpsDefaultExecute(HttpReqUtil.POST_METHOD, WeChatConfig.CREATE_TICKET_PATH, params, data); WechatQRCode wechatQRCode = null; try { wechatQRCode = gson.fromJson(data, WechatQRCode.class); gson = null; } catch (JsonSyntaxException e) { e.printStackTrace(); } return wechatQRCode == null ? null : wechatQRCode.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", WeChatConfig.QR_LIMIT_STR_SCENE); paramsMap.put("action_info", mapMap); Gson gson = new Gson(); String data = gson.toJson(paramsMap); data = HttpReqUtil.HttpsDefaultExecute(HttpReqUtil.POST_METHOD, WeChatConfig.CREATE_TICKET_PATH, params, data); WechatQRCode wechatQRCode = null; try { wechatQRCode = gson.fromJson(data, WechatQRCode.class); gson = null; } catch (JsonSyntaxException e) { e.printStackTrace(); } return wechatQRCode == null ? null : wechatQRCode.getTicket(); }
强烈建议用测试号生成永久的,正式的会占用使用数量
三、二维码长链接转成短链接
微信返回正确的二维码的结果,参数有个url,即二维码图片解析后的地址,也可以根据此URL生成需要的二维码图片,而不需要通过ticket去换取图片了
/** * 长链接转短链接 * @param accessToken * @param longUrl 长链接 * @return */ public String shortQRCodeurl(String accessToken, String longUrl){ TreeMap<String, String> params = new TreeMap<String, String>(); params.put("access_token", accessToken); Map<String, Object> paramsMap = new HashMap<String, Object>(); paramsMap.put("action", "long2short"); paramsMap.put("long_url", longUrl); Gson gson = new Gson(); String data = gson.toJson(paramsMap); String result = HttpReqUtil.HttpsDefaultExecute(HttpReqUtil.POST_METHOD, WeChatConfig.WECHAT_SHORT_QRCODE_URL, params, data); WechatQRCodeShortUrl wechatQRCodeShortUrl = gson.fromJson(result, WechatQRCodeShortUrl.class); gson = null; return wechatQRCodeShortUrl.getShort_url(); }
四、通过ticket凭证直接获取二维码
/** * 获取二维码ticket后,通过ticket换取二维码图片展示 * @param ticket * @return 二维码图片地址 * @throws Exception */ public String showQrcode(String ticket) throws Exception { return HttpReqUtil.setParmas(params(ticket), WeChatConfig.SHOW_QRCODE_PATH, null); } /** * 下载二维码 * * @param ticket * @param savePath 保存的路径,例如 F:\\phil\phil.jpg * @return Result.success = true 表示下载图片下载成功 */ public WechatResult showQrcode(String ticket, String savePath) throws Exception { return HttpReqUtil.downMeaterMetod(params(ticket), HttpReqUtil.GET_METHOD, WeChatConfig.SHOW_QRCODE_PATH, savePath); } private TreeMap<String, String> params(String ticket) { TreeMap<String, String> params = new TreeMap<String, String>(); params.put("ticket", HttpReqUtil.urlEncode(ticket, SystemConfig.CHARACTER_ENCODING)); return params; }
五、扫描带参数二维码事件推送
这个推送的XML信息通过之前开发者中心处设置的服务器地址获得,故得先接入
已关注推送XML示例
<xml><ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> <EventKey><![CDATA[qrscene_123123]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml>
EventKey事件KEY值,qrscene_为前缀,后面为二维码的参数值
未关注推送XML示例
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[SCAN]]></Event> <EventKey><![CDATA[SCENE_VALUE]]></EventKey> <Ticket><![CDATA[TICKET]]></Ticket> </xml>
EventKey事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id参考xml处理方式
六、参考类
WechatQRCode.java
package com.phil.wechatqrcode.model; /** * 微信带参二维码 * @author phil * @date 2017年6月7日 * */ public class WechatQRCode { // 获取的二维码 private String ticket; // 二维码的有效时间,单位为秒,最大不超过2592000(即30天) private int expire_seconds; // 二维码图片解析后的地址 private String url; public String getTicket() { return ticket; } public void setTicket(String ticket) { this.ticket = ticket; } public int getExpire_seconds() { return expire_seconds; } public void setExpire_seconds(int expire_seconds) { this.expire_seconds = expire_seconds; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
ResultState.java
package com.phil.common.result; import java.io.Serializable; /** * 微信API返回状态 * * @author phil * @date 2017年7月2日 * */ public class ResultState implements Serializable { /** * */ private static final long serialVersionUID = 1692432930341768342L; //@SerializedName("errcode") private int errcode; // 状态 //@SerializedName("errmsg") private String errmsg; //信息 public int getErrcode() { return errcode; } public void setErrcode(int errcode) { this.errcode = errcode; } public String getErrmsg() { return errmsg; } public void setErrmsg(String errmsg) { this.errmsg = errmsg; } }WechatQRCodeShortUrl.java
package com.phil.wechatqrcode.model; import com.phil.common.result.ResultState; /** * 二维码短链接返回结果 * @author phil * @date 2017年7月29日 * */ public class WechatQRCodeShortUrl extends ResultState{ /** * */ private static final long serialVersionUID = -835980382124181501L; private String short_url; //短链接 public String getShort_url() { return short_url; } public void setShort_url(String short_url) { this.short_url = short_url; } }WechatResult.java
package com.phil.common.result; /** * 微信返回的结果对象 * * @author phil * */ public class WechatResult { public static final int NEWSMSG = 1; // 图文消息 private boolean success; private int type; private Object object; private String msg; public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public int getType() { return type; } public void setType(int type) { this.type = type; } public Object getObject() { return object; } public void setObject(Object object) { this.object = object; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }HttpReqUtil.java
package com.phil.common.util; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; 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.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 javax.servlet.http.HttpServletRequest; import org.apache.commons.io.IOUtils; import com.google.gson.Gson; import com.phil.common.config.SystemConfig; import com.phil.common.result.ResultState; import com.phil.common.result.WechatResult; /** * Http连接工具类 * @author phil * @date 2017年7月2日 * */ public class HttpReqUtil { public static final String GET_METHOD = "GET"; public static final String POST_METHOD = "POST"; private static int DEFAULT_CONNTIME = 5000; private static int DEFAULT_READTIME = 5000; /** * 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(SystemConfig.CHARACTER_ENCODING)); output.flush(); output.close(); } if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream input = conn.getInputStream(); result = inputStreamToStrFromByte(input); input.close(); conn.disconnect(); } } return result; } /** * 根据url的协议选择对应的请求方式 * @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; } /** * 将输入流转换为字符串 (通过BufferedReader) * * @param in * @param charset * @return */ public static String inputStreamToStrFromReader(InputStream in, String charset) { String result = ""; StringBuffer buffer = new StringBuffer(); try { BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset)); while ((result = reader.readLine()) != null) { buffer.append(result);// append("\n"); } reader.close(); return buffer.toString(); } catch (IOException e) { buffer = null; e.printStackTrace(); } return result; } /** * 将输入流转换为字符串(通过byte数组) * * @param input 输入流 * @param charset * @return */ public static String inputStreamToStrFromByte(InputStream input, String charset) { String result = ""; int len = 0; byte[] array = new byte[1024]; StringBuffer buffer = new StringBuffer(); if (input != null) { try { while ((len = input.read(array)) != -1) { buffer.append(new String(array, 0, len, charset)); } result = buffer.toString(); } catch (IOException e) { buffer = null; e.printStackTrace(); } } return result; } /** * 将输入流转换为字符串(通过byte数组) * @param input 输入流 * @param charset * @return */ public static String inputStreamToStrFromByte(InputStream input) { String result = ""; int len = 0; byte[] array = new byte[1024]; StringBuffer buffer = new StringBuffer(); if (input != null) { try { while ((len = input.read(array)) != -1) { buffer.append(new String(array, 0, len, SystemConfig.CHARACTER_ENCODING)); } result = buffer.toString(); } catch (IOException e) { buffer = null; e.printStackTrace(); } } 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; } /** * 默认的下载素材方法 * * @param method http方法 POST/GET * @param apiPath api路径 * @param savePath 素材需要保存的路径 * @return 是否下载成功 Reuslt.success==true 表示下载成功 */ public static WechatResult downMeaterMetod(TreeMap<String, String> params, String method, String apiPath, String savePath) { WechatResult result = new WechatResult(); 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.setObject(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 WechatResult contentType(String contentType, HttpURLConnection conn, String savePath) { WechatResult result = new WechatResult(); try { if (conn != null) { InputStream input = conn.getInputStream(); // 考虑使用switch // switch(contentType){ // case "image/gif": result = inputStreamToMedia(input, // savePath, "gif"); // } 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 = inputStreamToStrFromByte(input); result.setObject(str); } else if (contentType.equals("application/json")) { // 返回json格式的数据 String str = inputStreamToStrFromByte(input); result.setObject(str); } } else { result.setObject("conn is null!"); } } catch (Exception ex) { ex.printStackTrace(); } return result; } /** * 将字符流转换为图片文件 * * @param input 字符流 * @param savePath 图片需要保存的路径 * @param 类型 jpg/png等 * @return */ private static WechatResult inputStreamToMedia(InputStream inputStream, String savePath, String type) { WechatResult result = new WechatResult(); 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 = inputStream.read(array)) != -1) { output.write(array, 0, len); } output.flush(); output.close(); result.setSuccess(true); result.setObject("save success!"); } catch (FileNotFoundException e) { e.printStackTrace(); //result.setSuccess(false); result.setObject(e.getMessage()); } catch (IOException e) { e.printStackTrace(); //result.setSuccess(false); result.setObject(e.getMessage()); result.setMsg(e.getMessage()); } return result; } /** * 编码 * @param source * @param encode * @return */ public static String urlEncode(String source, String encode) { String result = source; try { result = URLEncoder.encode(source, encode); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } /** * 将输入流转换字节数组 * * @param in * @return * @throws IOException */ public static byte[] readInput(InputStream inputStream) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); int len = 0; byte[] array = new byte[1024]; while ((len = inputStream.read(array)) != -1) { out.write(array, 0, len); } IOUtils.closeQuietly(out); IOUtils.closeQuietly(inputStream); return out.toByteArray(); } /** * 将输入流转换为字符串 * * @param is 待转换为字符串的输入流 * @return 由输入流转换String的字符串 * @throws IOException */ public static String inputStreamToString(InputStream inputStream) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int i; while ((i = inputStream.read()) != -1) { baos.write(i); } return baos.toString(); } /** * 将字符串转换为输入流 * * @param sInputString 待转换为输入流的字符串 * @return */ public static InputStream getStringStream(String sInputString) { ByteArrayInputStream byteArrayInputStream = null; if (sInputString != null && !sInputString.trim().equals("")) { try { byteArrayInputStream = new ByteArrayInputStream(sInputString.getBytes(SystemConfig.CHARACTER_ENCODING)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return byteArrayInputStream; } /** * 判断微信API是否返回正确的json数据包({"errcode":0,"errmsg":"ok"}) * @param result * @return */ public static boolean checkState(String result){ ResultState state = null; Gson gson = new Gson(); state = gson.fromJson(result, ResultState.class); gson = null; if(state.getErrcode()==0){ return Boolean.TRUE; } return Boolean.FALSE; } /** * 获取客户端ip * @param request * @return */ public static String getRemortIP(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } // squid的squid.conf 的配制文件中forwarded_for项改为off时 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } // 多级反向代理 if (ip != null && ip.indexOf(",") > 0 && ip.split(",").length > 1) { ip = ip.split(",")[0]; } return ip; } }
信任管理器MyX509TrustManager,实现方法自己定义(反正我没写)
/** * 信任管理器 * @author phil * */ 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 微信扫描二维码支付demo”应该是包含了一个完整的示例项目,帮助开发者理解如何在Java后端生成二维码并集成微信支付功能。下面我们将深入探讨相关知识点。 1. **微信支付API** 微信提供了公众平台支付...
为了满足用户渠道推广分析和用户帐号绑定等场景的需要,也就是推广和微商城分销的一个知识点,当你需要知道你的这个客户是谁推广的时候,当你为你的商城设计了分销的模式的时候,你就会发现这个知识点很好用
刘运强,网名“柳峰”,资深微信公众平台应用开发工程师,国内微信公众平台应用开发的先驱之一,项目经验丰富。他还是一位资深的Java软件开发工程师和Android/iOS移动应用开发工程师,活跃于CocoaChina、开源中国、...
缺省线程池的大小是10个,如果微信公众并发比较频繁,我们可以调整线程池的大小,以提高处理效率。 如果我们调整线程池大小为100,可以采用如下配置: <!-- 设置消息key缓存清理间隔,单位秒 --> ...
EggJS插件之微信公众平台基本服务源码.zip 微信小程序 小程序登录 小程序授权 小程序支付 推送模板消息 检测是否含有敏感词 生成二维码/小程序码 接入在线客服消息 微信服务号 网页授权 发送模板消息 获取...
### 使用Delphi Xe8 开发微信功能 -- (一)微信支付商户平台之对账单下载 #### 背景介绍 随着移动互联网的发展,微信作为国内最受欢迎的社交软件之一,其提供的各种服务功能也在逐渐扩展。对于企业来说,利用微信...
历经了一个月的时间,从开发到审核,我们的微信小程序终于在今天上线了,喜大普奔!因为业务的需求,需要做出携带参数的 小程序指定...微信公众平台接口调试工具 小程序的唯一标识(appid) 小程序的密钥(secret) 火狐浏
(1)微信公众平台 微信公众平台是微信公众账号申请入口和管理后台。商户可以在公众平台提交基本资料、业务资料、财务资料申请开通微信支付功能。 (2) 微信开放平台 微信开放平台是商户APP接入微信支付开放接口...
appid:appid是微信公众账号或开放平台APP的唯一标识,可在微信公众平台-->开发-->基本配置里面查看,商户的微信支付审核通过邮件中也会包含该字段值。 mch_id:微信支付商户号。商户申请微信支付后,由微信...
在Java开发中,微信支付接口的调用是一个常见的任务,特别是在电商或者服务类应用程序中。SSM框架(Spring、SpringMVC和MyBatis)是Java Web开发中的主流选择,它提供了一个完整的后端解决方案。下面我们将深入探讨...
- 生成二维码需要向微信特定URL传递参数,如创建时间、类型、场景值ID,成功返回ticket凭证。 7. **用户信息获取**: - 使用Openid可以获取用户基本信息,包括关注者列表。 - next_openid参数用于拉取关注者列表...
可以使用微信官方的JSAPI或自定义生成二维码的库来实现。 5. **处理支付结果**: 用户扫描二维码支付后,微信会回调你指定的异步通知地址。你需要在服务端处理这个通知,验证签名,确认支付状态,并更新订单状态。...
这一技术的核心在于二维码生成与识别,以及与微信支付平台的交互。在这个过程中,涉及到的技术主要包括Java编程语言、二维码库ZXing(Zebra Crossing)以及微信支付API。 1. **Java编程语言**:Java是一种广泛使用...
Java 生成二维码可以使用 Hutool 工具包,Hutool 是一个 Java 工具包类库,对文件、流、加密解密、转码、正则、线程、XML 等 JDK 方法进行封装,组成各种 Util 工具类。 准备工作: 微信扫码登录有两种实现方式: ...
这段代码首先根据传入的参数生成支付二维码所需的URL,然后调用`PayRequest.buildPayRequest`方法构建支付请求参数,并通过`payService.paySync`方法保存本地数据等待微信充值成功更改状态。最后,利用`Qrcode....
weixin-popular 包括微信公众平台基础API与支付API,提供便捷的API调用接口. API 列表 TokenAPI access_token 获取 MediaAPI 多媒体上传下载(临时素材) MaterialAPI 永久素材 MenuAPI 菜单 MessageAPI 信息发送...
对于Native支付,生成二维码或H5链接供用户操作。 - 监听支付状态的回调,获取支付结果并进行相应的业务处理。 5. **paysample**:这个文件可能是支付样例代码,可能包含JavaScript、Java、PHP或其他语言的示例,...
在constant.VxConfigEnum枚举类中的枚举类型需要修改成自己的对应微信公众平台上的值 值得注意的是MYTOKEN属性,这个属性为测试号管理的token 获取access_token vxinterface.GetToken中的getToken方法为获取access_...
微信支付是中国最流行的移动支付方式之一,由腾讯公司旗下的微信团队开发并维护。它为商家提供了集成支付功能的API和SDK,使得开发者可以方便地在自己的应用或网站中实现微信支付的功能。本教程将深入讲解如何进行...
Spring Boot 作为一款广泛应用的Java开发框架,结合微信支付API,能轻松实现高效、安全的支付流程。本文将详细介绍在Spring Boot环境中集成微信支付(小程序)的技术细节。 一、申请流程与步骤 1. 注册微信支付商户...