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实现相关推荐

  1. 微信公众号api关注接口php,微信公众平台接口开发入门示例

    本文实例讲述了微信公众平台接口开发入门示例.分享给大家供大家参考.具体如下: 微信公众平台的接口开发是一个现在比较常用的功能了,很多的人都会去了解一下微信公众平台一些简单开发应用,这里就来给大家介绍一 ...

  2. 微信公众平台接口开发基础

    微信接口开发的要点:公众号(订阅号.服务号).微信公众号提供的对应接口限制等.微信平台开发几乎涵盖了各行各业,小程序也让微信着实火了一把,时代在不断地发展,开发也在不断地切换自己的思维和平台.俗话说, ...

  3. 一周的微信公众平台接口开发总结

    2019独角兽企业重金招聘Python工程师标准>>> 在公司弄了一个星期的微信公众平台的接口开发,由于之前没弄过,开发的过程遇到了很多的小问题.下面我就总结一下我在开发过程中遇到了 ...

  4. 微信公众平台深度开发JAVA版第一季 30.菜单6

    {"button":[{ "type": "click", "name": "说明001", &qu ...

  5. 微信公众平台深度开发JAVA版第一季 15.响应被动消息3

    微信开发难度不大,但是逻辑关系很强. 这节课主要讲微信接口,至于在J2EE平台怎么把程序构造的更好不在这节课里面讨论. package net.wxinterface; import java.io. ...

  6. 微信公众平台深度开发JAVA版第一季 22.微信猜数字活动4

    select count(*) from huo t where t.shuzi='0' 这个SQL语句查不查询得到记录取决于两个条件:第一个是数据库里面有没有这个数字,第二个是getCountByS ...

  7. 微信公众平台深度开发JAVA版第一季 10.接收普通消息3

    获取到从腾讯服务器过来的字符串,业务服务器可以拼接出来可以打印出来.后续的工作是把这个字符串封装成一个Bean对象. <xml><ToUserName><![CDATA[ ...

  8. 微信公众平台深度开发JAVA版第一季 08.接收普通消息1

    上一节讲了开发的接口接入这一部分,这是非常重要的. 实现业务的逻辑应该写在POST方法这一块. GET是消息验证用的,验证接口那一块的. XML数据包:腾讯服务器传过来的数据是XML格式的传到你的业务 ...

  9. 微信公众平台深度开发JAVA版第一季 27.菜单3

    把字符串转化成对象. {"access_token":"zTZFxLrhM1vHAjXmq1ymk1JT8nlOKja4urFIr9PWqLYvFH9ZbWo8R6BmQ ...

最新文章

  1. 浅析py-faster-rcnn中不同版本caffe的安装及其对应不同版本cudnn的解决方案
  2. [云炬创业管理笔记]第一章讨论1
  3. Nginx rewrite使用
  4. 一个简单的 Generic Factory 类
  5. ajax实现环境,基于jQuery实现的Ajax(Django环境)
  6. 软考信息系统项目管理师2021_信息化与信息系统_项目管理阶段_方法_网络协议---软考高级之信息系统项目管理师003
  7. jsp action java_jsp中Action使用session方法实例分析
  8. [转载] 七龙珠第一部——第050话 海盗的陷阱
  9. Java基础---Java---面试题---交通灯管理系统(面向对象、枚举)
  10. 拓端tecdat|R语言代写岭回归ridge regression分析租房价格报告
  11. 读书笔记:《把时间当作朋友》
  12. 【题解】P3939数颜色
  13. 成都众恒微拓科技:怎么降低退款率
  14. 一文读懂 非root用户正确编译安装 protobuf —— 附 CMakeLists.txt 配置
  15. 高德地图的基础使用(一)显示地图
  16. 安信可LoRaWAN网关 RG-02 接入TTN平台,控制多节点LoRaWAN模组。
  17. 500G 史上最全的JAVA全套视频教程网盘
  18. 为什么有些大公司技术却弱爆了?
  19. 如何解决“bits/stdc++.h”:No such file or directory问题?
  20. 新手必读:三层交换技术基础知识详解

热门文章

  1. win10+tensorflow import cv2 bug解决
  2. unity 阳光插件_网络广告,阳光创信保驾护航
  3. Java注解的基本概念和原理及其简单实用
  4. IDEA 运行spingboot时出现Process finished with exit code -1073741819 (0xC0000005)
  5. Python(21)_input用户交互
  6. linux文件夹打包命令
  7. python try 异常处理 史上最全
  8. android软件获取系统签名
  9. 每日英语:Five Really Dumb Money Moves You've Got to Avoid
  10. python实现50行代码_50行Python代码,教你获取公众号全部文章