目录结构
- 项目结构图
- 在本地创建项目并在Jetty成功部署运行
- 源代码
- 注册工具类
-
核心Servlet
- Web工程配置文件
- Maven工程文件
- 在GitHub上创建项目,上传本地代码
- 上传工程WAR档至SAE
- 配置微信的Token相关信息
- 参考文档
- 完整项目源代码
项目结构图
源代码文件说明
序号 | 文件名 | 说明 |
1 | readme.txt | 项目说明文件 |
2 | pom.xml | Maven工程文件 |
3 | web.xml | Web项目配置文件(这里主要配置Servlet的信息) |
4 | index.jsp | 首页文件,显示时间信息,主要用来判断工程是否部署成功 |
5 | SignUtil.java | 工具类 |
6 | Coreservlet.java | 获取Token的Servlet |
在本地创建项目并在Jetty成功部署运行
确保工程在eclipse的Jetty容器中成功运行(SAE是基于Jetty的,不是Tomcat)
Running Jetty 6.1.26 2014-10-20 14:01:27.605:INFO::Logging to STDERR via org.mortbay.log.StdErrLog ParentLoaderPriority enabled Context path:/wxquan ProjectClassLoader: entry=D:\E422\workspace2\wxquan\target\classes ProjectClassLoader: entry=D:\Java\apache-maven-3.1.0\repo\javax\servlet\servlet-api\2.4\servlet-api-2.4.jar ProjectClassLoader: entry=D:\Java\apache-maven-3.1.0\repo\javax\servlet\jsp\jsp-api\2.1\jsp-api-2.1.jar Excluded entry=D:\E422\workspace2\wxquan\target\test-classes 2014-10-20 14:01:27.649:INFO::jetty-6.1.26 2014-10-20 14:01:27.853:INFO::Started SelectChannelConnector@0.0.0.0:8080
在浏览器中测试工程:
源代码
注册工具类
SignUtil.java
package com.coderdream.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import org.apache.log4j.Logger; /** * 请求校验工具类 * */ public class SignUtil { public static String TAG = "SignUtil"; /** * 与开发模式接口配置信息中的Token保持一致 */ private static String token = "weixinToken"; /** * 校验签名 * * @param signature * 微信加密签名 * @param timestamp * 时间戳 * @param nonce * 随机数 * @return */ public static boolean checkSignature(String signature, String timestamp, String nonce) { Logger logger = Logger.getLogger(SignUtil.class); Date utilDate = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String str = sdf.format(utilDate); logger.debug(TAG + " checkSignature " + str); // 对token、timestamp和nonce按字典排序 String[] paramArr = new String[] { token, timestamp, nonce }; Arrays.sort(paramArr); // 将排序后的结果拼接成一个字符串 String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]); String ciphertext = null; try { MessageDigest md = MessageDigest.getInstance("SHA-1"); // 对接后的字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); ciphertext = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // 将sha1加密后的字符串与signature进行对比 boolean flag = ciphertext != null ? ciphertext.equals(signature.toUpperCase()) : false; logger.debug(TAG + " checkSignature result: " + flag); return flag; } /** * 将字节数组转换为十六进制字符串 * * @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; } }
核心Servlet
CoreServlet.java
package com.coderdream.servlet; 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.coderdream.util.SignUtil; /** * 请求处理的核心类 * */ public class CoreServlet extends HttpServlet { private static final long serialVersionUID = 4440739483644821986L; /** * 请求校验(确认请求来自微信服务器) */ 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(); // 请求校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (SignUtil.checkSignature(signature, timestamp, nonce)) { out.print(echostr); } out.close(); out = null; } /** * 处理微信服务器发来的消息 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO 消息的接收、处理、响应 } }
Web工程配置文件
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>weixin</display-name> <servlet> <servlet-name>coreServlet</servlet-name> <servlet-class>com.coderdream.servlet.CoreServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>coreServlet</servlet-name> <url-pattern>/coreServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
Maven工程文件
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.coderdream</groupId> <artifactId>wxquan</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>wxquan Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.4</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>wxquan</finalName> </build> </project>
在GitHub上创建项目并上传本地代码
先在GitHub上创建项目
先将代码添加到本地的Git库
选择工程,右键,Team -> Share Project...
选“Git”:
勾选“Use or create repository in parent folder of project”,这个选项的意思是在本地(父文件夹中)创建git库:
出现警告,不用理会,点“Create Repository”按钮:
本地Git库创建成功,点“Finish”按钮,完成创建。
由于Build以后会生成Target目录,而我们不希望上传这个目录到Git的托管库GitHub中,所以我们需要过滤这个文件夹
运行“Git Bash”工具(这个工具安装Git后就有了),转到工程文件夹下,这里是 D:\E422\workspace2\wxquan
修改前(target文件上有问号):
修改后(target文件上没有问号了):
准备提交代码到GitHub:
选择项目,右键,Team -> Commit...
输入注释,选择所有的文件(这里为了以后导入工程方便,我们把所有的工程文件也加进去,一个20个文件)
在此之前要先配置好 eclipse 的 Git:
输入项目的git地址:
如果没有问题,“Source ref:”的下拉框会有值,选择“refs/heads/master”,然后点击右边的“Add Spec”:
这样,下面的“Specifications for push”就有内容了,然后点击“Finish”按钮,开始提交:
开始提交:
正在提交:
提交完成:
刷新浏览器,查询GitHub中的项目信息:
上传工程WAR档至SAE
将eclipse中的工程导出为wxquan.war档,上传到SAE中,成功部署后测试工程:
配置微信的Token相关信息
登录微信公众平台后,选左边的【开发者中心】:
输入正确的URL和Token(这些在由服务器中的项目名称和相关设置确定),同时自动生成“EncodingAESKey“
成功后会得到“提交成功”的信息。
最后的结果:
成功订阅后可以收到消息:
参考文档
完整源代码
相关推荐
微信公众号平台发开书籍与实例文档 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
微信公众平台应用开发实战-完整扫描版.pdf 全书一共9章,在逻辑上分为四大部分:第一部分(第1章)介绍了微信公众平台的开发模式、数据交互方式,以及开发公众平台应用所需要的各项技术;第二部分(第2~4章)首先...
微信开发实例 微信公众平台开发教程-深入浅出微信公众平台实战开发(微网站、LBS云、Api接口调用、服务号高级接口)1.微信接口前期准备。由北风网提供,微信开发实例微信公众平台基础篇: 1)微信公众平台简介:开发...
第二部分(第2、3章)介绍了进行微信公众平台开发所需的准备工作及将应用接入微信公众平台的方法;第三部分(第4、5章)详细介绍了微信公众平台已开放的API,通过实战项目对开发框架进行了系统讲解,读者甚至可以...
刘捷版微信公众平台企业应用开发实战 Sample源码以及相关SDK
全书一共9章,在逻辑上分为四大部分:第一部分(第1章)介绍了微信公众平台的开发模式、数据交互方式,以及开发公众平台应用所需要的各项技术;第二部分(第2~4章)首先详细讲解了微信公众平台开放的所有API的功能...
《微信公众平台应用开发实战》一共9章,在逻辑上分为四大部分:第一部分(第1章)介绍了微信公众平台的开发模式、数据交互方式,以及开发公众平台应用所需要的各项技术;第二部分(第2~4章)首先详细讲解了微信公众...
对微信公众平台开发有兴趣的同学 对ASP.NET MVC开发有兴趣的同学 有志进入开发行业的所有同学 课程特色: 最前沿ASP.NET MVC 5、Entity Framework 6、微信公众平台5.2 最全6大功能19个接口用法大揭秘 零基础快速...
《企业微信公众平台开发实战:再小的个体也有自己的品牌》方倍工作室,2015年,配套源码。
ASP.NET MVC 5 微信公众平台整合开发实战第三部
微信公众平台应用开发实战-完整扫描版 PDF扫描版,放心下载。
《微信公众平台开发实战》(php版),手打完美书签,方便导航入阅读
全书一共9章,在逻辑上分为四大部分:第一部分(第1章)介绍了微信公众平台的开发模式、数据交互方式,以及开发公众平台应用所需要的各项技术;第二部分(第2~4章)首先详细讲解了微信公众平台开放的所有API的功能...
PHP微信公众平台开发,内容丰富,涵盖了多个PHP微信公众平台开发的方面,适合于初学者来学习借鉴。
微信公众平台开发入门教程
微信小程序点餐系统微信小程序开发实战项目源码+后台+数据库(毕业设计)微信小程序点餐系统微信小程序开发实战项目源码+后台+数据库(毕业设计)微信小程序点餐系统微信小程序开发实战项目源码+后台+数据库(毕业...
第二部分(第2、3章)介绍了进行微信公众平台开发所需的准备工作及将应用接入微信公众平台的方法;第三部分(第4、5章)详细介绍了微信公众平台已开放的API,通过实战项目对开发框架进行了系统讲解,读者甚至可以...
对微信公众平台开发有兴趣的同学 对ASP.NET MVC开发有兴趣的同学 有志进入开发行业的所有同学 课程特色: 最前沿ASP.NET MVC 5、Entity Framework 6、微信公众平台5.2 最全6大功能19个接口用法大揭秘 零基础快速...