微信公共平台接口开发--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());
 }
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最大权闭合图hdu3996

定义&#xff1a;最大权闭合图&#xff1a;是有向图的一个点集&#xff0c;且该点集的所有出边都指向该集合。即闭合图内任意点的集合也在改闭合图内&#xff0c;给每个点分配一个点权值Pu&#xff0c;最大权闭合图就是使闭合图的点权之和最大。 最小割建边方式&#xff1a;源点…

非监督学习的单层网络分析

这篇博客对应的是Andrew.Ng的那篇文章&#xff1a;An Analysis o f Single-Layer Networks in Unsupervised Feature Learning&#xff0c;文章的主要目的是讨论receptive field size&#xff0c;number of hidden nodes&#xff0c; step-stride以及whitening在对卷积网络模型…

Spring MVC 验证码

页面 <% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <% String path request.getContextPath(); String basePath request.getScheme()"://"request.getServerName()":"request.getServerP…

数据结构实验之链表四:有序链表的归并

数据结构实验之链表四&#xff1a;有序链表的归并 Time Limit: 1000MS Memory limit: 65536K 题目描述 分别输入两个有序的整数序列&#xff08;分别包含M和N个数据&#xff09;&#xff0c;建立两个有序的单链表&#xff0c;将这两个有序单链表合并成为一个大的有序单链表&…

apk文件编译到系统文件中的方法(及包含so库的)

把第三方或自己开发的apk文件编译到系统文件(system.img)中的方法&#xff1a; 1 (1)源码编译后&#xff0c;把apk拷贝到out\target\product\generic\system\app中。 (2) 执行命令make snod , 把添加的spk编到system.img 中 缺点&#xff1a;执行make clean 后&#xff0c;再…

javascript中interval与setTimeOut的区别

setTimeout(code,millisec) //- 在指定时间后执行代码 code必须&#xff1b; millisec必须&#xff1b; clearTimeout(setTimeoutId) //- 取消 setTimeout() setInterval(code,millisec)&#xff1b;//指定间隔毫秒内循环执行代码 code必须&#xff1b; millisec必须&a…

java设计模式之单例模式(七种方法)

单例模式&#xff1a;个人认为这个是最简单的一种设计模式&#xff0c;而且也是在我们开发中最常用的一个设计模式。 单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例&#xff0c;而且自行实例化并向整个系统提供这个实例。这个类称为单例类。我们前面学习的…

java 遍历map集合

Map<String, String> map new HashMap<String, String>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); //第一种&#xff1a;通过Map.keySet遍…

poj3009 Curling 2.0 深搜

PS&#xff1a;以前看到题目这么长就没写下去了。今天做了半天&#xff0c;没做出来。准备看题解&#xff0c;打开了网站都忍住了&#xff0c;最后还是靠自己做出来的。算是一点进步吧。 分析&#xff1a; 题目的意思没明白或者理解有偏差都没办法做题。看样例3和样例4&#xf…

Android监听事件

ListView事件监听&#xff1a; setOnItemSelectedListener 鼠标滚动时触发 setOnItemClickListener 点击时触发 EditText事件监听&#xff1a; setOnKeyListener 获取焦点时触发 RadioGroup事件监听&#xff1a; setOnCheckedChangeListener 点击时触发 CheckBox事件监听&#…

子类能不能继承父类的构造方法?

class A{ public A(){} // 1:无参数构造方法。 public A(String s){} // 2.}class B extends A{ public B(String s){ super(s); // 3. }}说明&#xff1a;如果没有1处的无参数构造方法&#xff0c;那么3处一定要主动调用父类带参数的构造方法。如果有1处的构造方法&#…

基于原生javascript的ajax实现

function getXMLHttpRequest(){if(window.ActiveXObject){//用户是ie浏览器http_requestnew ActiveXObject("Microsoft.XMLHTTP");}else{//其他的浏览器http_requestnew XMLHttpRequest();}return http_request;}var httpRequest;function name(){httpRequestgetXMLH…

Google File System设计方面的问题汇总

1、Google File System概述 google file system是一个分布式文件系统&#xff0c;针对的是数据密集型应用&#xff0c;提供容错功能&#xff0c;运行在低廉的服务器上&#xff0c;同时给大量的用户提供高性能服务。尽管google file system有着传统的分布式文件系统的目标&#…

linux phpize

phpize是什么 1、phpize是用来扩展php扩展模块的&#xff0c;通过phpize可以建立php的外挂模块。 当php编译完后&#xff0c;在bin下面会有phpize这个脚本文件&#xff0c; 在编译你要添加的扩展模块之前&#xff0c;执行以下phpize就可以了&#xff1b; 比如现在想在php中加入…

一些常用的正则表达式

较验邮箱&#xff1a; var EmailReg /^[-_A-Za-z0-9]([_A-Za-z0-9]\.)[A-Za-z0-9]{2,3}$/; 身份证号码&#xff1a; var reg /(^\d{15}$)|(^\d{17}(\d|X)$)/; 15位身份证号 //身份证15位时&#xff0c;次序为省&#xff08;3位&#xff09;市&#xff08;3位&#xff…

iOS iphone屏幕分析(岂止而大)

在写本文前&#xff0c;我必须介绍几点内容&#xff1a;第一点&#xff1a;屏幕上面显示的内容多少和屏幕的尺寸大小无关第二点&#xff1a;屏幕上面显示的内容多少和分辨率完全无关第三点&#xff1a;屏幕上面显示的内容多少和屏幕尺寸、屏幕分辨率、PPI等都是无关的那到底什么…

js的一些实现

响应回车键提交表单 //*******************************************************响应回车键登录****************************************************************** document.οnkeydοwnfunction(event){ var e event || window.event || arguments…

【随笔】Win7下GVIM的安装与配置

针对各种语言的编辑器千千万万&#xff0c;最好的就是最适合自己的&#xff0c;这句话一点没错。 偶然间&#xff0c;需要在Windows上编写代码&#xff0c;MyEclipse等太大&#xff0c;完全没有必要&#xff0c;所以就想起来了vim这个神器。个子小&#xff0c;功能强&#xff0…

java遍历Set集合

在Java中使用Set,可以方便地将需要的类型&#xff0c;以集合类型保存在一个变量中.主要应用在显示列表. Set是一个不包含重复元素的collection。更确切地讲&#xff0c;set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2&#xff0c;并且最多包含一个 null 元素。 import java.u…

Java switch语句

在Java7之前&#xff0c;switch只能支持 byte、short、char、int或者其对应的封装类以及Enum类型。 Java7可以使用String作为判断条件 public class Test { public void test(String str) { switch(str) { case "abc": …