微信公共平台接口开发--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实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring mvc学习(5):IDEA
- 下一篇: 0-1背包问题-c语言实现