java开发微信公众号

1.接入微信公众号

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            System.out.println("接口测试开始!!!");
            //微信加密签名
            String signature = request.getParameter("signature");
            //时间戳
            String timestamp = request.getParameter("timestamp");
            //随机数
            String nonce = request.getParameter("nonce");
            //随机字符串
            String echostr = request.getParameter("echostr");
            
            PrintWriter out = response.getWriter();
            //通过校验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
            if(SignUtil.checkSignature(signature,timestamp,nonce)){
                out.print(echostr);
            }
            out.close();
            out = null;
//            response.encodeRedirectURL("success.jsp");
            
        
    }
    /**
     * 处理微信服务器发来的消息
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //消息的接受、处理、响应
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        //调用核心业务类型接受消息、处理消息
        String respMessage = EastnetService.processRequest(request);
        
        //响应消息
        PrintWriter out = response.getWriter();
        out.print(respMessage);
        out.close();
        
        
    }
确认请求来自于微信服务器
 1 import java.security.MessageDigest;
 2 import java.security.NoSuchAlgorithmException;
 3 import java.util.Arrays;
 4 import java.util.Iterator;
 5 import java.util.Map;
 6 import java.util.Set;
 7 import java.util.concurrent.ConcurrentHashMap;
 8 
 9 /**
10  * 请求校验工具类
11  * @author pengsong
12  * @date 2016.01.19
13  */
14 public class SignUtil {
15     //与微信配置中的的Token一致
16     private static String token  = "你的token";
17     
18     public static boolean checkSignature(String signature, String timestamp,
19             String nonce) {
20         String[] arra = new String[]{token,timestamp,nonce};
21         //将signature,timestamp,nonce组成数组进行字典排序
22         Arrays.sort(arra);
23         StringBuilder sb = new StringBuilder();
24         for(int i=0;i<arra.length;i++){
25             sb.append(arra[i]);
26         }
27         MessageDigest md = null;
28         String stnStr = null;
29         try {
30             md = MessageDigest.getInstance("SHA-1");
31             byte[] digest = md.digest(sb.toString().getBytes());
32             stnStr = byteToStr(digest);
33         } catch (NoSuchAlgorithmException e) {
34             // TODO Auto-generated catch block
35             e.printStackTrace();
36         }
37         //释放内存
38         sb = null;
39         //将sha1加密后的字符串与signature对比,标识该请求来源于微信
40         return stnStr!=null?stnStr.equals(signature.toUpperCase()):false;
41     }
42     /**
43      * 将字节数组转换成十六进制字符串
44      * @param digestArra
45      * @return
46      */
47     private static String byteToStr(byte[] digestArra) {
48         // TODO Auto-generated method stub
49         String digestStr = "";
50         for(int i=0;i<digestArra.length;i++){
51             digestStr += byteToHexStr(digestArra[i]);
52         }
53         return digestStr;
54     }
55     /**
56      * 将字节转换成为十六进制字符串
57      */
58     private static String byteToHexStr(byte dByte) {
59         // TODO Auto-generated method stub
60         char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
61         char[] tmpArr = new char[2];
62         tmpArr[0] = Digit[(dByte>>>4)&0X0F];
63         tmpArr[1] = Digit[dByte&0X0F];
64         String s = new String(tmpArr);
65         return s;
66     }
67     
68     public static void main(String[] args) {
69         /*byte dByte = 'A';
70         System.out.println(byteToHexStr(dByte));*/
71         Map<String,String> map = new ConcurrentHashMap<String, String>();
72         map.put("4", "zhangsan");
73         map.put("100", "lisi");
74         Set set = map.keySet();
75         Iterator iter = set.iterator();
76         while(iter.hasNext()){
77 //            String keyV = (String) iter.next();
78             String key =(String)iter.next();
79             System.out.println(map.get(key));
80 //            System.out.println(map.get(iter.next()));
81         }
82         /*for(int i=0;i<map.size();i++){
83             
84         }*/
85     }
效验signature SignUtil

2.创建菜单

      2.1获取Access_Token

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.eastnet.wechat.pojo.AccessToken;
import com.eastnet.wechat.pojo.Menu;
  
import net.sf.json.JSONObject;   
public class WeixinUtil {
//    private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);  
    // 获取access_token的接口地址(GET) 限200(次/天)  
    public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";  
    // 菜单创建(POST) 限100(次/天)  
    public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";  
    /** 
     * 发起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();  
            System.out.println(buffer.toString());
            jsonObject = JSONObject.fromObject(buffer.toString());  
        } catch (ConnectException ce) {  
            System.out.println("Weixin server connection timed out.");
        } catch (Exception e) {  
            System.err.println("https request error:{}");
//            log.error("https request error:{}", e);  
        }  
        return jsonObject;  
    }  
    /** 
     * 获取access_token 
     *  
     * @param appid 凭证 
     * @param appsecret 密钥 
     * @return 
     */  
    public static AccessToken getAccessToken(String appid, String appsecret) {  
        AccessToken accessToken = null;  
      
        String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);  
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  
        // 如果请求成功  
        if (null != jsonObject) {  
            try {  
                accessToken = new AccessToken();  
                accessToken.setToken(jsonObject.getString("access_token"));  
                accessToken.setExpiresIn(jsonObject.getInt("expires_in"));  
            } catch (Exception e) {  
                accessToken = null;  
                // 获取token失败  
                System.out.println("获取token失败 errcode:"+jsonObject.getInt("errcode")+"errmsg:"+jsonObject.getString("errmsg"));
//                log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));  
            }  
        }  
        return accessToken;  
    }
    /** 
     * 创建菜单 
     *  
     * @param menu 菜单实例 
     * @param accessToken 有效的access_token 
     * @return 0表示成功,其他值表示失败 
     */  
    public static int createMenu(Menu menu, String accessToken) {  
        int result = 0;  
      
        // 拼装创建菜单的url  
        String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);  
        // 将菜单对象转换成json字符串  
        String jsonMenu = JSONObject.fromObject(menu).toString();  
        // 调用接口创建菜单  
        JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);  
      
        if (null != jsonObject) {  
            if (0 != jsonObject.getInt("errcode")) {  
                result = jsonObject.getInt("errcode"); 
                System.out.println("创建菜单失败errcode:"+jsonObject.getInt("errcode")+"errmsg:"+jsonObject.getString("errmsg"));
//                log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));  
            }  
        }  
      
        return result;  
    } 
}
WeixinUtil
public class AccessToken {
    // 获取到的凭证  
    private String token;  
    // 凭证有效时间,单位:秒  
    private int expiresIn;  
  
