java连接微信服务器调用微信接口

一、注册微信公众平台

微信公众平台官网 https://mp.weixin.qq.com/,点击注册

java连接微信服务器调用微信接口_第1张图片

选择订阅号本文章只介绍个人账号,公司账号没试过,下次试了再发),之后注册部分不一一赘述。实在不会,网上可以搜到注册教程,完成注册。

二、登录微信公众平台(个人账号)

        如果对公众号没特别要求直接操作公众平台就可以了,这里主要介绍java后台开发者调用微信接口的操作。

由于个人号不能操作模板,我们这里选择 “开发“->“开发者工具”->“公众平台测试账号”,点击进入

java连接微信服务器调用微信接口_第2张图片

进入页面记住自己的appID和appsecret(很重要)

三、接口配置与接入

         java连接微信服务器调用微信接口_第3张图片

下面配置接口信息,这里我的理解是将我们的程序与微信服务器连接起来,让我的程序成为开发者方便开发。

下面进入eclipse编写java程序

我用的是maven项目来管理的

首先:

1、pom.xml


        UTF-8
        UTF-8
        4.3.3.RELEASE
        2.5.0
        1.8
    

    

        
            com.alibaba
            fastjson
            1.2.47
        


        
            net.sf.json-lib
            json-lib
            2.4
            jdk15
        

        
            org.dom4j
            dom4j
            2.1.0
        


        
            com.thoughtworks.xstream
            xstream
            1.4.9
        

        
            xstream
            xstream
            1.2.2
        

        
            javax.xml.stream
            stax-api
            1.0-2
        


        
        
            commons-collections
            commons-collections
            3.2.1
        

        
            io.springfox
            springfox-swagger-ui
            2.6.1
        

        
        
            org.springframework
            spring-core
            ${spring.version}
        

        
            org.springframework
            spring-beans
            ${spring.version}
        

        
            org.springframework
            spring-context
            ${spring.version}
        

        
            org.springframework
            spring-tx
            ${spring.version}
        

        
            org.springframework
            spring-web
            ${spring.version}
        

        
            org.springframework
            spring-webmvc
            ${spring.version}
        

        
            org.springframework
            spring-jdbc
            ${spring.version}
        

        
            org.springframework
            spring-test
            ${spring.version}
            test
        

        
        
            org.mybatis
            mybatis
            3.2.8
        

        
        
            org.mybatis
            mybatis-spring
            1.2.2
        

        

        
        
            mysql
            mysql-connector-java
            5.1.39
        

        
        
            commons-dbcp
            commons-dbcp
            1.4
        

        
        
            commons-pool
            commons-pool
            1.6
        

        
        
            log4j
            log4j
            1.2.17
        

        
        
            javax.servlet
            jstl
            1.2
        

        
            junit
            junit
            4.12
            test
        

        

        
        
            javax.xml.ws
            jaxws-api
            2.1
        

        
        
            javax.xml.bind
            jaxb-api
            2.1
        

        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        

        
            commons-lang
            commons-lang
            2.6
        


    

    

        
            
                org.apache.maven.plugins
                maven-war-plugin
                2.6
                
                    false
                

            

        

        

            
                src/main/resources
                
                    **/*.properties
                    **/*.xml
                

                true
            

            
                src/main/java
                
                    **/*.properties
                    **/*.xml
                

                true
            

        

    


2、controller层

package com.dajingzhu.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

//工具类在后面我会发出来

import com.alibaba.fastjson.JSONArray;
import com.dajingzhu.bean.SHA1;
import com.dajingzhu.bean.Template;
import com.dajingzhu.bean.TemplateParam;
import com.dajingzhu.service.WechatService;
import com.dajingzhu.utils.CommonUtil;
import com.dajingzhu.utils.WeChatUtil;
import com.dajingzhu.utils.WeixinUtil;

import net.sf.json.JSONObject;

@Controller

//这个和之后要设置的url息息相关
@RequestMapping(value="/wx")

public class WeChatController {

        private    static int i=0;

       //这里的token与之前说的接口配置的token要相同(注意,这个token与之后的accesstoken是不同的

