微信接入指南 https://mp.weixin.qq.com/wiki/8/f9a0b8382e0b77d87b3bcc1ce6fbc104.html 目錄 1 概述 2 第一步:填寫服務器配置 html
3 第二步:驗證服務器地址的有效性 package com.web.wexin; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.web.wexin.util.SignUtil; /** * 核心請求處理類 */ public class WeiXinServlet extends HttpServlet{ private static final long serialVersionUID = 1L; /** * 確認請求來自微信服務器 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 微信加密簽名 String signature = request.getParameter("signature"); // 時間戳 String timestamp = request.getParameter("timestamp"); // 隨機數 String nonce = request.getParameter("nonce"); // 隨機字符串 String echostr = request.getParameter("echostr"); PrintWriter out = response.getWriter(); // 經過檢驗signature對請求進行校驗,若校驗成功則原樣返回echostr,表示接入成功,不然接入失敗 if (SignUtil.checkSignature(signature, timestamp, nonce)) { out.print(echostr); } out.close(); out = null; } /** * 處理微信服務器發來的消息 */ public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { // 將請求、響應的編碼均設置爲UTF-8(防止中文亂碼) request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); // 調用核心業務類接收消息、處理消息 String respMessage = CoreService.processRequest(request); // 響應消息 PrintWriter out = response.getWriter(); out.print(respMessage); out.close(); } }
4 第三步:依據接口文檔實現業務邏輯java
先提供一個工具類 package com.web.wexin.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import java.util.HashMap; import java.util.Map; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import com.bean.AccessToken; import com.web.wexin.vo.Menu; import com.web.wexin.vo.OAuthInfo; import com.web.wexin.vo.WxUserinfo; /** * 公衆平臺通用接口工具類 * */ public class WeixinUtil { private static Logger log = LoggerFactory.getLogger(WeixinUtil.class); // 第三方用戶惟一憑證 public final static String appId = "wx71335f894797efd0"; // 第三方用戶惟一憑證密鑰 public final static String appSecret = "d524fcf5147c6c732a2270a64f5869a5"; // 獲取access_token的接口地址(GET) public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; // 菜單建立 public final static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; // 發送模板消息 public final static String sendtemplat_url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN"; // 獲取code後,請求如下連接獲取用戶access_token: public final static String userinfotoken_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code"; // 粉絲列表 public final static String fansi_url = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN"; // 獲取用戶信息 public final static String user_url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; // 獲取用戶基本信息(包括UnionID機制) 粉絲列表時使用 public final static String fansi_userinfo_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; // 建立臨時二維碼ticket public final static String temporary_url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN"; // 建立永久二維碼ticket public final static String permanent_url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN"; // 經過ticket換取二維碼 提醒:TICKET記得進行UrlEncode public final static String qrcode_url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET"; // 獲取用戶增減數據 最大時間跨度7天 public final static String getusersummary_url = "https://api.weixin.qq.com/datacube/getusersummary?access_token=ACCESS_TOKEN"; // 獲取累計用戶數據 最大時間跨度7天 public final static String getusercumulate_url = "https://api.weixin.qq.com/datacube/getusercumulate?access_token=ACCESS_TOKEN"; // 獲取jsapi_ticket public final static String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; // 建立分組 POST數據例子:{"group":{"name":"test"}} public final static String create_group_url = "https://api.weixin.qq.com/cgi-bin/groups/create?access_token=ACCESS_TOKEN"; // 查詢全部分組 public final static String selete_group_url = "https://api.weixin.qq.com/cgi-bin/groups/get?access_token=ACCESS_TOKEN"; // 查詢用戶所在分組 POST數據例子:{"openid":"od8XIjsmk6QdVTETa9jLtGWA6KBc"} public final static String selectUsers_group_url = "https://api.weixin.qq.com/cgi-bin/groups/getid?access_token=ACCESS_TOKEN"; // 修改分組名 POST數據例子:{"group":{"id":108,"name":"test2_modify2"}} public final static String update_group_url = "https://api.weixin.qq.com/cgi-bin/groups/update?access_token=ACCESS_TOKEN"; // 批量移動用戶分組 public final static String batch_group_url = "https://api.weixin.qq.com/cgi-bin/groups/members/batchupdate?access_token=ACCESS_TOKEN"; // 獲取微信卡券 api_ticket public final static String api_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card"; // 批量查詢卡券列表 public final static String batchget_url = "https://api.weixin.qq.com/card/batchget?access_token=ACCESS_TOKEN"; // 查詢卡券詳情 http請求方式: POST POST數據 {"card_id":"pFS7Fjg8kV1IdDz01r4SQwMkuCKc"} public final static String get_card_url = "https://api.weixin.qq.com/card/get?access_token=ACCESS_TOKEN"; // 建立卡券二維碼 ticket post請求 public final static String create_cardTicket_url = "https://api.weixin.qq.com/card/qrcode/create?access_token=ACCESS_TOKEN"; // 覈銷卡券Code接口 public final static String delete_code_url = "https://api.weixin.qq.com/card/code/consume?access_token=ACCESS_TOKEN"; // Code解碼接口 public final static String code_decrypt_url = "https://api.weixin.qq.com/card/code/decrypt?access_token=ACCESS_TOKEN"; // 檢測Code是否正常狀態 public final static String check_code_url = "https://api.weixin.qq.com/card/code/get?access_token=ACCESS_TOKEN"; // 建立卡券貨架接口 public final static String create_cardhj_url = "https://api.weixin.qq.com/card/landingpage/create?access_token=ACCESS_TOKEN"; // 獲取用戶已領取卡券接口 public final static String getcardlist_url = "https://api.weixin.qq.com/card/user/getcardlist?access_token=ACCESS_TOKEN"; /** * 獲取access_token * * @param appid * 憑證 * @param appsecret * 密鑰 * @return */ public static AccessToken getAccessToken(String appid, String appsecret) { AccessToken accessToken = null; String requestUrl = access_token_url.replace("APPID", appid).replace( "APPSECRET", appsecret); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); // 若是請求成功 if (null != jsonObject) { try { accessToken = new AccessToken(); accessToken.setToken(jsonObject.getString("access_token")); accessToken.setExpiresIn(jsonObject.getInteger("expires_in")); } catch (JSONException e) { accessToken = null; // 獲取token失敗 log.error("獲取token失敗 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg")); } } return accessToken; } /** * 獲取網頁受權用戶的token * * @param code * @return 2016年8月17日 */ public static OAuthInfo getUserToken(String code) { String requestUrl = userinfotoken_url.replace("APPID", appId) .replace("APPSECRET", appSecret).replace("CODE", code); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); OAuthInfo oa = new OAuthInfo(); if (null != jsonObject) { try { oa.setAccessToken(jsonObject.getString("access_token")); oa.setExpiresin(jsonObject.getInteger("expires_in").toString()); oa.setRefreshToken(jsonObject.getString("refresh_token")); oa.setOpenid(jsonObject.getString("openid")); oa.setScope(jsonObject.getString("scope")); } catch (JSONException e) { // 獲取token失敗 log.error("網頁受權獲取openId失敗 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg")); } } return oa; } /** * 獲取網頁受權用戶的詳細信息 * * @param oa * @return 2016年8月17日 */ public static WxUserinfo getWxUserInfo(OAuthInfo oa) { String requestUrl = user_url.replace("ACCESS_TOKEN", oa.getAccessToken()).replace("OPENID", oa.getOpenid()); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); WxUserinfo user = new WxUserinfo(); if (jsonObject != null) { user.setOpenid(jsonObject.getString("openid")); user.setNickname(jsonObject.getString("nickname")); user.setSex(jsonObject.getString("sex")); user.setProvince(jsonObject.getString("province")); user.setCity(jsonObject.getString("city")); user.setCountry(jsonObject.getString("country")); user.setHeadimgurl(jsonObject.getString("headimgurl")); user.setPrivilege(jsonObject.getString("privilege")); } return user; } /** * 建立菜單 * * @param menu * 菜單實例 * @param accessToken * 有效的access_token * @return 0表示成功,其餘值表示失敗 */ public static int createMenu(Menu menu, String accessToken) { int result = 0; // 拼裝建立菜單的url String url = menu_create_url.replace("ACCESS_TOKEN", accessToken); // 將菜單對象轉換成json字符串 String jsonMenu = JSONObject.toJSONString(menu); // 調用接口建立菜單 JSONObject jsonObject = httpRequest(url, "POST", jsonMenu); if (null != jsonObject) { if (0 != jsonObject.getInteger("errcode")) { result = jsonObject.getInteger("errcode"); log.error("建立菜單失敗 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg")); } } return result; } /** * 獲取粉絲列表信息 * * @param accessToken * @param openid * @return 2016年8月18日 */ public static JSONArray getFansList(String accessToken) { JSONArray arrs = new JSONArray(); String url = fansi_url.replace("ACCESS_TOKEN", accessToken); JSONObject jsonObject = httpRequest(url, "GET", null); if (null != jsonObject) { JSONObject data = (JSONObject) jsonObject.get("data"); JSONArray openidList = data.getJSONArray("openid"); for (int i = 0; i < openidList.size(); i++) { System.out.println(openidList.getString(i)); JSONObject obj = httpRequest( fansi_userinfo_url.replace("ACCESS_TOKEN", accessToken) .replace("OPENID", openidList.getString(i)), "GET", null); if (obj != null) { arrs.add(obj); } } } return arrs; } /** * 建立二維碼ticket * * @param type * 1=臨時 ,2=永久 * @param accessToken * @param expire_seconds * 該二維碼有效時間,以秒爲單位。 最大不超過2592000 * @param scene_id * 場景值ID,臨時二維碼時爲32位非0整型,永久二維碼時最大值爲100000 * @return 2016年8月18日 */ public static JSONObject createTicket(String type, String accessToken, String expire_seconds, String scene_id) { String requestUrl = ""; String jsonStr = ""; if (type.equals("1")) {// 臨時 requestUrl = temporary_url.replace("ACCESS_TOKEN", accessToken); jsonStr = "{\"expire_seconds\": 604800, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": 123}}}"; } else {// 永久 requestUrl = permanent_url.replace("ACCESS_TOKEN", accessToken); jsonStr = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": 123}}}"; } JSONObject jsonObject = httpRequest(requestUrl, "POST", jsonStr); return jsonObject; } /** * 發起https請求並獲取結果 * * @param requestUrl * 請求地址 * @param requestMethod * 請求方式(GET、POST) * @param outputStr * 提交的數據 * @return JSONObject(經過JSONObject.get(key)的方式獲取json對象的屬性值) */ public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 建立SSLContext對象,並使用咱們指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 從上述SSLContext對象中獲得SSLSocketFactory對象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url .openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 設置請求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 當有數據須要提交時 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意編碼格式,防止中文亂碼 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 將返回的輸入流轉換成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader( inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader( inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 釋放資源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONObject.parseObject(buffer.toString()); } catch (ConnectException ce) { log.error("Weixin server connection timed out."); } catch (Exception e) { log.error("https request error:{}", e); } return jsonObject; } public static Map<String, Object> wxMsgMap(Map<String, Object> allMap, String key, String value, String color) { Map<String, Object> map = new HashMap<String, Object>(); map.put("value", value); map.put("color", color); allMap.put(key, map); return allMap; } /** * 發送模板消息 * * @param accessToken * @param OpenId * @param template_id * @param detailUrl * @param map * @return 2016年9月19日 */ public static JSONObject postTemplateMsg(String accessToken, String OpenId, String template_id, String detailUrl, Map<String, Object> map) { String url = sendtemplat_url.replace("ACCESS_TOKEN", accessToken); JSONObject jso = new JSONObject(); jso.put("touser", OpenId); jso.put("template_id", template_id); if (detailUrl != null) jso.put("url", detailUrl); jso.put("data", map); return httpRequest(url, "POST", jso.toString()); } }
springMVC控制器 package com.web; import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.bean.CardReceive; import com.mapper.SqlcardReceive; import com.util.AjaxUtil; import com.util.DateUtil; import com.web.wexin.TokenThread; import com.web.wexin.util.SignUtil; import com.web.wexin.util.WeixinUtil; import com.web.wexin.vo.OAuthInfo; import com.web.wexin.vo.WxUserinfo; @Controller @RequestMapping("/wx") public class WeiXinController { @Resource public SqlcardReceive sqlcardReceive; /** * 網頁受權獲取用戶信息 * @param view * @param req * @return * 2016年8月16日 */ @RequestMapping("/oauth") public ModelAndView oauth(ModelAndView view,HttpServletRequest req){ String code=req.getParameter("code"); System.out.println(code); OAuthInfo oauth=WeixinUtil.getUserToken(code); if(oauth!=null){ WxUserinfo userinfo=WeixinUtil.getWxUserInfo(oauth); System.out.println("oauth===="+userinfo.toString()); } return view; } /** * 微信jssdk * @param request * 2016年8月25日 */ @RequestMapping("/wxJs") public void wxJs(HttpServletRequest request,HttpServletResponse response){ String url=request.getParameter("url"); String ticket=(String) request.getSession().getAttribute("ticket"); if(StringUtils.isEmpty(ticket)){ JSONObject json=WeixinUtil.httpRequest(WeixinUtil.jsapi_ticket_url.replaceAll("ACCESS_TOKEN", TokenThread.accessToken.getToken()), "GET", null); ticket=json.getString("ticket"); request.getSession().setAttribute("ticket", json.getString("ticket")); request.getSession().setMaxInactiveInterval(7200); } Map<Object, Object> returnMap = SignUtil.sign(ticket, url); returnMap.put("appId", "wx71335f894797efd0"); AjaxUtil.writeJsonMap(returnMap, response); } /** * 過濾已過時的卡券 * @return * 2016年9月7日 */ public JSONArray filterCard(String token){ JSONArray array=new JSONArray(); String str="{\"offset\": 0, \"count\":50,\"status_list\": [\"CARD_STATUS_VERIFY_OK\"]}"; //獲取卡券id列表 JSONObject json=WeixinUtil.httpRequest(WeixinUtil.batchget_url.replaceAll("ACCESS_TOKEN", token), "POST", str); if(json.getString("errcode").equals("0")){ JSONArray arr=(JSONArray) json.get("card_id_list"); for(int i = 0; i < array.size(); i++){ JSONObject cardObj=new JSONObject(); JSONObject outputStr=new JSONObject(); outputStr.put("card_id", arr.get(i)); //獲取卡券詳情 JSONObject obj=WeixinUtil.httpRequest(WeixinUtil.get_card_url.replaceAll("ACCESS_TOKEN", token), "POST", outputStr.toJSONString()); if(obj.getString("errcode").equals("0")){ JSONObject card= (JSONObject) obj.get("card"); JSONObject groupon= (JSONObject) card.get("groupon"); JSONObject base_info= (JSONObject) groupon.get("base_info"); JSONObject dateInfo= (JSONObject) base_info.get("date_info"); int end_timestamp=dateInfo.getIntValue("end_timestamp"); int newtimestamp=DateUtil.getUnixDate(); if(end_timestamp<=newtimestamp){ cardObj.put("card_id", arr.get(i)); // cardObj.put("title", base_info.get("title")); array.add(cardObj); } } } } return array; } /** * 建立卡券領取二維碼tike * @param request * @param response * 2016年9月6日 */ @RequestMapping("/createCardqrCode") public void createCardqrCode(HttpServletRequest request,HttpServletResponse response){ String token="ko6W-mcZJG_Xlj6H4JExQcrf218i5TymJw9IJtkTSJaplxgRtWDNt6CRgcbMjRERP-yWqaZRt02A0J6zbedB2JELWJ0i8cmAB9UDAcxSyLjvfWjXOtqNTuD-bAOpQJ0bIKFeCBAZBW"; // JSONArray array=filterCard(token); JSONArray listarry=new JSONArray(); // for (int i = 0; i < array.size(); i++){ JSONObject map=new JSONObject(); map.put("card_id", "pwibYt5UeRE7KTs4Gn6j1EM_xS-k"); listarry.add(map); // } String url=WeixinUtil.create_cardTicket_url; String outputStr="{\"action_name\": \"QR_MULTIPLE_CARD\","; outputStr +="\"expire_seconds\": 1800,"; outputStr +="\"action_info\":{\"multiple_card\":{\"card_list\":"+listarry.toJSONString()+"}}}"; JSONObject obj=WeixinUtil.httpRequest(url.replaceAll("ACCESS_TOKEN", token), "POST", outputStr); AjaxUtil.out(obj.toJSONString(), response); } /** * 建立卡券貨架領取 返回url地址 * @param request * @param response * 2016年9月6日 */ @RequestMapping("/shelves") public void shelves(HttpServletRequest request,HttpServletResponse response){ String token=""; JSONArray array=filterCard(token); JSONObject m=new JSONObject(); m.put("banner", "http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFN"); m.put("page_title", "卡券貨架接口測試"); m.put("can_share", true); m.put("scene", "SCENE_H5"); JSONArray listarry=new JSONArray(); for (int i = 0; i < array.size(); i++){ JSONObject map=new JSONObject(); map.put("thumb_url", "www.qq.com/a.jpg"); map.put("card_id", ""+array.get(i)+""); listarry.add(map); } m.put("card_list", listarry); System.out.println(m.toJSONString()); JSONObject obj=WeixinUtil.httpRequest(WeixinUtil.create_cardhj_url.replaceAll("ACCESS_TOKEN", token), "POST", m.toString()); System.out.println(obj.toJSONString()); AjaxUtil.out(obj.toJSONString(), response); } /** * 卡券內跳轉外鏈的簽名中會對code進行加密處理,經過調用解碼接口獲取真實code。 * Code解碼接口 * @param request * @param response * 2016年9月6日 */ @RequestMapping("/codeDecrypt") public void codeDecrypt(HttpServletRequest request,HttpServletResponse response){ String token=""; String encrypt_code=request.getParameter("encrypt_code"); String url=WeixinUtil.code_decrypt_url; JSONObject outputStr=new JSONObject(); outputStr.put("encrypt_code", encrypt_code); JSONObject json=WeixinUtil.httpRequest(url.replaceAll("ACCESS_TOKEN", token), "POST", outputStr.toJSONString()); AjaxUtil.out(json.toJSONString(), response); } /** * 覈銷卡券 * @param request * @param response * 2016年9月6日 */ @RequestMapping("/consumeCode") public void consumeCode(HttpServletRequest request,HttpServletResponse response){ Map<Object, Object> map=new HashMap<Object, Object>(); try { String token=""; String check_code_url=WeixinUtil.check_code_url; //檢測code String delete_code_url=WeixinUtil.delete_code_url; //覈銷code String code=request.getParameter("code"); String card_id=request.getParameter("card_id");//自定義Code卡券 JSONObject check=new JSONObject(); check.put("code", code); if(StringUtils.isNotEmpty(card_id)){ check.put("card_id", card_id); } check.put("check_consume", true); System.out.println(check.toJSONString()); JSONObject checkStatus=new JSONObject(); checkStatus=WeixinUtil.httpRequest(check_code_url.replaceAll("ACCESS_TOKEN", token), "POST", check.toJSONString()); if(checkStatus.getString("errcode").equals("0")){ check.remove("check_consume"); //覈銷卡券 JSONObject obj=WeixinUtil.httpRequest(delete_code_url.replaceAll("ACCESS_TOKEN", token), "POST", check.toJSONString()); if(obj.getString("errcode").equals("0")){ CardReceive card=new CardReceive(); JSONObject cardObj=(JSONObject) obj.get("card"); card.setCardId(cardObj.getString("card_id")); card.setUserCardCode(code); card.setOpenid(obj.getString("openid")); card.setSource("卡券覈銷記錄"); sqlcardReceive.save(card); map.put("status", 200); map.put("message", "覈銷成功"); }else{ map.put("status", 500); map.put("message", "覈銷失敗"); } }else{ map.put("status", 500); map.put("message", "卡券無效"); } } catch (Exception e) { map.put("status", 500); map.put("message", "服務器繁忙"); e.printStackTrace(); } // AjaxUtil.out(checkStatus.toJSONString(), response); AjaxUtil.writeJsonMap(map, response); } @RequestMapping("/baidu") public String baidu(){ return "redirect:http://www.baidu.com"; } }
微信驗證工具 微信js-sdk驗證 package com.web.wexin.util; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Formatter; import java.util.HashMap; import java.util.Map; import java.util.UUID; public class SignUtil { // 與接口配置信息中的Token要一致 private static String token = "weixinqxw"; /** * 驗證簽名 * * @param signature * @param timestamp * @param nonce * @return */ public static boolean checkSignature(String signature, String timestamp, String nonce) { String[] arr = new String[] { token, timestamp, nonce }; // 將token、timestamp、nonce三個參數進行字典序排序 Arrays.sort(arr); StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 將三個參數字符串拼接成一個字符串進行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 將sha1加密後的字符串可與signature對比,標識該請求來源於微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } /** * 將字節數組轉換爲十六進制字符串 * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 將字節轉換爲十六進制字符串 * * @param mByte * @return */ private static String byteToHexStr(byte mByte) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } /** * JS-SDK使用權限簽名算法 * @param jsapi_ticket * @param url * @return * 2016年8月25日 */ public static Map<Object, Object> sign(String jsapi_ticket, String url) { Map<Object, Object> ret = new HashMap<Object, Object>(); String nonce_str = create_nonce_str(); String timestamp = create_timestamp(); String string1; String signature = ""; //注意這裏參數名必須所有小寫,且必須有序 string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url=" + url; System.out.println(string1); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } ret.put("url", url); ret.put("jsapi_ticket", jsapi_ticket); ret.put("nonceStr", nonce_str); ret.put("timestamp", timestamp); ret.put("signature", signature); return ret; } private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } private static String create_nonce_str() { return UUID.randomUUID().toString(); } private static String create_timestamp() { return Long.toString(System.currentTimeMillis() / 1000); } }
package com.web.wexin.vo; /** * 網頁受權用 * @author admin * 2016年8月16日 */ public class OAuthInfo { private String accessToken; private String expiresin; private String refreshToken; private String openid; private String scope; public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getExpiresin() { return expiresin; } public void setExpiresin(String expiresin) { this.expiresin = expiresin; } public String getRefreshToken() { return refreshToken; } public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } public String getOpenid() { return openid; } public void setOpenid(String openid) { this.openid = openid; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } @Override public String toString() { return "OAuthInfo [accessToken=" + accessToken + ", expiresin=" + expiresin + ", refreshToken=" + refreshToken + ", openid=" + openid + ", scope=" + scope + "]"; } }