SpringBoot和微信二維碼相關的部分
package soke.home.util; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.lang.reflect.Field; import java.net.URLEncoder; import java.security.KeyStore; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.net.ssl.SSLContext; import javax.servlet.http.HttpServletRequest; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Namespace; import org.dom4j.QName; import org.dom4j.io.SAXReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import com.alibaba.fastjson.JSONObject; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.XppDriver; import com.typesafe.config.ConfigFactory; import soke.common.util.GetPostUtil; import soke.home.classes.domain.model.CpClass; import soke.home.classes.domain.model.CpClassMember; import soke.home.family.domain.model.CpFamily; import soke.home.message.domain.model.CpMsg; import soke.home.message.domain.model.CpMsgDnd; import soke.home.message.domain.model.CpMsgInbox; import soke.home.message.domain.model.Message; import soke.home.message.domain.model.MessageManagerPool; import soke.home.org.domain.model.OrgMember; import soke.home.org.domain.model.Organization; import soke.home.user.domain.model.User; import soke.home.user.enums.JFTRole; import soke.home.wx.annotation.XStreamCDATA; import soke.home.wx.constants.WeiXinConstants; import soke.home.wx.thread.HomeVisitThread; import soke.memory.redis.RedisDb; @SuppressWarnings("deprecation") @Component /** * * @author 15293 * */ public class WeixinUtil { static Logger logger = LoggerFactory.getLogger(WeixinUtil.class); /*-------------------------WX---------------------------*/ /** appId 微信的正式環境 */ public static String appID = ConfigFactory.load().getString("weixin.appId"); public static String appsecret = ConfigFactory.load().getString("weixin.appsecret"); /** 商品號 */ public static String mch_id = ConfigFactory.load().getString("weixin.mchId"); /** 付款回撥地址 */ public static String notify_url = ConfigFactory.load().getString("weixin.notifyUrl"); /** 微信公眾號Key */ public static String key = ConfigFactory.load().getString("weixin.key"); /** 微信公眾號校驗的欄位 */ public static String token = ConfigFactory.load().getString("weixin.token"); /** 專案路徑 **/ public static String applyaddress = ConfigFactory.load().getString("weixin.applyaddress"); /** 傳送紅包的證書路徑 **/ public static String redPaperPath = ConfigFactory.load().getString("wexin.redPaperPath"); /** * 獲取微信的access_token(redis裡面獲取不到就自己去取) * * @return String(null) * **/ public static String getAccessToken() { String accessToken = null; if (RedisDb.exists(WeiXinConstants.ACCESSTOKEN_IN_REDIS)) { accessToken = RedisDb.getString("access_token"); } String aString = GetPostUtil.sendGet("https://api.weixin.qq.com/cgi-bin/token", "grant_type=client_credential&appid=" + appID + "&secret=" + appsecret); JSONObject jsonObject = JSONObject.parseObject(aString); if (jsonObject.get("access_token") != null) { accessToken = (String) jsonObject.get("access_token"); RedisDb.setAccessToken("access_token", accessToken, WeiXinConstants.EXPIRETIME); } else { logger.error("access_token的獲取有問題" + jsonObject); } return accessToken; } /** * 獲取生成臨時二維碼需要的ticket * * 1.設定了過期時間為2592000---即30天 2.如果報40001(access_token無效)的錯誤 * 就移除Redis裡面的access_token重新生成 * * @param l:傳入的帶引數的二維碼裡面存的引數值 * * @return String(null) * */ public static String getTicket(long l) { String accessToken = getAccessToken(); JSONObject jsonObject = JSONObject.parseObject( "{\"expire_seconds\":2592000,\"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\":" + l + "}}}"); String aString2 = GetPostUtil .post("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken, jsonObject); JSONObject jsonObject2 = JSONObject.parseObject(aString2); // 當出現access_token出現40001異常的時候 從redis裡面移除 String errcode = (String) jsonObject2.get("errcode"); if (errcode != null && errcode.equals("40001")) { RedisDb.delString("access_token"); accessToken = getAccessToken(); GetPostUtil.post("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken, jsonObject); } String ticket = (String) jsonObject2.get("ticket"); return ticket; } /** * 解析微信發來的請求或者XML為鍵值對,方便取值(因為有request和xml2種情況 ,所以合併成一個介面,傳入2個引數 ) * * @param request:requset請求 * @param xml:String的xml語句 * * @return HashMap<Sring,String> * * @throws IOException * @throws DocumentException * */ public static Map<String, String> parseXml(HttpServletRequest request, String xml) throws IOException, DocumentException { // 將解析結果儲存在HashMap中 Map<String, String> map = new HashMap<String, String>(); InputStream inputStream = null; Document document = null; if (request != null) { inputStream = request.getInputStream(); SAXReader reader = new SAXReader(); document = reader.read(inputStream); } if (xml != null) { document = DocumentHelper.parseText(xml); } Element rootElement = document.getRootElement(); ele2map(map, rootElement); if (inputStream != null) { inputStream.close(); inputStream = null; } return map; } /** * 解析xml檔案 */ static void ele2map(Map<String, String> map, Element ele) { // 獲得當前節點的子節點 List<Element> elements = ele.elements(); if (elements.size() == 0) { // 沒有子節點說明當前節點是葉子節點,直接取值即可 if (ele.getText() != null) { map.put(ele.getName(), ele.getText()); } } else if (elements.size() == 1) { // 只有一個子節點說明不用考慮list的情況,直接繼續遞迴即可 Map<String, String> tempMap = new HashMap<String, String>(); ele2map(map, elements.get(0)); if (tempMap.get(ele.getName()) != null) { map.put(ele.getName(), tempMap.get(ele.getName())); } } else { // 多個子節點的話就得考慮list的情況了,比如多個子節點有節點名稱相同的 // 構造一個map用來去重 Map<String, String> tempMap = new HashMap<String, String>(); for (Element element : elements) { tempMap.put(element.getName(), null); } Set<String> keySet = tempMap.keySet(); for (String string : keySet) { Namespace namespace = elements.get(0).getNamespace(); List<Element> elements2 = ele.elements(new QName(string, namespace)); // 如果同名的數目大於1則表示要構建list 現在假設不可能重名 if (elements2.size() > 1) { } else { // 同名的數量不大於1則直接遞迴去 ele2map(map, elements2.get(0)); } } } } /** * 根據access和OpenId獲取使用者基本資訊 * * @param openid * * @return JsonObject(null) */ public static JSONObject getUserInfoFromWX(String openid) { if (openid == null) { return null; } String url = "https://api.weixin.qq.com/cgi-bin/user/info"; String accessToken = getAccessToken(); String info = GetPostUtil.sendGet(url, "access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN"); JSONObject jsonObject = JSONObject.parseObject(info); return jsonObject; } /** * 把object轉換成xml物件 * * @param object * * @return String */ public static String objectToXml(Object object) { XStream xstream = createXstream(); xstream.alias("xml", object.getClass()); return xstream.toXML(object); } /** * 利用Xstream來把Object轉換成xml檔案(匿名內部類) * * @return */ public static XStream createXstream() { return new XStream(new XppDriver() { @Override public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { boolean cdata = false; Class<?> targetClass = null; @Override public void startNode(String name, @SuppressWarnings("rawtypes") Class clazz) { super.startNode(name, clazz); // 業務處理,對於用XStreamCDATA標記的Field,需要加上CDATA標籤 if (!"xml".equals(name)) { cdata = needCDATA(targetClass, name); } else { targetClass = clazz; } } @Override protected void writeText(QuickWriter writer, String text) { if (cdata) { writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); } else { writer.write(text); } } }; } }); } /** * 迴圈往上面遍歷,看域上面是否有註解 * * @param targetClass * @param fieldAlias * @return */ private static boolean needCDATA(Class<?> targetClass, String fieldAlias) { boolean cdata = false; cdata = existsCDATA(targetClass, fieldAlias); if (cdata) { return cdata; } Class<?> superClass = targetClass.getSuperclass(); while (!superClass.equals(Object.class)) { cdata = existsCDATA(superClass, fieldAlias); if (cdata) { return cdata; } superClass = superClass.getClass().getSuperclass(); } return false; } private static boolean existsCDATA(Class<?> clazz, String fieldAlias) { // 特例新增 if ("MediaId".equals(fieldAlias)) { return true; } Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.getAnnotation(XStreamCDATA.class) != null) { XStreamAlias xStreamAlias = field.getAnnotation(XStreamAlias.class); if (null != xStreamAlias) { if (fieldAlias.equals(xStreamAlias.value())) { return true; } } else { // 如果傳入的xml節點的名稱和@xstreamAlias的相等也返回true if (fieldAlias.equals(field.getName())) { return true; } } } } return false; } /** * 判斷是否是QQ表情 * * @param content * @return */ public static boolean isQqFace(String content) { boolean result = false; // 判斷QQ表情的正則表示式 String qqfaceRegex = "/::\\)|/::~|/::B|/::\\||/:8-\\)|/::<|/::$|/::X|/::Z|/::'\\(|/::-\\||/::@|" + "/::P|/::D|/::O|/::\\(|/::\\+|/:--b|/::Q|/::T|/:,@P|/:,@-D|/::d|/:,@o|/::g|/:\\|-\\)|" + "/::!|/::L|/::>|/::,@|/:,@f|/::-S|/:\\?|/:,@x|/:,@@|/::8|/:,@!|/:!!!|/:xx|/:bye|/:wipe|" + "/:dig|/:handclap|/:&-\\(|/:B-\\)|/:<@|/:@>|/::-O|/:>-\\||/:P-\\(|/::'\\||/:X-\\)|/::\\*|" + "/:@x|/:8\\*|/:pd|/:<W>|/:beer|/:basketb|/:oo|/:coffee|/:eat|/:pig|/:rose|/:fade|/:showlove|" + "/:heart|/:break|/:cake|/:li|/:bome|/:kn|/:footb|/:ladybug|/:shit|/:moon|/:sun|/:gift|/:hug|" + "/:strong|/:weak|/:share|/:v|/:@\\)|/:jj|/:@@|/:bad|/:lvu|/:no|/:ok|/:love|/:<L>|/:jump|/:shake|" + "/:<O>|/:circle|/:kotow|/:turn|/:skip|/:oY|/:#-0|/:hiphot|/:kiss|/:<&|/:&>" + "|\\[Smart\\]|\\[Hey\\]|\\[Facepalm\\]|\\[Smirk\\]|\\[Concerned\\]|\\[Yeah!\\]|\\[Packet\\]|\\[Chick\\]"; Pattern p = Pattern.compile(qqfaceRegex); Matcher m = p.matcher(content); if (m.matches()) { result = true; } return result; } /** * 調起Js * * @return */ public static String getJsSdkConfigTicket() { String ticket = null; if (RedisDb.exists("jsapi_ticket")) { ticket = RedisDb.getString("jsapi_ticket"); } if (ticket != null) { System.err.println("jsapi_ticket是從Redis裡面取得,值為:"); return ticket; } String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"; String accessToken = getAccessToken(); String info = GetPostUtil.sendGet(url, "access_token=" + accessToken + "&type=jsapi"); JSONObject jsonObject = JSONObject.parseObject(info); System.err.print("獲取JsApiTicket的值:ticket是手動獲取的:" + jsonObject); ticket = jsonObject.getString("ticket"); RedisDb.setAccessToken("jsapi_ticket", ticket, WeiXinConstants.EXPIRETIME); return ticket; } /** * 生成內部訂單號 */ public static String createOutTradeNo(Integer uid) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); String date = LocalDateTime.now().format(formatter); Random random = new Random(); String uuid = uid + ""; int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000; if (uid == null) { uuid = "00"; } else if (uid < 10) { uuid = "0" + uid; } return date + uuid + rannum; } /** * 因為微信授權的特殊性 同一code只能獲取一次資訊 所以用redis來處理一下; * * @param code * 微信網頁授權碼 * * @param openId * openId */ public static String opreateOpenId(String code, String openId) { if (code == null) { logger.info("WeixinUtil的opreateOpenId傳入的code為null"); return null; } if (openId != null) { RedisDb.setString(code, openId); return null; } else { openId = RedisDb.getString(code); return openId; } } /** * @param mchId * ----商戶Id * * @param xml * ----包含簽名的xml檔案 * * @param url * ----需要post資料的url地址 * * @return String * */ public static String WxRedPaperSend(String mchId, String xml, String url) { try { KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream instream = new FileInputStream(new File(redPaperPath)); try { keyStore.load(instream, mchId.toCharArray()); } finally { instream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); StringBuffer result = new StringBuffer(); try { HttpPost httpPost = new HttpPost(url); // 構造HttpClient的HttpPost請求 httpPost.addHeader("Connection", "keep-alive"); httpPost.addHeader("Accept", "*/*"); httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); httpPost.addHeader("Host", "api.mch.weixin.qq.com"); httpPost.addHeader("X-Requested-With", "XMLHttpRequest"); httpPost.addHeader("Cache-Control", "max-age=0"); httpPost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); httpPost.setEntity(new StringEntity(xml, "UTF-8")); CloseableHttpResponse response = httpclient.execute(httpPost); try { HttpEntity entity = response.getEntity(); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent())); String text; while ((text = bufferedReader.readLine()) != null) { result.append(text); result.append("\n"); } } EntityUtils.consume(entity); } finally { response.close(); } } finally { httpclient.close(); } return result.toString(); } catch (Exception e) { e.printStackTrace(); logger.error("傳送現金紅包的封裝接口出錯:" + e.getMessage()); return null; } } }
相關推薦
SpringBoot和微信二維碼相關的部分
package soke.home.util; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.Inp
關於viewport引起的微信二維碼識別區域偏移的問題討論與解決
ges 瀏覽器內核 不同 清晰 css 工作量 分辨 轉換成 如果 一、問題概述 在開發一個含有二維碼的微信頁面時,我遇到了這樣一個問題:使用iPhone第一次進入該頁面時,二維碼可以長按識別,但第二次進入時長按無法識別到二維碼。安卓機都能識別。 二、我進行了以下嘗試:
微信公眾平臺開發(121) 微信二維碼海報
關鍵字:微信公眾平臺 二維碼 海報作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/weixin-poster.html 本文介紹微信公眾平臺下二維碼海報的開發過程。 一、微信二維碼海報介紹 微信二維碼海報是指在
通過程式設計做特別效果的個性 微信 二維碼(思路)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android 基於google Zxing實現二維碼 條形碼掃描,仿微信二維碼掃描效果
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
你的微信二維碼是唯一的嗎 【微信二維碼的祕密】
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
微信二維碼上傳檔案
轉載自:https://blog.csdn.net/peng_wei_kang/article/details/80279923 作者:peng_wei_kang 在業務系統中常常遇到檔案上傳比較麻煩等問題,首先拍照後要將照片拷貝到電
微信二維碼的製作
1.匯入pom中的jar包 <!-- https://mvnrepository.com/artifact/com.google.zxing/core --> <dependency> <groupId>com
TP5.0 web微信二維碼付款,包括查詢是否支付成功。
首先呢,需要公司去註冊微信平臺上的東西,拿到資質,拿到配置資訊才可以進行測試。 我們程式猿這裡直接從程式碼開始,不管前面亂七八糟的程式。 下載好文件後把文件放在 exends 目錄下 ![這裡我改名為 wechatpay](https://img-blog.csdnimg.cn/20
如何在CSDN個人主頁新增公眾號或者個人微信二維碼
對於CSDN,在這裡,如果有自己的能力,你想推廣你個人。我想,你將你的微信二維碼或者你的微信公眾號的二維碼放在這裡,至少我是這樣想的 那麼我在我的CSDN的部落格主頁面中,我們就添加了我的微信公眾號的二維碼: 具體實現的步驟: 1、 找到個人主頁裡的“管理部落格”
多個微信二維碼收款,加人,進群,這樣做簡單方便又安全!
我有幾個微訊號,可以同時收款嗎? 我業務長期推廣,有幾個微訊號,想做成一個微信二維碼加人可以嗎? 我這邊做活動,想把很多微信群二維碼,做成一個可以嗎? 其實沒那麼麻煩,一個介面就能搞定!重點給大家講解一下! 支付活碼:微信收款用 微信活碼:微信加人用 群活碼:
node.js獲取微信二維碼並儲存到伺服器
const body = {path: 'pages/index',} const opts = { url: `https://api.weixin.qq.com/wxa/getwxa
C#獲取微信二維碼顯示到wpf
微信的api開放的二維碼是一個連結地址,而我們要將這個二維碼顯示到客戶端。方式很多,今天我們講其中一種。 /// <summary> /// 獲取圖片路徑 /// </summary> /// <param name="h
java生成帶圖片的微信二維碼
廢話不多說。 import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.
java生成自己的微信二維碼
根據上一篇得到的資料,我們可以生成自己的微信二維碼: import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.OutputStream; i
解析微信二維碼內的資訊
這兩天對微信二維碼比較感興趣,所以就花了點時間學習了一下,下面我將先介紹一下如何解析微信二維碼內的資訊。 直接上程式碼: import java.awt.image.BufferedImage; import java.io.File; import java.io.IOExcep
Android 基於google Zxing實現二維碼、條形碼掃描,仿微信二維碼掃描效果(現在正做個掃描App、收藏)
瞭解二維碼這個東西還是從微信中,當時微信推出二維碼掃描功能,自己感覺挺新穎的,從一張圖片中掃一下竟然能直接加好友,不可思議啊,那時候還不瞭解二維碼,呵呵,然後做專案的時候,老闆說要加上二維碼掃描功能,然後自己的屁顛屁顛的去百度,google啥的,發現很多朋友都
Java 微信二維碼支付
本文程式碼並非原創,是根據網上一篇部落格修改而成,留作備忘。 微信支付有2種模式,第一種模式略微複雜,本文采用第二種模式; 微信掃碼模式二 業務流程說明: (1)商戶後臺系統根據使用者選購的商品生成訂單。 (2)使用者確認
解決mui-app微信二維碼分享
var Intent = null, File = null, Uri = null, main = null; var shares = null; var shareImageUrl = ''; mui.plusReady(function() {
微信二維碼海報推廣示例
這倆天根據客戶 需求 微信商城 能生成自己的二維碼 並且 需先關注公眾號,掃碼的使用者顯示出自己的上級研究兩天,發現微信二維碼介面能實現這個功能 ! 思路:1.生成微信永久二位碼 具體看微信公眾文件 http://mp.weixin.qq.com/wiki/18/