       private String Token = "fjjjkl";  
      //主方法,接口配置的url也是定位到这个方法的
        @RequestMapping(value = "/chat", method = { RequestMethod.GET, RequestMethod.POST })  
        @ResponseBody  
        public void liaotian( PrintWriter out,HttpServletRequest request, HttpServletResponse response) throws IOException {  

           //设置输入编码格式
            request.setCharacterEncoding("UTF-8");

          //设置输出编码格式 
            response.setCharacterEncoding("UTF-8"); 
            System.out.println("进入chat");  

           //判断输入是否是get请求方式,个人理解:如果是get请求,说明在配置上图接口配置的请求是get方式,其他的不是get方式
            boolean isGet = request.getMethod().toLowerCase().equals("get");  
            if (isGet) {  

               //如果是get请求得到微信加密签名等属性进行字典排序,access方法在下面
                String signature = request.getParameter("signature");  
                String timestamp = request.getParameter("timestamp");  
                String nonce = request.getParameter("nonce");  
                String echostr = request.getParameter("echostr");  
                System.out.println(signature);  
                System.out.println(timestamp);  
                System.out.println(nonce);  
                System.out.println(echostr);  
                access(request, response);  
            } else {  
                // 进入POST聊天处理  
                i++;
                System.out.println("enter post");  
  /*         try {  
                    // 接收消息并返回消息 
               acceptMessage(request, response);  
                     } catch (IOException e) {  
                    e.printStackTrace();  
                }  */
                if(request!=null) {

               //如果请求头不为空,返回消息
               WechatService ws= new WechatService();
               String processRequest = ws.processRequest(request);
               response.getWriter().write(processRequest);
               processRequest=new String(processRequest.getBytes(), "Utf-8");
               out.write(processRequest);  
               System.out.println("==============");
                }

                //i为计数,每次发送消息返回模板消息,五次之后不返回(为保障程序的纯洁性,这是单独的发送模板消息,之后我集成到其他程序上去了,如果逻辑啥的走不通不要惊讶,找找原因,这已经是大半完成品了),都在同一个页面,要理解微信的工作方式

java连接微信服务器调用微信接口_第4张图片
                if(i<5) {

                      //根据AppID和appsecret生成accesstoken;
                      String access_token=WeixinUtil.getAccessToken("让你记住的appid","让你记住的appsecret");
                    System.out.println(access_token);

                     //根据从工具类得到的accesstoken得到所有关注本公众号的用户数组
                    JSONArray openIdArray = WeChatUtil.getOpenIds(access_token);
                    //每个用户循环发送
                    for (Object openId : openIdArray) {
                          System.out.println(openId.toString());

                          //模板实体类
                         Template tem=new Template();  

                          //模板id
                          tem.setTemplateId("模板id");  】

                          //模板背景色
                          tem.setTopColor("#00DD00");  

                           //要发送的用户的openid
                          tem.setToUser(openId.toString());  

                           //点击模板可以跳转的url
                          tem.setUrl("");  
                           //向模板id插入东西,可以是从另一个方法传来的对象哦,那样就可以实现模板的实时变动

里面的first等字段都是和市直模板内容对应的,微信模板不知道怎么创建百度一下就好了,当时我写程序可都是面向百度编程
                          List paras=new ArrayList();  
                          paras.add(new TemplateParam("first","我们已收到您的货款,开始为您打包商品,请耐心等待: )","#FF3333"));  
                          paras.add(new TemplateParam("keyword1","¥20.00","#0044BB"));  
                          paras.add(new TemplateParam("keyword2","火烧牛干巴","#0044BB"));  
                        //  paras.add(new TemplateParam("alarm_type","火烧牛干巴","#0044BB"));  
                          paras.add(new TemplateParam("keyword3","火烧牛干巴","#0044BB"));  
                          paras.add(new TemplateParam("remark","感谢你对我们商城的支持!!!!","#AAAAAA"));  
                          //利用方法发送模板
                          tem.setTemplateParamList(paras);  
                           //System.out.println(tem);

                           //查看返回结果,返回的是状态码和json数据,状态码各代表不同意思,200是成功
                          boolean result=sendTemplateMsg(access_token,tem); 
                          System.out.println(result);
                            }
                    }
     
            }  
}

       //进行微信字典排序加密,防止数据泄露
        private String access(HttpServletRequest request, HttpServletResponse response) {  
            // 验证URL真实性  
            System.out.println("进入验证access");  
            String signature = request.getParameter("signature");// 微信加密签名  
            String timestamp = request.getParameter("timestamp");// 时间戳  
            String nonce = request.getParameter("nonce");// 随机数  
            String echostr = request.getParameter("echostr");// 随机字符串  
            List params = new ArrayList();  
            params.add(Token);  
            params.add(timestamp);  
            params.add(nonce);  
            // 1. 将token、timestamp、nonce三个参数进行字典序排序  
            Collections.sort(params, new Comparator() {  
                @Override  
                public int compare(String o1, String o2) {  
                    return o1.compareTo(o2);  
                }   
            });  
            // 2. 将三个参数字符串拼接成一个字符串进行sha1加密  
            String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));  
            if (temp.equals(signature)) {  
                try {  
                    response.getWriter().write(echostr);  
                    System.out.println("成功返回 echostr:" + echostr);  
                    return echostr;  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
            System.out.println("失败 认证");  
            return null;  
        }  
      

       //发送模板消息的方法
       public static boolean sendTemplateMsg(String token,Template template){  
            boolean flag=false;                
            String requestUrl="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";  
            requestUrl=requestUrl.replace("ACCESS_TOKEN", token);  
            JSONObject jsonResult=CommonUtil.httpsRequest(requestUrl, "POST", template.toJSON());  
            System.out.println(jsonResult);
            if(jsonResult!=null){  
                System.out.println(jsonResult);
                int errorCode=jsonResult.getInt("errcode");  
                String errorMessage=jsonResult.getString("errmsg");  
                if(errorCode==0){  
                    flag=true;  
                }else{  
                    System.out.println("模板消息发送失败:"+errorCode+","+errorMessage);  
                    flag=false;  
                }  
            }  
            return flag;  
    }  
}

