微信公衆號開發_CustomController中的代碼(三)

package com.igoxin.weixin.custom;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.igoxin.base.UrlRoute;
import com.igoxin.base.WeiXinConfig;
import com.igoxin.util.CommonUtil;

import net.sf.json.JSONObject;

/**
 * 微信公衆號的自定義處理Controller
 * 
 * 整體是微信公衆號的自定義操作 1.自定義回覆 2.自定義界面佈局
 * 
 * @author fanglanfeng
 *
 */
@Controller
@RequestMapping(UrlRoute.WEIXIN)
public class CustomController {

	// 解析微信傳遞過來的內容,並處理需要返回的數據
	public String analyticalWechatMag(String xml) {

		/** 解析xml數據 */
		ReceiveXmlEntity xmlEntity = new ReceiveXmlProcess().getMsgEntity(xml);
		/** 回覆內容 */
		String result = "直接在公衆號內留言即可,我們會第一時間爲您處理留言格式爲:訂單號 + 收貨人姓名 + 手機號碼 + 問題";// "詳情請諮詢購信官網:http://www.igoxin.com";
		String msgType = xmlEntity.getMsgType();

		/*
		 * TODO - 後期做擴展用 // 文本消息 if
		 * (msgType.equals(MessageType.REQ_MESSAGE_TYPE_TEXT)) { result =
		 * "您發送的是文本消息!"; } // 圖片消息 else if
		 * (msgType.equals(MessageType.REQ_MESSAGE_TYPE_IMAGE)) { result =
		 * "您發送的是圖片消息!"; } // 地理位置消息 else if
		 * (msgType.equals(MessageType.REQ_MESSAGE_TYPE_LOCATION)) { result =
		 * "您發送的是地理位置消息!"; } // 鏈接消息 else if
		 * (msgType.equals(MessageType.REQ_MESSAGE_TYPE_LINK)) { result =
		 * "您發送的是鏈接消息!"; } // 音頻消息 else if
		 * (msgType.equals(MessageType.REQ_MESSAGE_TYPE_VOICE)) { result =
		 * "您發送的是音頻消息!"; }
		 */

		// 判斷事件
		if (MessageType.REQ_MESSAGE_TYPE_EVENT.endsWith(msgType)) {
			// 點擊了自定義菜單點擊事件
			if ("CLICK".endsWith(xmlEntity.getEvent())) {
				if ("customerService".endsWith(xmlEntity.getEventKey())) {
					result = "直接在公衆號內留言即可,我們會第一時間爲您處理留言格式爲:訂單號 + 收貨人姓名 + 手機號碼 + 問題";
				}
				// 這裏是關注和取消關注
			} else {
				result = "客官好!終於等到您了。點擊【購信拼團】,開啓品質新生活。" + "【購信鮮花】現已正式上線,推出單品包月,混合花束包月,首單贈送精美條紋花瓶。"
						+ "點擊【購信鮮花】,同您一起open happiness1!" + "~TIPS:1.售後問題請直接聯繫服務號,給服務號留言即可;"
						+ "或直接撥打客服電話:400-033-06122.購信拼團每日爲您精挑細選15款高品質拼團商品。";
			}
		}
		// 事件推送之外的所有處理
		else {
			String str = xmlEntity.getContent();
			result = processingString(str);
		}
		System.out.println("analyticalWechatMag=====result====" + result);
		return result;
	}

	// TODO - 回覆處理 - 爲了後期擴展用,單獨處理
	private String processingString(String str) {
		String result = "";
		System.out.println("WechatProcess==The content you entered is====" + str);
		if (str.contains("+")) {
			result = "不要着急,物流的派送時間爲3天呢";
			return result;
		} else { // 如果沒有指定的關鍵字,統一回復爲鮮花二維碼圖片
			result = "image";
			return result;
		}
	}