    public String getToken() {  
        return token;  
    }  
  
    public void setToken(String token) {  
        this.token = token;  
    }  
  
    public int getExpiresIn() {  
        return expiresIn;  
    }  
  
    public void setExpiresIn(int expiresIn) {  
        this.expiresIn = expiresIn;  
    }  
}
AccessToken类
import javax.net.ssl.X509TrustManager;  
  
/** 
 * 证书信任管理器(用于https请求) 
 *  
 * @author steve 
 * @date 2013-08-08 
 */  
public class MyX509TrustManager implements X509TrustManager{
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
    }  
  
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
    }  
  
    public X509Certificate[] getAcceptedIssuers() {  
        return null;  
    }  
}
证书信任管理器(用于https请求) MyX509TrustManager
import java.io.IOException;
import java.io.PrintWriter;

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

import com.eastnet.wechat.pojo.AccessToken;
import com.eastnet.wechat.pojo.Button;
import com.eastnet.wechat.pojo.CommonButton;
import com.eastnet.wechat.pojo.ComplexButton;
import com.eastnet.wechat.pojo.Menu;
import com.eastnet.wechat.pojo.ViewButton;
import com.eastnet.wechat.utils.WeixinUtil;

public class CreateMenuServlet extends HttpServlet {

    /**
     * Constructor of the object.
     */
    public CreateMenuServlet() {
        super();
    }

