微信公众号开发_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 mediasMap = new HashMap();
				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;
	}
	// ===================== -上面是:--第一次在公众号里面配置的时候用--- ==================

}

你可能感兴趣的:(微信公众号开发)