1.微信公众号测试平台
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
扫描进入后可以获得appid和appsecret
并且需要配置自己的域名
2.工具类,java发送HTTP请求的
package com.test.util;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
public class Util {
private static final String DEF_CHARSET="UTF-8";
/**
* 向指定的地址发送get请求
* 如果地址中有中文可能会造成乱码,可以用URLEncoder.encode("中文", "UTF-8")处理
* @param url
* @return
*/
public static String get(String url) {
StringBuilder sBuilder = new StringBuilder();
try {
URL urlObj = new URL(url);
//开链接
URLConnection connection = urlObj.openConnection();
InputStream is = connection.getInputStream();
byte[] b = new byte[1024];
int len;
while ((len=is.read(b))!=-1 ) {
sBuilder.append(new String(b,0,len));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sBuilder.toString();
}
/**
* 向指定地址发送post请求,带着数据
* data格式"qrcode=1111&longitude=21.222&latitude=23.344&address=空间大姐夫"
* @param url
* @param data
* @return
*/
public static String post(String url,String data) {
StringBuilder sBuilder = new StringBuilder();
try {
URL urlObj = new URL(url);
//开链接
URLConnection connection = urlObj.openConnection();
connection.setRequestProperty("charset", "utf-8");
//要发送数据出去,必须要设置为可发送数据状态
connection.setDoOutput(true);
//获取输出流
OutputStream os = connection.getOutputStream();
//写出数据
os.write(data.getBytes());
os.close();
//获取输入流读取数据
InputStream is = connection.getInputStream();
byte[] b = new byte[1024];
int len;
while ((len=is.read(b))!=-1 ) {
sBuilder.append(new String(b,0,len));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sBuilder.toString();
}
public static void main(String[] args) {
post("http://192.168.1.4:8080/zzserver/qrcodejb/saveQRCodeJB","qrcode=1111&longitude=21.222&latitude=23.344&address=空间大姐夫");
}
}
3.写一个servlet
package com.test.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.test.service.WxService;
import net.sf.json.JSONObject;
/**
* Servlet implementation class TestServlet
*/
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TestServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String code = request.getParameter("code");
String result=WxService.getOpenId(code);
//String token = JSONObject.fromObject(result).getString("access_token");此种方法获取的token会报错!!!!!!!!!!!
String token =WxService.getAccessToken();
String openid = JSONObject.fromObject(result).getString("openid");
System.out.println("doget======token:"+token);
System.out.println("doget======openid:"+openid);
String userInfo=WxService.getUserInfo(token,openid);
System.out.println(userInfo);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
4.写一个service
package com.test.service;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.test.model.AccessToken;
import com.test.util.*;
import jdk.nashorn.api.scripting.URLReader;
import net.sf.json.JSONObject;
public class WxService {
private static final String APPID="你自己公众号的appid";
private static final String APPSECRET="你自己公众号的APPSECRET";
private static final String GET_TOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
//用于存储token
private static AccessToken at;
/**
* 获取token
*/
private static void getToken() {
String url = GET_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
System.out.println(url);
String str = Util.get(url);
JSONObject object= JSONObject.fromObject(str);
String token = object.getString("access_token");
String expireIn = object.getString("expires_in");
//创建token对象并存起来
at = new AccessToken(token,expireIn);
}
/**
* 向外暴露获取token的方法
* @return
*/
public static String getAccessToken() {
if(at==null || at.isExpired()) {
System.out.println("1");
getToken();
}
return at.getAccessToken();
}
/**
* 获取用户的基本信息
* @param openId
* @return
*/
public static String getUserInfo(String accessToken,String openId) {
String url="https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
url = url.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
String result=Util.get(url);
System.out.println("getUserInfo:"+result);
return result;
}
/**
* 根据code获取openId
* 注意:此方法只能获取openid,accesstoken要用getAccessToken()获取,否则报错;
* @param code
* @return
* {"access_token":"17_GGijMMF0rx8PpOrQ7QaHXzXvWa5TuaHl4TJ_uTrL0t4SJNy9KdX2OqUytRmMnFto919ikZEH_pwNolsolZUJ49PaEMSP1lXc80VKa53r0fo","expires_in":7200,"refresh_token":"17_MhG27a3Y84FJEAms_8P-LQx1sfCRwlRy5DFG3zHJ28XuSqLr94GgSd8H9fZVx7Cz8eoy5nMuO0RfflJHcOi7K3Izvf-z2nBhFB2dlScfqgo","openid":"opPyS0gqyIf5bDT0hpyahIAOl5iU","scope":"snsapi_userinfo"}
*/
public static String getOpenId(String code) {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
url=url.replace("APPID", APPID).replace("SECRET", APPSECRET).replace("CODE", code);
String result = Util.get(url);
System.out.println("getOpenId:"+result);
return result;
}
public static void main(String[] args) {
//getAccessToken();
//getUserInfo("");
}
/**
* 验证签名
*/
public static boolean check(String token, String timestamp, String nonce, String signature) {
/**
* 1)将token、timestamp、nonce三个参数进行字典序排序
* 2)将三个参数字符串拼接成一个字符串进行sha1加密
* 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
*/
String[] strs=new String[] {token,timestamp,nonce};
System.out.println(strs);
Arrays.sort(strs);
System.out.println(strs);
String str = strs[0]+strs[1]+strs[2];
String mysig=sha1(str);
System.out.println(mysig);
System.out.println(signature);
return mysig.equalsIgnoreCase(signature);
}
private static String sha1(String str) {
//获取一个加密对象
try {
MessageDigest md = MessageDigest.getInstance("sha1");
//加密
byte[] digest = md.digest(str.getBytes());
char[] chars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
StringBuilder sb = new StringBuilder();
//处理加密结果
for(byte b:digest) {
sb.append(chars[(b>>4)&15]);
sb.append(chars[b&15]);
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static Map<String, String> parseRequest(HttpServletRequest request) {
Map<String,String> map = new HashMap<String,String>();
try {
InputStream is=request.getInputStream();
SAXReader reader = new SAXReader();
//读取输入流
Document document = reader.read(is);
//根据文档对象获取节点
Element root = document.getRootElement();
//获取根节点的所有子节点
List<Element> elements = root.elements();
for (Element e : elements) {
map.put(e.getName(), e.getStringValue());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
}
5.用来存放token的实体类
package com.test.model;
public class AccessToken {
private String accessToken;
private long expireTime;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(long expireTime) {
this.expireTime = expireTime;
}
public AccessToken(String accessToken, String expireIn) {
super();
this.accessToken = accessToken;
this.expireTime = System.currentTimeMillis()+Integer.parseInt(expireIn)*1000;
}
/**
* 查看是否国企
* @return
*/
public boolean isExpired() {
return System.currentTimeMillis()>expireTime;
}
}
项目源码以及jar等在github上,地址为 https://github.com/441985745/studyWechat