在开始之前,先搭建个简单的java web工程
spring mvc 来做web层
httpclient 4.4来做http层
log4j来做日志
本文将实行微信公众号开发的两个简单接口
获取access token
access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
获取微信服务器IP地址
如果公众号基于消息接收安全上的考虑,需要获知微信服务器的IP地址列表,以便识别出哪些消息是微信官方推送给你的,哪些消息可能是他人伪造的,可以通过该接口获得微信服务器IP地址列表。
先上代码
package com.fly.wechat.mpdemo.api.session;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fly.wechat.mpdemo.api.BaseController;
import com.fly.wechat.mpdemo.common.secure.SignUtils;
import com.fly.wechat.mpdemo.config.MchInfo;
@Controller
@RequestMapping("/baseSupport")
public class BaseSupportController extends BaseController{
/**
* 获取token url
*/
public static final String GETACCESSTOKEN_URL="https://api.weixin.qq.com/cgi-bin/token";
/**
* 获取微信服务器IP地址
*/
public static final String GETCALLBACKIP_URL="https://api.weixin.qq.com/cgi-bin/getcallbackip";
@ResponseBody
@RequestMapping("/getAccessToken.do")
public String getAccessToken() throws Throwable {
Map<String,String> map=new HashMap<String,String>();
map.put("appid", MchInfo.APPID);
map.put("secret", MchInfo.APPSECRET);
map.put("grant_type", "client_credential");
return httpGet(GETACCESSTOKEN_URL, SignUtils.createLinkString(map), d_timeout);
}
@ResponseBody
@RequestMapping("/getcallbackip.do")
public String getcallbackip() throws Throwable {
Map<String,String> map=new HashMap<String,String>();
map.put("access_token", MchInfo.getAccessToken());
return httpGet(GETCALLBACKIP_URL, SignUtils.createLinkString(map), d_timeout);
}
public static void main(String[] args) throws Throwable{
BaseSupportController bsc=new BaseSupportController();
System.out.println(bsc.getAccessToken());
// System.out.println(bsc.getcallbackip());
}
}
开始之前需要一些基础类来完成
BaseController 来做一些基本操作的封装
package com.fly.wechat.mpdemo.api;
import java.io.File;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.entity.ContentType;
import org.apache.log4j.Logger;
import com.fly.wechat.mpdemo.common.BeanUtil;
import com.fly.wechat.mpdemo.common.http.HttpUtils;
import com.fly.wechat.mpdemo.common.http.Response;
import com.fly.wechat.mpdemo.config.MchInfo;
public class BaseController {
public Logger log = Logger.getLogger(getClass());
String token = "jiayou";
protected int d_timeout=5000;
String access(HttpServletRequest request, HttpServletResponse response) {
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
if (signature == null || timestamp == null || nonce == null || echostr == null) {
return "signature==null||timestamp==null||nonce==null||echostr==null参数错误";
}
log.info("----------signature:" + signature + "--timestamp:" + timestamp + "--nonce:" + nonce
+ "--echostr:" + echostr);
String[] str = { timestamp, nonce, token };
Arrays.sort(str); // 字典序排序
String bigStr = str[0] + str[1] + str[2];
String calSign = getSHA1String(bigStr);
log.info("-----calSign-----" + calSign);
if (signature.equals(calSign)) {
System.out.println("ok");
return echostr;
}
return "";
}
protected String parseResponse(Response response) throws Throwable{
if(response!=null&&response.getStatusCode()==200){
String rtn = new String(response.getResponseString().getBytes("ISO-8859-1"), "utf-8");
log.info("response:"+rtn+" errMsg:"+MchInfo.coverErrorCode(BeanUtil.json2Map(rtn).get("errcode")+""));
return rtn;
}
return "!200 error";
}
protected String httpGet(String url, String params, int timeout) throws Throwable{
params = new String(params.getBytes("utf-8"), "ISO-8859-1");
Response response=HttpUtils.httpGet(url, params, timeout);
return parseResponse(response);
}
protected String httpPost(String url, String params, int timeout) throws Throwable{
params = new String(params.getBytes("utf-8"), "ISO-8859-1");
Response response=HttpUtils.httpPost(url, params, timeout);
return parseResponse(response);
}
protected String httpPostFile(String url,String name, File file,ContentType contentType, int timeout) throws Throwable{
Response response=HttpUtils.httpPostFile(url, name, file,contentType, timeout);
return parseResponse(response);
}
protected String httpPostHeader(String url, String params, int timeout) throws Throwable{
params = new String(params.getBytes("utf-8"), "ISO-8859-1");
Response response=HttpUtils.httpPostHeader(url, params, timeout);
return response.getResponseString();
}
private final static String[] strDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",
"e", "f" };
private static String byteToArrayString(byte bByte) {
int iRet = bByte;
// System.out.println("iRet="+iRet);
if (iRet < 0) {
iRet += 256;
}
int iD1 = iRet / 16;
int iD2 = iRet % 16;
return strDigits[iD1] + strDigits[iD2];
}
private static String byteToString(byte[] bByte) {
StringBuffer sBuffer = new StringBuffer();
for (int i = 0; i < bByte.length; i++) {
sBuffer.append(byteToArrayString(bByte[i]));
}
return sBuffer.toString();
}
public static String getSHA1String(String strObj) {
String resultString = null;
try {
resultString = new String(strObj);
MessageDigest md = MessageDigest.getInstance("SHA1");
// md.digest() 该函数返回值为存放哈希值结果的byte数组
resultString = byteToString(md.digest(strObj.getBytes()));
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
return resultString;
}
}