从零开发微信公众号系列 【三】接收和自动回复消息


微信文档 

如果微信官方文档已能为您提供帮助,请忽略本文。

WechatController.java

package com.blacklist.cotroller;

import java.io.IOException;
import java.util.Map;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.blacklist.enums.WechatType;
import com.blacklist.server.WechatService;

@RestController
@SpringBootApplication
@RequestMapping("/wechat")
@Scope("prototype")
public class WechatController {
	@Autowired
	private WechatService wechatService;

	@RequestMapping(method = { RequestMethod.POST, RequestMethod.GET }, produces = "text/html;charset=UTF-8")
	@ResponseBody
	public void index(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		boolean isGet = request.getMethod().toLowerCase().equals("get");
		if (isGet) {// 接入指引
			String signature = request.getParameter("signature");
			String timestamp = request.getParameter("timestamp");
			String nonce = request.getParameter("nonce");
			String echostr = request.getParameter("echostr");
			if (wechatService.validate(signature, timestamp, nonce)) {
				response.getWriter().write(echostr);
			}
		} else {// 接收用户消息
			Map<String, String> reqMap = wechatService.parseReq(request);
			if ("text".equalsIgnoreCase(reqMap.get("MsgType"))) {
				String input = wechatService.buildResponse(reqMap, WechatType.TEXT);
				response.getWriter().write(input);
			} else if("event".equalsIgnoreCase(reqMap.get("MsgType"))
					&& "subscribe".equalsIgnoreCase(reqMap.get("Event"))){
				String input = wechatService.buildResponse(reqMap, WechatType.EVENT);
				response.getWriter().write(input);
			}else {
				String input = wechatService.buildResponse(reqMap, WechatType.IMAGE);
				response.getWriter().write(input);
			}
		}
	}

}
WechatService.java
package com.blacklist.server;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.blacklist.config.WechatConfig;
import com.blacklist.domain.Topic;
import com.blacklist.domain.enums.TopicEnum;
import com.blacklist.enums.WechatType;
import com.blacklist.utils.FreemarkerUtils;
import com.blacklist.utils.LuceneIKUtil;
import com.blacklist.utils.SHA1;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

@Service
public class WechatService {
	private static Logger log = LoggerFactory.getLogger(WechatService.class);

	public String getToken() throws IOException {
		if ((System.currentTimeMillis() / 1000 - WechatConfig.expiresTime) > 7000) {
			String pathUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
					+ WechatConfig.appid
					+ "&secret="
					+ WechatConfig.secret;
			URL url = new URL(pathUrl);
			HttpURLConnection httpConn = (HttpURLConnection) url
					.openConnection();
			httpConn.setDoOutput(true);// 使用 URL 连接进行输出
			httpConn.setDoInput(true);// 使用 URL 连接进行输入
			httpConn.setUseCaches(false);// 忽略缓存
			httpConn.setRequestMethod("GET");// 设置URL请求方法
			httpConn.setRequestProperty("Accept", "*/*"); // 设置接收数据的格式
			httpConn.connect();

			int length = (int) httpConn.getContentLength();// 获取长度
			InputStream is = httpConn.getInputStream();
			if (length != -1) {
				byte[] data = new byte[length];
				byte[] temp = new byte[512];
				int readLen = 0;
				int destPos = 0;
				while ((readLen = is.read(temp)) > 0) {
					System.arraycopy(temp, 0, data, destPos, readLen);
					destPos += readLen;
				}
				String result = new String(data, "UTF-8");
				JsonObject json = new JsonParser().parse(result)
						.getAsJsonObject();
				WechatConfig.token = json.get("access_token")
						.getAsString();
				WechatConfig.expiresTime = System.currentTimeMillis() / 1000;
			}
		}

		System.out.println("wechat access token is:" + WechatConfig.token);
		return WechatConfig.token;
	}

	public boolean validate(String signature, String timestamp, String nonce) {
		List<String> list = new ArrayList<String>();
		list.add(timestamp);
		list.add(nonce);
		list.add(WechatConfig.token);
		Collections.sort(list);
		String temp = String.join("", list);
		if (signature.equals(SHA1.str2SHA1(temp))) {
			return true;
		}
		return false;
	}

