微信公众号开发学习笔记(一) -- 接入
2017-02-10 15:58
260 查看
微信公众号开发入门(一) -- 接入
测试号申请
由于项目还处在演示版和研发初期, 客户并没有提供正式的公众号, 所以暂时使用测试号进行研发.测试号申请地址
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
开发者扫码即可申请成功, 申请成功后如下图:
![](https://images2015.cnblogs.com/blog/667290/201702/667290-20170210155626932-1428238408.png)
测试号信息:
appID和appsecret相当于公众号的一把钥匙, 可以用来获取全局唯一票据access_token.
接口配置信息:
URL: 开发者用来接收微信消息和事件的接口URL
Token: 由开发者可以任意填写, 用作生成签名(该Token会和接口URL中包含的Token进行比对, 从而验证安全性)
准备外网环境
我们需要有一台能被互联网所访问的服务器, 没有也没有关系, 市面上各种云服务器还是比较好用的.可以将我们的发布包部署在上面. ngrok也可以
微信公众号接口只支持80端口
编写接入程序(Java)
这里用的是Servlet, 用其他技术也是可以的比如spring mvc.新建一个Servlet, 命名为CoreController, 作为核心控制器
get方法作为接入微信服务的接口
post方法预留, 用于接收用户请求
package com.thunisoft.wechat.connect; import java.io.IOException; import java.util.Arrays; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.thunisoft.wechat.util.PropertiesLoader; import com.thunisoft.wechat.util.Sha1Util; public class CoreController extends HttpServlet { /** 日志 */ private final Logger LOGGER = LoggerFactory.getLogger(CoreController.class); /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 微信加密签名, signature结合了开发者填写的token参数和请求中的timestamp参数, nonce参数。 String signature = request.getParameter("signature"); // 时间戳 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echostr = request.getParameter("echostr"); String token = PropertiesLoader.getProperty("token"); /* * 加密/校验流程如下: * 1. 将token、timestamp、nonce三个参数进行字典序排序 * 2. 将三个参数字符串拼接成一个字符串进行sha1加密 * 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信 * 4. 返回echostr */ String[] tmpStrArr = {token, timestamp, nonce}; Arrays.sort(tmpStrArr); StringBuilder tmpStr = new StringBuilder(); for(int i=0; i<tmpStrArr.length; i++) { String temp = tmpStrArr[i]; tmpStr.append(temp); } if(Sha1Util.checkSignature(signature, tmpStr.toString())) { response.getWriter().print(echostr); LOGGER.info("------接入成功------"); } else { LOGGER.info("------接入失败------"); } } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
其中, token就是公众号配置页面中所填写的token, 这里把它写在了配置文件wechat.properties中.
#Token token=wechat
CoreController在web.xml中的配置:
<!-- 微信接入 --> <servlet> <servlet-name>CoreController</servlet-name> <servlet-class>com.thunisoft.wechat.connect.CoreController</servlet-class> </servlet> <servlet-mapping> <servlet-name>CoreController</servlet-name> <url-pattern>/connect</url-pattern> </servlet-mapping>
url-pattern为
/connect, 要与公众号配置页面中所填写的URL一致.
CoreController中用到了PropertiesLoader和Sha1Util两个类,
PropertiesLoader用于加载配置文件wechat.properties, 并提供配置项的值, 代码如下:
package com.thunisoft.wechat.util; import java.io.BufferedInputStream; import java.io.InputStream; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PropertiesLoader { private static final Logger logger = LoggerFactory.getLogger(PropertiesLoader.class); private static final String CONFIG_PROPERTIES = "/props/wechat.properties"; private static Properties properties = new Properties(); static { // load wechat.properties InputStream in = PropertiesLoader.class.getResourceAsStream(CONFIG_PROPERTIES); if (in == null) { logger.error("{} not found", CONFIG_PROPERTIES); throw new RuntimeException(CONFIG_PROPERTIES + " not found"); } else { if (!(in instanceof BufferedInputStream)) { in = new BufferedInputStream(in); } try { properties.load(in); in.close(); logger.debug("{} loaded", CONFIG_PROPERTIES); } catch (Exception e) { logger.error("Error while processing {}", CONFIG_PROPERTIES); throw new RuntimeException("Error while processing " + CONFIG_PROPERTIES, e); } } } public static String getProperty(final String key) { return properties.getProperty(key); } }
Sha1Util用于sha1加密以及验证sha1加密票据, 代码如下:
package com.thunisoft.wechat.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Sha1Util * @author 第七狙击手 * @version 1.0 * */ public class Sha1Util { /** 字符数组 */ private static char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** 日志 */ private static final Logger LOGGER = LoggerFactory.getLogger(Sha1Util.class); /** * sha1加密 * @param src 待加密字符串 * @return 加密字符串 */ public static String encrypt(String src) { String sha1Dest = null; MessageDigest md = null; try { md = MessageDigest.getInstance("SHA-1"); byte[] digest = md.digest(src.getBytes()); sha1Dest = byteToStr(digest); } catch (NoSuchAlgorithmException e) { LOGGER.error("加密失败!", e); } return sha1Dest; } /** * 验证sha1签名 * @param signature sha1签名 * @param src 待加密串 * @return 通过是否验证 */ public static boolean checkSignature(String signature, String src) { String sha1Dest = encrypt(src); return sha1Dest != null ? sha1Dest.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[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } }
如有错误, 请随时指正, 谢谢!
如需转载, 请注明作者及出处.
作者:第七狙击手
出处:http://www.cnblogs.com/lzj0616/
相关文章推荐
- 微信公众号JAVA开发学习笔记(一) 公众号开发准备
- JAVA微信订阅号开发者模式接入(java微信开发学习笔记1)
- 适合新手学习的laravel接入微信接口,实现微信公众号二次开发
- 微信学习开发笔记:一、微信的接入
- java微信公众号开发学习笔记(一)——vps购买及tomcat服务器搭建
- 学习php微信开发应用接入API接口笔记
- java微信公众号开发学习笔记(二)——安装eclipse 及token验证
- 微信公众号开发笔记3-sdk接入(nodejs)
- Java软件开发学习笔记(一)
- J2ME学习笔记(四)-----用特定的MIDP API开发MIDlets
- 数据库开发技术与工程实践 学习笔记
- Java软件开发学习笔记(一)
- 用S60操作系统SDK开发NOKIA手机应用程序-学习笔记(3)
- 《Web Service 编程 --用C#.NET 开发网络服务》北京希望出版社 我的学习笔记(第二章)(也就是书上抄了一写东西而已)
- 嵌入式开发学习笔记--第一课
- 游戏开发学习笔记(一)--采用何种语言开发
- 开发asp.net自定义控件(asp.net学习笔记二)
- Java软件开发学习笔记(四)
- Java软件开发学习笔记(三)
- 用S60操作系统SDK开发NOKIA手机应用程序-学习笔记(1)