微信公共平台接口开发--Java实现
Java微信实现,采用SpringMVC 架构,采用SAXReader解析XML
@RequestMapping(value="/extend")
public class WeixinController {
@RequestMapping(value="/weixin")
public ModelAndView weixin(HttpServletRequest request,HttpServletResponse response) {
String method=request.getMethod();
method=method.toLowerCase();
String signature=request.getParameter("signature");// — 微信加密签名
String timestamp=request.getParameter("timestamp");// — 时间戳
String nonce=request.getParameter("nonce");// — 随机数
String echostr=request.getParameter("echostr");// — 随机字符串
String token="";//token
ModelAndView mv = new ModelAndView("return");
if("get".equals(method)){
String diget=signature(token,timestamp,nonce);
if(diget.equals(signature)){//标识请求来自微信
mv.addObject("returnObject", echostr);
}
}else if("post".equals(method)){
try {
ServletInputStream inputStream = request.getInputStream();
if(null!=inputStream){
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(reader);
Element rootElm = document.getRootElement();
String toUserName = rootElm.element("ToUserName").getData().toString();// 消息接收方微信号,一般为公众平台账号微信号
String fromUserName = rootElm.element("FromUserName").getData().toString();// 消息发送方微信号
String createTime = rootElm.element("CreateTime").getData().toString();// 消息创建时间
String msgType = rootElm.element("MsgType").getData().toString();// 文本消息为text
String event="";
Element eventElement=rootElm.element("Event");
if(null!=eventElement){
Object object=eventElement.getData();
if(null!=object){
event=object.toString();// 文本消息为text
}
}
String content = "";
Element contentElement=rootElm.element("Content");
if(null!=contentElement){
Object object=contentElement.getData();
if(null!=object){
content=object.toString();// 文本消息为text
}
}
System.err.println(document.asXML()+"---->"+fromUserName+" send message to "+toUserName+": MsgType->"+msgType+" Content->"+content);
if("event".equals(msgType)&&"subscribe".equals(event)){
String reply=generReplyTextMessage(fromUserName,toUserName,"欢迎您关注无不网络微信公共账号,无不竭诚为您服务!");
mv.addObject("returnObject", reply);
}else{
String questionContent = "取消关注";
String xml=generReplyTextMessage(fromUserName,toUserName,questionContent);
mv.addObject("returnObject", xml);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
return mv;
}
private String generReplyTextMessage(String toUserName,String fromUserName,String content){
StringBuffer xml=new StringBuffer();
xml.append("<xml>");
xml.append("<ToUserName><![CDATA["+toUserName+"]]></ToUserName>");
xml.append("<FromUserName><![CDATA["+fromUserName+"]]></FromUserName>");
xml.append("<CreateTime>"+new Date().getTime()+"</CreateTime>");
xml.append("<MsgType><![CDATA[text]]></MsgType>");
xml.append("<Content><![CDATA["+content+"]]></Content>");
xml.append("<FuncFlag>0</FuncFlag>");
xml.append("</xml>");
return xml.toString();
}
/**
* 验证微信
* @param token
* @param timestamp
* @param nonce
* @return
*/
private static String signature(String token, String timestamp, String nonce) {
String[] str = { token, timestamp, nonce };
Arrays.sort(str); // 字典序排序
String bigStr = str[0] + str[1] + str[2];
// SHA1加密
String digest = new SHA1().getDigestOfString(bigStr.getBytes()).toLowerCase();
return digest;
}
}
SHA1加密算法
public class SHA1 {
private final int[] abcde = { 0x67452301, 0xefcdab89, 0x98badcfe,
0x10325476, 0xc3d2e1f0 };
// 摘要数据存储数组
private int[] digestInt = new int[5];
// 计算过程中的临时数据存储数组
private int[] tmpData = new int[80];
// 计算sha-1摘要
private int process_input_bytes(byte[] bytedata) {
// 初试化常量
System.arraycopy(abcde, 0, digestInt, 0, abcde.length);
// 格式化输入字节数组,补10及长度数据
byte[] newbyte = byteArrayFormatData(bytedata);
// 获取数据摘要计算的数据单元个数
int MCount = newbyte.length / 64;
// 循环对每个数据单元进行摘要计算
for (int pos = 0; pos < MCount; pos++) {
// 将每个单元的数据转换成16个整型数据,并保存到tmpData的前16个数组元素中
for (int j = 0; j < 16; j++) {
tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4));
}
// 摘要计算函数
encrypt();
}
return 20;
}
// 格式化输入字节数组格式
private byte[] byteArrayFormatData(byte[] bytedata) {
// 补0数量
int zeros = 0;
// 补位后总位数
int size = 0;
// 原始数据长度
int n = bytedata.length;
// 模64后的剩余位数
int m = n % 64;
// 计算添加0的个数以及添加10后的总长度
if (m < 56) {
zeros = 55 - m;
size = n - m + 64;
} else if (m == 56) {
zeros = 63;
size = n + 8 + 64;
} else {
zeros = 63 - m + 56;
size = (n + 64) - m + 64;
}
// 补位后生成的新数组内容
byte[] newbyte = new byte[size];
// 复制数组的前面部分
System.arraycopy(bytedata, 0, newbyte, 0, n);
// 获得数组Append数据元素的位置
int l = n;
// 补1操作
newbyte[l++] = (byte) 0x80;
// 补0操作
for (int i = 0; i < zeros; i++) {
newbyte[l++] = (byte) 0x00;
}
// 计算数据长度,补数据长度位共8字节,长整型
long N = (long) n * 8;
byte h8 = (byte) (N & 0xFF);
byte h7 = (byte) ((N >> 8) & 0xFF);
byte h6 = (byte) ((N >> 16) & 0xFF);
byte h5 = (byte) ((N >> 24) & 0xFF);
byte h4 = (byte) ((N >> 32) & 0xFF);
byte h3 = (byte) ((N >> 40) & 0xFF);
byte h2 = (byte) ((N >> 48) & 0xFF);
byte h1 = (byte) (N >> 56);
newbyte[l++] = h1;
newbyte[l++] = h2;
newbyte[l++] = h3;
newbyte[l++] = h4;
newbyte[l++] = h5;
newbyte[l++] = h6;
newbyte[l++] = h7;
newbyte[l++] = h8;
return newbyte;
}
private int f1(int x, int y, int z) {
return (x & y) | (~x & z);
}
private int f2(int x, int y, int z) {
return x ^ y ^ z;
}
private int f3(int x, int y, int z) {
return (x & y) | (x & z) | (y & z);
}
private int f4(int x, int y) {
return (x << y) | x >>> (32 - y);
}
// 单元摘要计算函数
private void encrypt() {
for (int i = 16; i <= 79; i++) {
tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14]
^ tmpData[i - 16], 1);
}
int[] tmpabcde = new int[5];
for (int i1 = 0; i1 < tmpabcde.length; i1++) {
tmpabcde[i1] = digestInt[i1];
}
for (int j = 0; j <= 19; j++) {
int tmp = f4(tmpabcde[0], 5)
+ f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4]
+ tmpData[j] + 0x5a827999;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int k = 20; k <= 39; k++) {
int tmp = f4(tmpabcde[0], 5)
+ f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4]
+ tmpData[k] + 0x6ed9eba1;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int l = 40; l <= 59; l++) {
int tmp = f4(tmpabcde[0], 5)
+ f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4]
+ tmpData[l] + 0x8f1bbcdc;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int m = 60; m <= 79; m++) {
int tmp = f4(tmpabcde[0], 5)
+ f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4]
+ tmpData[m] + 0xca62c1d6;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int i2 = 0; i2 < tmpabcde.length; i2++) {
digestInt[i2] = digestInt[i2] + tmpabcde[i2];
}
for (int n = 0; n < tmpData.length; n++) {
tmpData[n] = 0;
}
}
// 4字节数组转换为整数
private int byteArrayToInt(byte[] bytedata, int i) {
return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16)
| ((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff);
}
// 整数转换为4字节数组
private void intToByteArray(int intValue, byte[] byteData, int i) {
byteData[i] = (byte) (intValue >>> 24);
byteData[i + 1] = (byte) (intValue >>> 16);
byteData[i + 2] = (byte) (intValue >>> 8);
byteData[i + 3] = (byte) intValue;
}
// 将字节转换为十六进制字符串
private static String byteToHexString(byte ib) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'B', 'C', 'D', 'E', 'F' };
char[] ob = new char[2];
ob[0] = Digit[(ib >>> 4) & 0X0F];
ob[1] = Digit[ib & 0X0F];
String s = new String(ob);
return s;
}
// 将字节数组转换为十六进制字符串
private static String byteArrayToHexString(byte[] bytearray) {
String strDigest = "";
for (int i = 0; i < bytearray.length; i++) {
strDigest += byteToHexString(bytearray[i]);
}
return strDigest;
}
// 计算sha-1摘要,返回相应的字节数组
public byte[] getDigestOfBytes(byte[] byteData) {
process_input_bytes(byteData);
byte[] digest = new byte[20];
for (int i = 0; i < digestInt.length; i++) {
intToByteArray(digestInt[i], digest, i * 4);
}
return digest;
}
// 计算sha-1摘要,返回相应的十六进制字符串
public String getDigestOfString(byte[] byteData) {
return byteArrayToHexString(getDigestOfBytes(byteData));
}
public static void main(String[] args) {
String data = "123456";
System.out.println(data);
String digest = new SHA1().getDigestOfString(data.getBytes());
System.out.println(digest);
// System.out.println( ToMD5.convertSHA1(data).toUpperCase());
}
}
微信公共平台接口开发--Java实现相关推荐
- 微信公众号api关注接口php,微信公众平台接口开发入门示例
本文实例讲述了微信公众平台接口开发入门示例.分享给大家供大家参考.具体如下: 微信公众平台的接口开发是一个现在比较常用的功能了,很多的人都会去了解一下微信公众平台一些简单开发应用,这里就来给大家介绍一 ...
- 微信公众平台接口开发基础
微信接口开发的要点:公众号(订阅号.服务号).微信公众号提供的对应接口限制等.微信平台开发几乎涵盖了各行各业,小程序也让微信着实火了一把,时代在不断地发展,开发也在不断地切换自己的思维和平台.俗话说, ...
- 一周的微信公众平台接口开发总结
2019独角兽企业重金招聘Python工程师标准>>> 在公司弄了一个星期的微信公众平台的接口开发,由于之前没弄过,开发的过程遇到了很多的小问题.下面我就总结一下我在开发过程中遇到了 ...
- 微信公众平台深度开发JAVA版第一季 30.菜单6
{"button":[{ "type": "click", "name": "说明001", &qu ...
- 微信公众平台深度开发JAVA版第一季 15.响应被动消息3
微信开发难度不大,但是逻辑关系很强. 这节课主要讲微信接口,至于在J2EE平台怎么把程序构造的更好不在这节课里面讨论. package net.wxinterface; import java.io. ...
- 微信公众平台深度开发JAVA版第一季 22.微信猜数字活动4
select count(*) from huo t where t.shuzi='0' 这个SQL语句查不查询得到记录取决于两个条件:第一个是数据库里面有没有这个数字,第二个是getCountByS ...
- 微信公众平台深度开发JAVA版第一季 10.接收普通消息3
获取到从腾讯服务器过来的字符串,业务服务器可以拼接出来可以打印出来.后续的工作是把这个字符串封装成一个Bean对象. <xml><ToUserName><![CDATA[ ...
- 微信公众平台深度开发JAVA版第一季 08.接收普通消息1
上一节讲了开发的接口接入这一部分,这是非常重要的. 实现业务的逻辑应该写在POST方法这一块. GET是消息验证用的,验证接口那一块的. XML数据包:腾讯服务器传过来的数据是XML格式的传到你的业务 ...
- 微信公众平台深度开发JAVA版第一季 27.菜单3
把字符串转化成对象. {"access_token":"zTZFxLrhM1vHAjXmq1ymk1JT8nlOKja4urFIr9PWqLYvFH9ZbWo8R6BmQ ...
最新文章
- 浅析py-faster-rcnn中不同版本caffe的安装及其对应不同版本cudnn的解决方案
- [云炬创业管理笔记]第一章讨论1
- Nginx rewrite使用
- 一个简单的 Generic Factory 类
- ajax实现环境,基于jQuery实现的Ajax(Django环境)
- 软考信息系统项目管理师2021_信息化与信息系统_项目管理阶段_方法_网络协议---软考高级之信息系统项目管理师003
- jsp action java_jsp中Action使用session方法实例分析
- [转载] 七龙珠第一部——第050话 海盗的陷阱
- Java基础---Java---面试题---交通灯管理系统(面向对象、枚举)
- 拓端tecdat|R语言代写岭回归ridge regression分析租房价格报告
- 读书笔记:《把时间当作朋友》
- 【题解】P3939数颜色
- 成都众恒微拓科技:怎么降低退款率
- 一文读懂 非root用户正确编译安装 protobuf —— 附 CMakeLists.txt 配置
- 高德地图的基础使用(一)显示地图
- 安信可LoRaWAN网关 RG-02 接入TTN平台,控制多节点LoRaWAN模组。
- 500G 史上最全的JAVA全套视频教程网盘
- 为什么有些大公司技术却弱爆了?
- 如何解决“bits/stdc++.h”:No such file or directory问题?
- 新手必读:三层交换技术基础知识详解
热门文章
- win10+tensorflow import cv2 bug解决
- unity 阳光插件_网络广告,阳光创信保驾护航
- Java注解的基本概念和原理及其简单实用
- IDEA 运行spingboot时出现Process finished with exit code -1073741819 (0xC0000005)
- Python(21)_input用户交互
- linux文件夹打包命令
- python try 异常处理 史上最全
- android软件获取系统签名
- 每日英语:Five Really Dumb Money Moves You've Got to Avoid
- python实现50行代码_50行Python代码,教你获取公众号全部文章