    /**
     * Destruction of the servlet. <br>
     */
    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
        // Put your code here
    }

    /**
     * The doGet method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to get.
     * 
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 第三方用户唯一凭证  
        String appId = "你的appId";  
        // 第三方用户唯一凭证密钥  
        String appSecret = "你的appSecret";  
  
        // 调用接口获取access_token  
        AccessToken at = WeixinUtil.getAccessToken(appId, appSecret);  
  
        if (null != at) {  
            // 调用接口创建菜单  
            int result = WeixinUtil.createMenu(getMenu(), at.getToken());  
  
            // 判断菜单创建结果  
            if (0 == result){
                response.setContentType("text/html;charset=UTF-8");  
                PrintWriter pw = response.getWriter();  
                pw.println("菜单创建成功!");  
                pw.flush();     
            }else{
                response.setContentType("text/html;charset=UTF-8");  
                PrintWriter pw = response.getWriter();  
                pw.println("菜单创建失败,错误码:" + result);  
                pw.flush();     
            }   
        }
    }

    /**
     * The doPost method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to post.
     * 
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }

    /**
     * Initialization of the servlet. <br>
     *
     * @throws ServletException if an error occurs
     */
    public void init() throws ServletException {
        // Put your code here
    }
    /** 
     * 组装菜单数据 
     *  
     * @return 
     */  
    private static Menu getMenu() {  
        CommonButton btn11 = new CommonButton();  
        btn11.setName("个人信息查看");  
        btn11.setType("click");  
        btn11.setKey("stuInfoView");  
  
        CommonButton btn12 = new CommonButton();  
        btn12.setName("个人信息修改");  
        btn12.setType("click");  
        btn12.setKey("stuInfoEdit"); 
  
        CommonButton btn21 = new CommonButton();  
        btn21.setName("行程查看");  
        btn21.setType("click");  
        btn21.setKey("stuTravelView");  
  
        CommonButton btn22 = new CommonButton();  
        btn22.setName("行程添加");  
        btn22.setType("click");  
        btn22.setKey("stuTravelAdd");  
  
        CommonButton btn23 = new CommonButton();  
        btn23.setName("行程修改");  
        btn23.setType("click");  
        btn23.setKey("stuTravelEdit");  
  
        CommonButton btn31 = new CommonButton();  
        btn31.setName("操作说明");  
        btn31.setType("click");  
        btn31.setKey("help");  
  
        CommonButton btn32 = new CommonButton();  
        btn32.setName("呼叫管理员");  
        btn32.setType("click");  
        btn32.setKey("callAdmin");  
  
        CommonButton btn33 = new CommonButton();  
        btn33.setName("意见反馈");  
        btn33.setType("click");  
        btn33.setKey("suggestions");  
  
        ComplexButton mainBtn1 = new ComplexButton();  
        mainBtn1.setName("个人信息");  
        mainBtn1.setSub_button(new Button[] { btn11, btn12});  
  
        ComplexButton mainBtn2 = new ComplexButton();  
        mainBtn2.setName("行程");  
        mainBtn2.setSub_button(new Button[] { btn21, btn22, btn23});  
  
        ComplexButton mainBtn3 = new ComplexButton();  
        mainBtn3.setName("帮助");  
        mainBtn3.setSub_button(new Button[] { btn31, btn32, btn33 });  
  
        /** 
         * 这是公众号xiaoqrobot目前的菜单结构,每个一级菜单都有二级菜单项<br> 
         *  
         * 在某个一级菜单下没有二级菜单的情况,menu该如何定义呢?<br> 
         * 比如,第三个一级菜单项不是“更多体验”,而直接是“幽默笑话”,那么menu应该这样定义:<br> 
         * menu.setButton(new Button[] { mainBtn1, mainBtn2, btn33 }); 
         */  
        Menu menu = new Menu();  
        menu.setButton(new Button[] { mainBtn1, mainBtn2, mainBtn3 });  
  
        return menu;  
    }  
CreateMenuServlet
public class CommonButton extends Button {
    private String type;  
    private String key;  
  
    public String getType() {  
        return type;  
    }  
  
    public void setType(String type) {  
        this.type = type;  
    }  
  
    public String getKey() {  
        return key;  
    }  
  
    public void setKey(String key) {  
        this.key = key;  
    }  
}
CommonButton
public class ComplexButton extends Button {  
    private Button[] sub_button;  
  
    public Button[] getSub_button() {  
        return sub_button;  
    }  
  
    public void setSub_button(Button[] sub_button) {  
        this.sub_button = sub_button;  
    }  
}  
public class Menu {
    private Button[] button;  
      
    public Button[] getButton() {  
        return button;  
    }  
  
    public void setButton(Button[] button) {  
        this.button = button;  
    }  
}
Menu
原文地址:https://www.cnblogs.com/LW-baiyun/p/7889824.html