微信公众号Java接入demo
微信公众号Java接入demo
前不久买了一台服务,本来是用来当梯子用的,后来买了一个域名搭了一个博客网站,后来不怎么在上面写博客一直闲着,最近申请了一个微信公众号就想着弄点什么玩玩。周末没事就鼓捣了下微信公众号的接入。
准备工作
一台能用域名访问的服务器
一个微信公众号
给服务器装上jdk、tomcat、ftp、shell工具
编码
登录测试公众号后台,获取appId和appSecret,新建一个配置文件来保存ppId和appSecret,也可以直接写在代码里,个人不建议这么写,在项目中经常会用到一些常量或者说是资源配置,比如要接入其他公司推给你的数据,会给你接口地址、验证码什么的统一建一个配置文件存放会比较好一点,在以后的频繁的修改中就会凸显出重要性,从软件的结构来看也比较清晰。
-新建一个servlet,编写代码,下面图片是微信公众号的基本配置界面,在下图的url 上填写你服务器用来接受微信验证的url,url必须以http://或https://开头,分别支持80端口和443端口。用来接收微信消息和事件接口的urltoken随便填写,加密方式我选择了安全模式,
这里写图片描述
先贴代码,本人文档水平有限:
这是一个servlet文件,用来处理微信发过来的认证请求;
package myservlet;
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;
/**
* Servlet implementation class MyServlet
*/
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
boolean isSuccess = CheckUtil.check(signature, timestamp, nonce);
if(isSuccess) {
pw.print(echostr);
pw.write("接入成功!");
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
验证方法
/**
* @Title: CheckUtil.java
* @Package myservlet
* @Description: TODO(用一句话描述该文件做什么)
* @author wjk
* @date 2018年7月5日
* @version V1.0
*/
package myservlet;
import java.util.Arrays;
/**
* @ClassName: CheckUtil
* @Description: TODO(这里用一句话描述这个类的作用)
* @author wjk
* @date 2018年7月5日
*
*/
public class CheckUtil {
public static final String token ="##";
public static boolean check(String signature,String timestamp,String nonce ) {
String arrs[] = {token,timestamp,nonce};
Arrays.sort(arrs);//字典排序
//拼接字符串
StringBuffer sb = new StringBuffer();
for(String str :arrs) {
sb.append(str);
}
String signaturesha1 = Sha1Util.encode(sb.toString());
return signaturesha1.equals(signature);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
sha1加密
package myservlet;
import java.security.MessageDigest;
public final class Sha1Util {
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f' };
/**
*
* @Title: getFormattedText
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param @param bytes
* @param @return 参数
* @return String 返回类型
* @throws
*/
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
// 把密文转换成十六进制的字符串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
/**
*
* @Title: encode
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param @param str
* @param @return 参数
* @return String 返回类型
* @throws
*/
public static String encode(String str) {
if (str == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
messageDigest.update(str.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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_3_0.xsd" id="WebApp_ID" version="3.0">
<servlet>
<!--servlet名称,可以自定义-->
<servlet-name>MyServlet</servlet-name>
<!-- servlet类名: 包名+简单类名-->
<servlet-class>myservlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--servlet名称,应与上面的名称保持一致,因为是通过下面的servlet访问名称来定位到上面的servlet名称,再通过上面的名称定位到servlet类的位置-->
<servlet-name>MyServlet</servlet-name>
<!-- servlet的访问名称: /名称 -->
<url-pattern>/helloMyServlet.do</url-pattern>
</servlet-mapping>
</web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
原理
将token,timestamp,nonce进行字典排序,拼接成一个字符串。
将字符串进行sha1加密。
将加密后的字符创和signature比较。true则提交成功,请原样返回echostr参数内容;false则为失败。
微信公众号Java接入demo的更多相关文章
- 玩玩微信公众号Java版之七:自定义微信分享
前面已经学会了微信网页授权,现在微信网页的功能也可以开展起来啦! 首先,我们先来学习一下分享,如何在自己的页面获取分享接口及让小伙伴来分享呢? 今天的主人公: 微信 JS-SDK, 对应官方链接为:微 ...
- Java 微信公众号开发--- 接入微信
开发微信公众号在没有正式的公众平台账号时,我们可以使用测试平台账号--- 测试平台申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandb ...
- 玩玩微信公众号Java版之一:配置微信公众平台服务器信息
在进行微信公众平台开发前,前先做好准备工作,好了以后,我们可以开始啦! 第一.准备好服务端接口 定义一个http服务接口,主要分为如下几步: 1.创建一个servlet类,用来接收请求: ...
- 玩玩微信公众号Java版之准备
微信自2013年流行起来,现在的发展已经超过了我们的想象,那么对应的公众平台,小程序等都是让人眼前一亮的东西,这里来学习一下微信工作号的对接,实现为Java,希望大家一起学习! 这里大概描述一下所 ...
- 玩玩微信公众号Java版之四:自定义公众号菜单
序: 微信公众号基本的菜单很难满足个性化及多功能的实现,那么微信能否实现自定菜单呢,具体的功能又如何去实现么?下面就来学习一下微信自定义公众号菜单吧! 自定义菜单接口可实现多种类型按钮,如下: 1.c ...
- 微信公众号java开发思路
方法一:不开启开发模式,直接在自定义菜单中跳转到网页,适用于流量较小的公众号. 方法二:开启开发者模式,关闭自带的自定义菜单和消息回复,接入自己开发的应用 1.接入校验:创建s ...
- 玩玩微信公众号Java版之六:微信网页授权
我们经常会访问一些网站,用微信登录的时候需要用到授权,那么微信网页授权是怎么一回事呢,一起来看看吧! 参考官方文档:https://mp.weixin.qq.com/wiki?t=resource ...
- 玩玩微信公众号Java版之三:access_token及存储access_token
微信官方参考文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183 基本说明: access_token是 ...
- 玩玩微信公众号Java版之五:获取关注用户信息
在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同).公众号可通过本接口来根据Op ...
随机推荐
- jquery移除元素时会自动解绑事件
.html() When .html() is used to set an element's content, any content that was in that element is co ...
- ie8网页时调用特定的css文件
加上条件注释语句<!--[if IE 8]><link rel="".........................><![endif]--> ...
- 《Linux内核原理与分析》第八周作业
课本:第七章 可执行程序工作原理 ELF目标文件格式 目标文件:编译器生成的文件. 目标文件的格式:out格式.COFF格式.PE(windows)格式.ELF(Linux)格式. ELF(Execu ...
- JavaScript 实现打印操作
一.打印当前页面指定元素中的内容 方式一:直接使用window.print(); (1)首先获得元素的html内容(这里建议如果有样式最好是用内联样式的方式) var newstr = documen ...
- IIS 集成模式 导致 AjaxPro 无法正常运行
web.config 配置如下: system.web/httphandlers <httpHandlers> <add verb="POST,GET" path ...
- ARTIFICIAL INTELLIGENCE FOR GAMES (Ian Millington / John Funge 著)
相关网站:http://www.ai4g.com PART I AI AND GAMESCHAPTER1 INTRODUCTIONCHAPTER2 GAME AIPART II TECHNIQUESC ...
- oracle-data-mining
create user datamine identified by 123456 QUOTA UNLIMITED ON users; 然后在sqldeveloper工具界面-data miner中, ...
- 单源最短路径Dijkstra算法,多源最短路径Floyd算法
1.单源最短路径 (1)无权图的单源最短路径 /*无权单源最短路径*/ void UnWeighted(LGraph Graph, Vertex S) { std::queue<Vertex&g ...
- 让所有浏览器支持HTML5 video视频标签
HTML5究竟需要多少种视频编码格式 当前,video 元素支持三种视频格式:Ogg = 带有 Theora 视频编码和 Vorbis 音频编码的 Ogg 文件MPEG4 = 带有 H.264 视频编 ...
- Java Collection - 001 集合的遍历
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.java.domain ...