(这里用了大量的工具类,我也是从网上找的,有的重复,有的有错 ,自求多福吧)

3、service层

package com.dajingzhu.service;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.dajingzhu.bean.TextMessage;
import com.dajingzhu.utils.WechatMessageUtil;

public class WechatService {


     public String processRequest(HttpServletRequest request) {
            Map map = WechatMessageUtil.xmlToMap(request);
            // 发送方帐号(一个OpenID)
            String fromUserName = map.get("FromUserName");
            // 开发者微信号
            String toUserName = map.get("ToUserName");
            // 消息类型
            String msgType = map.get("MsgType");
            // 默认回复一个"success"
            String responseMessage = "success";
            // 对消息进行处理
            if (WechatMessageUtil.MESSAGE_TEXT.equals(msgType)) {// 文本消息
                System.out.println("传来的是text");
                TextMessage textMessage = new TextMessage();
                textMessage.setMsgType(WechatMessageUtil.MESSAGE_TEXT);
                textMessage.setToUserName(fromUserName);
                textMessage.setFromUserName(toUserName);
                textMessage.setCreateTime(System.currentTimeMillis());
                textMessage.setContent("我已经受到你发来的消息了");
                System.out.println(textMessage);
                responseMessage = WechatMessageUtil.textMessageToXml(textMessage);
                System.out.println(responseMessage);
            }
            return responseMessage;
          
     
              
        }
           
      public void sendemplate() {
          
        }

     

}
4、工具类

(1)CommonUtil

package com.dajingzhu.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;


import com.dajingzhu.bean.Token;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;


/*
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;*/
/**
* 类名: CommonUtil

* 描述: 通用工具类

* 开发人员: souvc

* 创建时间:  2015-9-30

* 发布版本:V1.0  

 */
public class CommonUtil {
    //private static Logger log = LoggerFactory.makeNewLoggerInstance(CommonUtil.class);

    // 凭证获取(GET)
    public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";


    /**
     * 发送https请求
     * 
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式(GET、POST)
     * @param outputStr 提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        try {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            conn.setRequestMethod(requestMethod);

            // 当outputStr不为null时向输出流写数据
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 从输入流读取返回内容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            //log.error("连接超时:{}", ce);
            ce.printStackTrace();
        } catch (Exception e) {
          ///  log.error("https请求异常:{}", e);
            e.printStackTrace();
        }
        return jsonObject;
    }

    /**
     * 获取接口访问凭证
     * 
     * @param appid 凭证
     * @param appsecret 密钥
     * @return
     */
    public static Token getToken(String appid, String appsecret) {
        Token token = null;
        String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
        // 发起GET请求获取凭证
        JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);

        if (null != jsonObject) {
            try {
                token = new Token();
                token.setAccessToken(jsonObject.getString("access_token"));
                token.setExpiresIn(jsonObject.getInt("expires_in"));
            } catch (JSONException e) {
                token = null;
                // 获取token失败
               // log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
                e.printPartialStackTrace(null);
            }
        }
        return token;
    }

}

(2)HttpUtil

