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;效验signature SignUtil
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 }
2.创建菜单
2.1获取Access_Token
import java.io.BufferedReader;WeixinUtil
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;
}
}
public class AccessToken {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;
}
}
import javax.net.ssl.X509TrustManager;证书信任管理器(用于https请求) MyX509TrustManager
/**
* 证书信任管理器(用于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;
}
}
import java.io.IOException;CreateMenuServlet
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;
}
public class CommonButton extends Button {CommonButton
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;
}
}
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 {Menu
private Button[] button;
public Button[] getButton() {
return button;
}
public void setButton(Button[] button) {
this.button = button;
}
}