	public Map<String, String> parseReq(HttpServletRequest request) {
		Map<String, String> resultMap = new HashMap<String, String>();
		try {
			InputStream inputStream = request.getInputStream();
			SAXReader reader = new SAXReader();
			Document document = reader.read(inputStream);
			Element root = document.getRootElement();
			@SuppressWarnings("unchecked")
			List<Element> elementList = root.elements();
			for (Element e : elementList) {
				resultMap.put(e.getName(), cut(e.getText()));
			}
			inputStream.close();
			inputStream = null;
		} catch (IOException | DocumentException e1) {
			log.error("wechat parseReq error:{}", e1.getMessage());
			e1.printStackTrace();
		}

		return resultMap;
	}

	public boolean validate() {
		return false;
	}
	
	private String cut(String str) {
		return str.replace("<![CDATA[", "").replace("]]>", "");
	}
	
	private String baseTextResponse(Map<String, String> map) {
		StringBuffer sb = new StringBuffer();
		sb.append("<xml>");
		sb.append("<ToUserName><![CDATA[" + map.get("FromUserName")
				+ "]]></ToUserName>");
		sb.append("<FromUserName><![CDATA[" + map.get("ToUserName")
				+ "]]></FromUserName>");
		sb.append("<CreateTime>" + System.currentTimeMillis() / 1000
				+ "</CreateTime>");
		sb.append("<MsgType><![CDATA[text]]></MsgType>");
		sb.append("<Content><![CDATA[###MSG###]]></Content>");
		sb.append("</xml>");
		return sb.toString();
	}

	private String buildNotSupportResponse(Map<String, String> map) {
		return baseTextResponse(map).replace("###MSG###", "不支持的消息!");
	}

	private String buildWelcome(Map<String, String> map) {
		return baseTextResponse(map).replace("###MSG###", "然而,你并不知道怎么玩");
	}
	
	private String buildError(Map<String, String> map, String err) {
		return baseTextResponse(map).replace("###MSG###", err);
	}

	private String buildResponse(Map<String, String> map) {
		String content = map.get("Content");
		if(WechatConfig.autoUser.equalsIgnoreCase(map.get("FromUserName"))) {
			return baseTextResponse(map).replace("###MSG###", "hello,"+content);
		} else {
			log.info("from user is:{}", map.get("FromUserName"));
			return buildNotSupportResponse(map);
		}
	}

	public String buildResponse(Map<String, String> map,
			WechatType type) {
		switch (type) {
		case TEXT:
			return buildResponse(map);
		case EVENT:
			return buildWelcome(map);
		default:
			return buildNotSupportResponse(map);
		}
	}
}
SHA1.java见 上一篇

附请求参数:
响应参数:

转载请注明来源【 IT黑名单
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前端微信公众号开发流程一般包括以下步骤: 1. 注册微信公众号:首先,你需要在微信公众平台上注册一个公众号。根据你的需求,可以选择订阅、服务或企业。 2. 设置服务器:在公众平台上,你需要设置服务器用于接收和处理微信服务器发送的消息。你需要提供一个能够响应微信服务器验证的URL,并配置合法域名。 3. 开发公众号后台:你可以选择使用开发框架(如Node.js、Java等)来开发公众号后台,用于处理微信服务器发送的消息和事件。根据需求,你可能需要实现菜单管理、自动回复、素材管理等功能。 4. 开发前端页面:根据你的设计需求和业务逻辑,开发前端页面。你可以使用HTML、CSS和JavaScript等技术来构建用户界面,并与后台交互获取数据。 5. 微信JS-SDK的使用:如果你需要在公众号中使用微信的JS-SDK功能(如分享、支付等),你需要在前端页面中引入相应的JS文件,并按照文档说明进行相应的配置和调用。 6. 调试和测试:在开发过程中,及时进行调试和测试,确保公众号的正常运行和符合预期的功能。 7. 提交审核和发布:当你开发完成并测试通过后,可以在微信公众平台上提交审核。审核通过后,你可以正式发布你的公众号。 请注意,以上仅为一般的开发流程,具体的步骤和实现方式可能因个人需求和技术栈而异。在开发过程中,你可以参考微信公众平台的开发文档和示例代码,以便更好地理解和实现相应功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值