	/**
	 * - - 公衆號消息被動回覆 - -
	 */
	@RequestMapping(UrlRoute.WEIXIN_MESSAGE_XIAO)
	@ResponseBody
	public void xiaoMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
		flowerMessage(request, response);
	}

	@RequestMapping(UrlRoute.WEIXIN_MESSAGE_FLOWER)
	@ResponseBody
	public void flowerMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {

		/** 判斷是否是微信接入激活驗證,只有首次接入驗證時纔會收到echostr參數,此時需要把它直接返回 */
		String echostr = request.getParameter("echostr");
		// 判斷是否是第一次
		if (echostr != null && echostr.length() > 1){
			System.out.println("For the first time ======one====");
			echostrMessageVerification(request, response);
		} else {
			
			System.out.println("For the not first time ======notOne====");
			System.out.println("flowerMessage=========request==========" + request);
			
			request.setCharacterEncoding("UTF-8");
			response.setCharacterEncoding("UTF-8");

			String openid = request.getParameter("openid");
			
			/** 讀取接收到的xml消息 */
			StringBuffer sb = new StringBuffer();
			InputStream is = request.getInputStream();

			InputStreamReader isr = new InputStreamReader(is, "UTF-8");
			BufferedReader br = new BufferedReader(isr);
			String s = "";
			while ((s = br.readLine()) != null) {
				sb.append(s);
			}
			String xml = sb.toString(); // 爲接收到微信端發送過來的xml數據
			// 對微信發過來的數據進行解析
			String xmlString = analyticalWechatMag(xml);

			//最後返回給微信的xml數據
			String result = "";

			// 2.1 - 拿到access_token
			String appid = WeiXinConfig.APPID;
			String secret = WeiXinConfig.APPSECRET;
			String get_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid
					+ "&secret=" + secret;
			// 請求 token
			JSONObject jsonObjectToken = CommonUtil.httpsRequest(get_token, "GET", null);
			String access_token = (String) jsonObjectToken.get("access_token");

			if (!xmlString.contains("image")) {
				result = new WechatProcess().processWechatMagtText(xml, openid, xmlString);
			}
			// 統一回復爲鮮花二維碼圖片
			else {
				
				// 2.開始正常的處理
				// String url =
				// "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=";

				// 2.2 - 生成圖片
				// 二維碼圖片的內容
				String content = "http://packsale.gocent.net/index.html#/tab/index?sharerId=" + openid;
				String imagePath = "image/" + openid + ".png";

				// File fileImagePath = new File(imagePath);
				// if(fileImagePath.exists()){
				// }

				QRCodeUtils qrcode = new QRCodeUtils();
				// BufferedImage bufferIamge = qrcode.qRCodeCommon(content, "png",7);

				// 2.2.2這裏會將圖片臨時存放在項目的一個目錄中,可隨時刪除處理,由於一個圖片只有5k左右,所以在現有項目中的量不是很大
				qrcode.encoderQRCode(content, imagePath, "png", 7);

				// 2.3 - 將生成的圖片上傳到微信素材中心
				/**
				 * 上傳(這裏是根據項目做的臨時的圖片上傳處理),獲得media * access_token 獲取到的access_token *
				 * imagePath 圖片的位置(相對位置)
				 */

				// 2.3.1 - 微信返回的數據 - 這裏最主要是獲取到圖片在微信中的 media_id,
				// 因爲在發送圖片給用戶的時候,需要media_id(在微信素材庫的唯一標識),而不是圖片的url(更不是二進制數據)
				String jadonMedias = HttpUploadFile.uploadImage(access_token, imagePath);

				jadonMedias = jadonMedias.substring(1, jadonMedias.length() - 2);
				System.out.println("jadonMedias===" + jadonMedias);
				String[] strings = jadonMedias.split(",");

				System.out.println("strings===" + strings);

				Object media = "";

				Map<String, Object> mediasMap = new HashMap<String, Object>();
				for (String sss : strings) {
					String[] ms = sss.split(":");
					ms[0] = ms[0].substring(1, ms[0].length() - 1);
					ms[1] = ms[1].substring(1, ms[1].length() - 1);
					System.out.println("ms[0]===" + ms[0] + "ms[1]===" + ms[1]);
					if ("media_id".equals(ms[0])) {
						media = ms[1];
					}
					mediasMap.put(ms[0], ms[1]);
				}
				System.out.println("mediasMap.toString() === " + mediasMap.toString());
				String media_id = (String) mediasMap.get("media_id");
				// Object created_at = mediasMap.get("created_at");

				System.out.println("flowerMessage=====media_id========" + media);
				
				result = new WechatProcess().processWechatMagImage(xml, openid, media_id);
			}
			
			// 2.4 - 判斷用戶提交的內容、觸發的事件,判斷處理,返回給用戶對應的信息
			try {
				OutputStream os = response.getOutputStream();
				os.write(result.getBytes("UTF-8"));
				os.flush();
				os.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("flowerMessage==================result" + result);
		}
	}
	
	
	// ===================== -下面是--第一次在公衆號裏面配置的時候用--- ==================
	/**
	 * - - 公衆號消息被動回覆 - 驗證token 第一次配置的時候用 - 也可以直接將接口寫在下面使用
	 * 
	 */
	public void echostrMessageVerification(HttpServletRequest request, HttpServletResponse response)
			throws IOException {

		String signature = request.getParameter("signature");
		String echostr = request.getParameter("echostr");
		String timestamp = request.getParameter("timestamp");
		String nonce = request.getParameter("nonce");

		PrintWriter out = response.getWriter();
		if (checkSignature(signature, timestamp, nonce)) {
			System.out.println("check ok");
			out.print(echostr);
		}
		out.close();
		System.out.println("flowerMessage=========================" + request);
	}

	private boolean checkSignature(String signature, String timestamp, String nonce) {
		String token = "xiao2016";
		String[] arr = new String[] { token, timestamp, nonce };
		Arrays.sort(arr);
		String content = arr[0] + arr[1] + arr[2];
		MessageDigest md = null;
		String result = "";
		try {
			md = MessageDigest.getInstance("SHA-1");
			byte[] date = md.digest(content.toString().getBytes());
			// 將字節數組轉換成字符串
			result = bytesToStr(date);
			System.out.println("加密後的" + result);

		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result != null ? (result.equals(signature.toUpperCase())) : false;
	}

	// 將直接數組轉換成十六進制字符串
	private static String bytesToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	// 將一個字節轉換成16進制字符串
	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[] temp1 = new char[2];
		temp1[0] = Digit[mByte >>> 4 & 0X0F];
		temp1[1] = Digit[mByte & 0X0F];
		String str = new String(temp1);
		return str;
	}
	// ===================== -上面是:--第一次在公衆號裏面配置的時候用--- ==================

}

發佈了29 篇原創文章 · 獲贊 5 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章