package com.dajingzhu.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class HttpUtil {
    /*
     * https请求
     * requestUrl:请求地址
     * requestMethod:GET / POST
     * outputStr:POST请求数据,GET请传NULL
     */
       public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        StringBuffer buffer = new StringBuffer();
        try {

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式,防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            return buffer.toString();
        } catch (ConnectException ce) {
            ce.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
       
    /*
     * http请求
     * requestUrl:请求地址
     * requestMethod:GET / POST
     * outputStr:POST请求数据,GET请传NULL
     */
       public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
        StringBuffer buffer = new StringBuffer();
        try {

            URL url = new URL(requestUrl);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();


            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式,防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            return buffer.toString();
        } catch (ConnectException ce) {
            ce.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
       /*
        * http请求
        * requestUrl:请求地址
        */
    public static String httpRequest(String requestUrl) {
        InputStream inputStream = null;
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
            httpUrlConn.setDoInput(true);
            httpUrlConn.setRequestMethod("GET");
            httpUrlConn.connect();
            // 获得返回的输入流
            inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    
    /*
     * url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,
     * 
        URL字符转义
        用其它字符替代吧,或用全角的。
        +    URL 中+号表示空格                                 %2B   
        空格 URL中的空格可以用+号或者编码           %20 
        /   分隔目录和子目录                                     %2F     
        ?    分隔实际的URL和参数                             %3F     
        %    指定特殊字符                                          %25     
        #    表示书签                                                  %23     
        &    URL 中指定的参数间的分隔符                  %26     
        =    URL 中指定参数的值                                %3D
     */
    public static String httpParameterFilter(String param){
        String    s    =    "";  
        if    (param.length()    ==    0)    return    "";  
        s    =    param.replaceAll("+",    "%2B");
        s    =    s.replaceAll(" ",        "%20");
        s    =    s.replaceAll("/",        "%2F");  
        s    =    s.replaceAll("?",        "%3F");  
        s    =    s.replaceAll("%'",      "%25");
        s    =    s.replaceAll("#'",      "%23");
        s    =    s.replaceAll("&'",      "%26");
        s    =    s.replaceAll("=",      "%3D");  
        return    s;  
    }
}


(3)MyX509TrustManager

package com.dajingzhu.utils;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;

/**
* 类名: MyX509TrustManager

* 描述: 信任管理器

* 开发人员: fj

* 创建时间:  2018-6-12

* 发布版本:V1.0  

 */
public class MyX509TrustManager implements X509TrustManager {

    // 检查客户端证书
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    // 检查服务器端证书
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    // 返回受信任的X509证书数组
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

(5)SerializeXmlUtil

package com.dajingzhu.utils;

import java.io.Writer;  
import java.lang.reflect.Field;

import com.dajingzhu.bean.XStreamCDATA;
import com.thoughtworks.xstream.XStream;  
import com.thoughtworks.xstream.annotations.XStreamAlias;  
import com.thoughtworks.xstream.core.util.QuickWriter;  
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;  
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;  
import com.thoughtworks.xstream.io.xml.XppDriver;  
  
/** 
 * xml 转换工具类 
 *  
 * @author morning 
 * @date 2015年2月16日 下午2:42:50 
 */  
public class SerializeXmlUtil {  
  
    public static XStream createXstream() {  
        return new XStream(new XppDriver() {  
            @Override  
            public HierarchicalStreamWriter createWriter(Writer out) {  
                return new PrettyPrintWriter(out) {  
                    boolean cdata = false;  
                    Class targetClass = null;  
  
                    @Override  
                    public void startNode(String name, @SuppressWarnings("rawtypes") Class clazz) {  
                        super.startNode(name, clazz);  
                        // 业务处理,对于用XStreamCDATA标记的Field,需要加上CDATA标签  
                        if (!name.equals("xml")) {  
                            cdata = needCDATA(targetClass, name);  
                        } else {  
                            targetClass = clazz;  
                        }  
                    }  
  
                    @Override  
                    protected void writeText(QuickWriter writer, String text) {  
                        if (cdata) {  
                            writer.write("                             writer.write(text);  
                            writer.write("]]>");  
                        } else {  
                            writer.write(text);  
                        }  
                    }  
                };  
            }  
        });  
    }  
  
    private static boolean needCDATA(Class targetClass, String fieldAlias) {  
        boolean cdata = false;  
        // first, scan self  
        cdata = existsCDATA(targetClass, fieldAlias);  
        if (cdata)  
            return cdata;  
        // if cdata is false, scan supperClass until java.lang.Object  
        Class superClass = targetClass.getSuperclass();  
        while (!superClass.equals(Object.class)) {  
            cdata = existsCDATA(superClass, fieldAlias);  
            if (cdata)  
                return cdata;  
            superClass = superClass.getClass().getSuperclass();  
        }  
        return false;  
    }  
  
    private static boolean existsCDATA(Class clazz, String fieldAlias) {  
        if ("MediaId".equals(fieldAlias)) {  
            return true; // 特例添加 morning99  
        }  
        // scan fields  
        Field[] fields = clazz.getDeclaredFields();  
        for (Field field : fields) {  
            // 1. exists XStreamCDATA  
            if (field.getAnnotation(XStreamCDATA.class) != null) {  
                XStreamAlias xStreamAlias = field.getAnnotation(XStreamAlias.class);  
                // 2. exists XStreamAlias  
                if (null != xStreamAlias) {  
                    if (fieldAlias.equals(xStreamAlias.value()))// matched  
                        return true;  
                } else {// not exists XStreamAlias  
                    if (fieldAlias.equals(field.getName()))  
                        return true;  
                }  
            }  
        }  
        return false;  
    }  
  
}  

(6)WeChatUtil

package com.dajingzhu.utils;

import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dajingzhu.bean.WeChatContext;


/**
 * 微信工具
 * @Author wuwz
 * @TypeName WeChatUtil
 */
@SuppressWarnings("unchecked")
public abstract class WeChatUtil {
    
    // access_token有效毫秒记录数
    public static long ACCESS_TOKEN_TIME = 0;
    
    // jsapi_ticket有效毫秒记录数
    public static long JSAPI_TICKET_TIME = 0;
    
    // jsapi_ticket有效毫秒记录数
    public static Map tempData = new HashMap();
    
    // 微信配置上下文
        public static WeChatContext context = WeChatContext.getInstance();    

    
    // 获取关注用户
    public static JSONObject getUsersJSON(String token) {
        
        try {
            
            //请求接口地址
            String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN";
            
            //请求参数
            requestUrl=requestUrl.replace("ACCESS_TOKEN", token);  
            
            //发起请求
            String result = HttpUtil.httpRequest(requestUrl, "GET", requestUrl);
            
            if(result != null && !"".equals(result)) {
                return JSON.parseObject(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null;
    }
    
    // 获取关注用户的OpenIds
    public static JSONArray getOpenIds(String token) {
        try {
            JSONObject usersJsonObj = getUsersJSON(token);
            
            return (usersJsonObj.getJSONObject("data")).getJSONArray("openid");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}


(7)WechatMessageUtil

package com.dajingzhu.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.dajingzhu.bean.TextMessage;
import com.thoughtworks.xstream.XStream;

public class WechatMessageUtil {
    // 各种消息类型,除了扫带二维码事件
    /**
     * 文本消息
     */
    public static final String MESSAGE_TEXT = "text";
    /**
     * 图片消息
     */
    public static final String MESSAtGE_IMAGE = "image";
    /**
     * 图文消息
     */
    public static final String MESSAGE_NEWS = "news";
    /**
     * 语音消息
     */
    public static final String MESSAGE_VOICE = "voice";
    /**
     * 视频消息
     */
    public static final String MESSAGE_VIDEO = "video";
    /**
     * 小视频消息
     */
    public static final String MESSAGE_SHORTVIDEO = "shortvideo";
    /**
     * 地理位置消息
     */
    public static final String MESSAGE_LOCATION = "location";
    /**
     * 链接消息
     */
    public static final String MESSAGE_LINK = "link";
    /**
     * 事件推送消息
     */
    public static final String MESSAGE_EVENT = "event";
    /**
     * 事件推送消息中,事件类型,subscribe(订阅)
     */
    public static final String MESSAGE_EVENT_SUBSCRIBE = "subscribe";
    /**
     * 事件推送消息中,事件类型,unsubscribe(取消订阅)
     */
    public static final String MESSAGE_EVENT_UNSUBSCRIBE = "unsubscribe";
    /**
     * 事件推送消息中,上报地理位置事件
     */
    public static final String MESSAGE_EVENT_LOCATION_UP = "LOCATION";
    /**
     * 事件推送消息中,自定义菜单事件,点击菜单拉取消息时的事件推送
     */
    public static final String MESSAGE_EVENT_CLICK = "CLICK";
    /**
     * 事件推送消息中,自定义菜单事件,点击菜单跳转链接时的事件推送
     */
    public static final String MESSAGE_EVENT_VIEW = "VIEW";

    /**
     * 将xml转化为Map集合
     * 
     * @param request
     * @return
     */
    public static Map xmlToMap(HttpServletRequest request) {
        Map map = new HashMap();
        SAXReader reader = new SAXReader();
        InputStream ins = null;
        try {
            ins = request.getInputStream();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        Document doc = null;
        try {
            doc = reader.read(ins);
        } catch (DocumentException e1) {
            e1.printStackTrace();
        }
        Element root = doc.getRootElement();
        @SuppressWarnings("unchecked")
        List list = root.elements();
        for (Element e : list) {
            map.put(e.getName(), e.getText());
        }
        try {
            ins.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return map;
    }

    /**
     * 文本消息转化为xml
     * 
     * @param textMessage
     * @return
     */
    public static String textMessageToXml(TextMessage textMessage) {
        XStream xstream = new XStream();
        xstream.alias("xml", textMessage.getClass());
        return xstream.toXML(textMessage);

    }

}
 

(8)WexinUtil

package com.dajingzhu.utils;
import java.io.BufferedReader;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.io.OutputStream;  
import java.net.ConnectException;  
import java.net.URL;  
import javax.net.ssl.HttpsURLConnection;  
import javax.net.ssl.SSLContext;  
import javax.net.ssl.SSLSocketFactory;  
import javax.net.ssl.TrustManager;  
import net.sf.json.JSONException;  
import net.sf.json.JSONObject;  
  
/** 
 * 公众平台通用接口工具类 
 */  
public class WeixinUtil {  
      
    /** 
     * 发起https请求并获取结果 
     *  
     * @param requestUrl 请求地址 
     * @param requestMethod 请求方式(GET、POST) 
     * @param outputStr 提交的数据 
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) 
     */  
    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {  
        JSONObject jsonObject = null;  
        StringBuffer buffer = new StringBuffer();  
        try {  
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化  
            TrustManager[] tm = { new MyX509TrustManager() };  
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");  
            sslContext.init(null, tm, new java.security.SecureRandom());  
            // 从上述SSLContext对象中得到SSLSocketFactory对象  
            SSLSocketFactory ssf = sslContext.getSocketFactory();  
  
            URL url = new URL(requestUrl);  
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();  
            httpUrlConn.setSSLSocketFactory(ssf);  
  
            httpUrlConn.setDoOutput(true);  
            httpUrlConn.setDoInput(true);  
            httpUrlConn.setUseCaches(false);  
            // 设置请求方式(GET/POST)  
            httpUrlConn.setRequestMethod(requestMethod);  
  
            if ("GET".equalsIgnoreCase(requestMethod))  
                httpUrlConn.connect();  
  
            // 当有数据需要提交时  
            if (null != outputStr) {  
                OutputStream outputStream = httpUrlConn.getOutputStream();  
                // 注意编码格式,防止中文乱码  
                outputStream.write(outputStr.getBytes("UTF-8"));  
                outputStream.close();  
            }  
  
            // 将返回的输入流转换成字符串  
            InputStream inputStream = httpUrlConn.getInputStream();  
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
  
            String str = null;  
            while ((str = bufferedReader.readLine()) != null) {  
                buffer.append(str);  
            }  
            bufferedReader.close();  
            inputStreamReader.close();  
            // 释放资源  
            inputStream.close();  
            inputStream = null;  
            httpUrlConn.disconnect();  
            jsonObject = JSONObject.fromObject(buffer.toString());  
        } catch (ConnectException ce) {  
            ce.printStackTrace();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return jsonObject;  
    }  
  
    /** 
     * 获取access_token 
     *  
     * @param appid 凭证 
     * @param appsecret 密钥 
     * @return 
     */  
    public static String getAccessToken(String appid, String appsecret) {  
        // 获取公众号access_token的链接  
        String access_token = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";  
  
        String requestUrl = access_token.replace("APPID", appid).replace("APPSECRET", appsecret);  
          
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  
          
        // 如果请求成功  
        if (null != jsonObject) {  
            try {  
                return jsonObject.getString("access_token");  
            } catch (JSONException e) {  
            }  
        }  
        return null;  
    }  
  
    /** 
     * 获取jsapi_ticket 
     *  
     * @param appid 凭证 
     * @param appsecret 密钥 
     * @return 
     */  
    public static String getJsapiTicket(String accessToken) {  
        // 获取公众号jsapi_ticket的链接  
        String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";  
        if (accessToken != null) {  
            String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN", accessToken);  
            // String requestUrl = access_token_url.replace("APPID",  
            // appid).replace("APPSECRET", appsecret);  
            JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  
            // 如果请求成功  
            if (null != jsonObject) {  
                try {  
                    return jsonObject.getString("ticket");  
                } catch (JSONException e) {  
                }  
            }  
        } else {  
            System.out.println("*****token为空 获取ticket失败******");  
        }  
  
        return null;  
    }  
}  

5、实体类

(1)BaseWechatMessage

package com.dajingzhu.bean;

/**
 * @author gaowei.cheng
 * 2016年1月19日
 * 微信消息基类
 */
public class BaseWechatMessage {
    /**
     * 开发者微信号
     */
    private String ToUserName;
    /**
     * 发送方帐号(一个OpenID)
     */
    private String FromUserName;
    /**
     * 消息创建时间 (整型)
     */
    private long CreateTime;
    /**
     * 消息类型
     */
    private String MsgType;
    /**
     * 消息id,64位整型
     */
    private String MsgId;
    public String getToUserName() {
        return ToUserName;
    }
    public void setToUserName(String toUserName) {
        ToUserName = toUserName;
    }
    public String getFromUserName() {
        return FromUserName;
    }
    public void setFromUserName(String fromUserName) {
        FromUserName = fromUserName;
    }
    public long getCreateTime() {
        return CreateTime;
    }
    public void setCreateTime(long createTime) {
        CreateTime = createTime;
    }
    public String getMsgType() {
        return MsgType;
    }
    public void setMsgType(String msgType) {
        MsgType = msgType;
    }
    public String getMsgId() {
        return MsgId;
    }
    public void setMsgId(String msgId) {
        MsgId = msgId;
    }
    
}


(2)SHA1

package com.dajingzhu.bean;

import java.security.MessageDigest;

public final class SHA1 {  
      
    private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };  
  
    /** 
     * Takes the raw bytes from the digest and formats them correct. 
     *  
     * @param bytes 
     *            the raw bytes from the digest. 
     * @return the formatted bytes. 
     */  
    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();  
    }  
  
    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);  
        }  
    }  
}  

(3)InputMessage

package com.dajingzhu.bean;

import java.io.Serializable;  

import com.thoughtworks.xstream.annotations.XStreamAlias;  
  
/** 
 * POST的XML数据包转换为消息接受对象 
 *  
 *

 
 * 由于POST的是XML数据包,所以不确定为哪种接受消息,
 
 * 所以直接将所有字段都进行转换,最后根据MsgType字段来判断取何种数据 
 *

 
 *  
 */  
@XStreamAlias("xml")  
public class InputMessage implements Serializable {  
  
    /** 
     *  
     */  
    private static final long serialVersionUID = 1L;  
    @XStreamAlias("ToUserName")  
    private String ToUserName;  
    @XStreamAlias("FromUserName")  
    private String FromUserName;  
    @XStreamAlias("CreateTime")  
    private Long CreateTime;  
    @XStreamAlias("MsgType")  
    private String MsgType = "text";  
    @XStreamAlias("MsgId")  
    private Long MsgId;  
    // 文本消息  
    @XStreamAlias("Content")  
    private String Content;  
    // 图片消息  
    @XStreamAlias("PicUrl")  
    private String PicUrl;  
    // 位置消息  
    @XStreamAlias("LocationX")  
    private String LocationX;  
    @XStreamAlias("LocationY")  
    private String LocationY;  
    @XStreamAlias("Scale")  
    private Long Scale;  
    @XStreamAlias("Label")  
    private String Label;  
    // 链接消息  
    @XStreamAlias("Title")  
    private String Title;  
    @XStreamAlias("Description")  
    private String Description;  
    @XStreamAlias("Url")  
    private String URL;  
    // 语音信息  
    @XStreamAlias("MediaId")  
    private String MediaId;  
    @XStreamAlias("Format")  
    private String Format;  
    @XStreamAlias("Recognition")  
    private String Recognition;  
    // 事件  
    @XStreamAlias("Event")  
    private String Event;  
    @XStreamAlias("EventKey")  
    private String EventKey;  
    @XStreamAlias("Ticket")  
    private String Ticket;  
  
    public String getToUserName() {  
        return ToUserName;  
    }  
  
    public void setToUserName(String toUserName) {  
        ToUserName = toUserName;  
    }  
  
    public String getFromUserName() {  
        return FromUserName;  
    }  
  
    public void setFromUserName(String fromUserName) {  
        FromUserName = fromUserName;  
    }  
  
    public Long getCreateTime() {  
        return CreateTime;  
    }  
  
    public void setCreateTime(Long createTime) {  
        CreateTime = createTime;  
    }  
  
    public String getMsgType() {  
        return MsgType;  
    }  
  
    public void setMsgType(String msgType) {  
        MsgType = msgType;  
    }  
  
    public Long getMsgId() {  
        return MsgId;  
    }  
  
    public void setMsgId(Long msgId) {  
        MsgId = msgId;  
    }  
  
    public String getContent() {  
        return Content;  
    }  
  
    public void setContent(String content) {  
        Content = content;  
    }  
  
    public String getPicUrl() {  
        return PicUrl;  
    }  
  
    public void setPicUrl(String picUrl) {  
        PicUrl = picUrl;  
    }  
  
    public String getLocationX() {  
        return LocationX;  
    }  
  
    public void setLocationX(String locationX) {  
        LocationX = locationX;  
    }  
  
    public String getLocationY() {  
        return LocationY;  
    }  
  
    public void setLocationY(String locationY) {  
        LocationY = locationY;  
    }  
  
    public Long getScale() {  
        return Scale;  
    }  
  
    public void setScale(Long scale) {  
        Scale = scale;  
    }  
  
    public String getLabel() {  
        return Label;  
    }  
  
    public void setLabel(String label) {  
        Label = label;  
    }  
  
    public String getTitle() {  
        return Title;  
    }  
  
    public void setTitle(String title) {  
        Title = title;  
    }  
  
    public String getDescription() {  
        return Description;  
    }  
  
    public void setDescription(String description) {  
        Description = description;  
    }  
  
    public String getURL() {  
        return URL;  
    }  
  
    public void setURL(String uRL) {  
        URL = uRL;  
    }  
  
    public String getEvent() {  
        return Event;  
    }  
  
    public void setEvent(String event) {  
        Event = event;  
    }  
  
    public String getEventKey() {  
        return EventKey;  
    }  
  
    public void setEventKey(String eventKey) {  
        EventKey = eventKey;  
    }  
  
    public String getMediaId() {  
        return MediaId;  
    }  
  
    public void setMediaId(String mediaId) {  
        MediaId = mediaId;  
    }  
  
    public String getFormat() {  
        return Format;  
    }  
  
    public void setFormat(String format) {  
        Format = format;  
    }  
  
    public String getRecognition() {  
        return Recognition;  
    }  
  
    public void setRecognition(String recognition) {  
        Recognition = recognition;  
    }  
  
    public String getTicket() {  
        return Ticket;  
    }  
  
    public void setTicket(String ticket) {  
        Ticket = ticket;  
    }  
}  

(4)MediaIdMessage

package com.dajingzhu.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;  

public class MediaIdMessage {  
    @XStreamAlias("MediaId")  
    @XStreamCDATA  
    private String MediaId;  
  
    public String getMediaId() {  
        return MediaId;  
    }  
  
    public void setMediaId(String mediaId) {  
        MediaId = mediaId;  
    }  
  
}  

(5)OutputMessage

 

package com.dajingzhu.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;  

/** 
 *  
 * @author morning 
 * @date 2015年2月16日 下午2:29:32 
 */  
@XStreamAlias("xml")  
public class OutputMessage {  
  
    @XStreamAlias("ToUserName")  
    @XStreamCDATA  
    private String ToUserName;  
  
    @XStreamAlias("FromUserName")  
    @XStreamCDATA  
    private String FromUserName;  
  
    @XStreamAlias("CreateTime")  
    private Long CreateTime;  
  
    @XStreamAlias("MsgType")  
    @XStreamCDATA  
    private String MsgType = "text";  
  
    private ImageMessage Image;  
  
    public String getToUserName() {  
        return ToUserName;  
    }  
  
    public void setToUserName(String toUserName) {  
        ToUserName = toUserName;  
    }  
  
    public String getFromUserName() {  
        return FromUserName;  
    }  
  
    public void setFromUserName(String fromUserName) {  
        FromUserName = fromUserName;  
    }  
  
    public Long getCreateTime() {  
        return CreateTime;  
    }  
  
    public void setCreateTime(Long createTime) {  
        CreateTime = createTime;  
    }  
  
    public String getMsgType() {  
        return MsgType;  
    }  
  
    public void setMsgType(String msgType) {  
        MsgType = msgType;  
    }  
  
    public ImageMessage getImage() {  
        return Image;  
    }  
  
    public void setImage(ImageMessage image) {  
        Image = image;  
    }  
  
}  

(6)Template

package com.dajingzhu.bean;

import java.util.List;

public class Template {
     // 消息接收方  
    private String toUser;  
    // 模板id  
    private String templateId;  
    // 模板消息详情链接  
    private String url;  
    // 消息顶部的颜色  
    private String topColor;  
    // 参数列表  
    private List templateParamList;  
  
    public String getToUser() {  
        return toUser;  
    }  
  
    public void setToUser(String toUser) {  
        this.toUser = toUser;  
    }  
  
    public String getTemplateId() {  
        return templateId;  
    }  
  
    public void setTemplateId(String templateId) {  
        this.templateId = templateId;  
    }  
  
    public String getUrl() {  
        return url;  
    }  
  
    public void setUrl(String url) {  
        this.url = url;  
    }  
  
    public String getTopColor() {  
        return topColor;  
    }  
  
    public void setTopColor(String topColor) {  
        this.topColor = topColor;  
    }  
      
    public String toJSON() {  
        StringBuffer buffer = new StringBuffer();  
        buffer.append("{");  
        buffer.append(String.format("\"touser\":\"%s\"", this.toUser)).append(",");  
        buffer.append(String.format("\"template_id\":\"%s\"", this.templateId)).append(",");  
        buffer.append(String.format("\"url\":\"%s\"", this.url)).append(",");  
        buffer.append(String.format("\"topcolor\":\"%s\"", this.topColor)).append(",");  
        buffer.append("\"data\":{");  
        TemplateParam param = null;  
        for (int i = 0; i < this.templateParamList.size(); i++) {  
             param = templateParamList.get(i);  
            // 判断是否追加逗号  
            if (i < this.templateParamList.size() - 1){  
                  
                buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"},", param.getName(), param.getValue(), param.getColor()));  
            }else{  
                buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"}", param.getName(), param.getValue(), param.getColor()));  
            }  
          
        }  
        buffer.append("}");  
        buffer.append("}");  
        return buffer.toString();  
        }  
  
    public List getTemplateParamList() {  
        return templateParamList;  
    }  
  
    public void setTemplateParamList(List templateParamList) {  
        this.templateParamList = templateParamList;  
    }  
  
}

 

(7)token

package com.dajingzhu.bean;

public class Token {
    // 接口访问凭证
    private String accessToken;
    // 凭证有效期,单位:秒
    private int expiresIn;

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public int getExpiresIn() {
        return expiresIn;
    }

    public void setExpiresIn(int expiresIn) {
        this.expiresIn = expiresIn;
    }

    @Override
    public String toString() {
        return "Token [accessToken=" + accessToken + ", expiresIn=" + expiresIn + "]";
    }
    
}
 

(8)WeChatContext

package com.dajingzhu.bean;

/**
 * 微信基础配置上下文
 * @Author wuwz
 * @TypeName WeChatContext
 */
public class WeChatContext {
    private WeChatContext() {}
    private static WeChatContext context;
    private String appId;
    private String appSecrct;
    private String validateUrl;
    private String token;
    private String templateId;
    
    public static WeChatContext getInstance() {
        if(context == null) {
            context = new WeChatContext();
        }
        return context;
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getAppSecrct() {
        return appSecrct;
    }

    public void setAppSecrct(String appSecrct) {
        this.appSecrct = appSecrct;
    }

    public String getValidateUrl() {
        return validateUrl;
    }

    public void setValidateUrl(String validateUrl) {
        this.validateUrl = validateUrl;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }
    public String getTemplateId() {
        return templateId;
    }
    public void setTemplateId(String templateId) {
        this.templateId = templateId;
    }
}
 

也不知道哪些错的哪些对的,都传了,还有几个感觉没啥用,就没传了,如果少了直接联系我,当年我在网上找资料,受够了藏一半的博客

四、尝试连接微信

      将写好的程序发布到Tomcat上,而微信接口开发者配置只接受80端口,我的解决方案是Ngrok反向代理,模拟80端口(我前面的文章有写过怎么设置ngork反向代理),把地址填写到接口配置的url上,设置token,点击保存,保存成功就能调用接口,如果不能调用就是程序的问题,检测程序,排错。

你可能感兴趣的:(wechat)