微信工具类

发布于 2019-01-17  501 次阅读


[wpstatistics stat=usersonline time=today]

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sky.model.TWechatConfigurationfile;
import com.sky.wechat.replyport.ReplyUtil.AccessToken;
import com.sky.wechat.replyport.ReplyUtil.MyX509TrustManager;
import com.sky.wechat.replyport.ReplyUtil.SignUtil;
import com.sky.wechat.replyport.model.AccessTokenInWeb;
import com.sky.wechat.replyport.model.JsapiTicket;

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

public class WechatUtil {
private static Log log=LogFactory.getLog(WechatUtil.class);

private static Map<String ,AccessToken> tokenMap=new HashMap<String, AccessToken>();

public static Map<String, AccessToken> getTokenMap() {
return tokenMap;
}

public static Map<String,JsapiTicket> jsapiTick=new HashMap<String, JsapiTicket>();

/**

  • 获取凭证
  • @return
    */

public static String getToken(String appid) {
log.info("进入getToken获取凭证");
AccessToken token = tokenMap.get(appid);
log.info("进入getToken获取凭证,获取到的凭证是:"+token);
if(token==null){
throw new RuntimeException("无公众号配置");
}
if (token.getToken()==null||token.isDisabled()) {
String requestUrl = access_token_url.replace("APPID", token.getC().getAppid()).replace("APPSECRET", token.getC().getAppsecret());
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
token.setToken(jsonObject.getString("access_token"));
token.setExpiresIn(jsonObject.getInt("expires_in"));
} catch (Exception e) {
token .setToken(null);
// 获取token失败
log.info("获取token失败 errcode:{"+ jsonObject.getInt("errcode") + "} errmsg:{"+ jsonObject.getString("errmsg") + "}");
throw new RuntimeException("获取token失败");
}
}
}
return token.getToken();
}

/**

  • 创建json菜单字符串并发布至微信服务器
    *
  • @param menu
  • @param accessToken
  • @return 0创建菜单成功,其他失败
    */
    public static int createMenu(String menu,String configfileId) {
    int result = 0;
    AccessToken token=null;
    Iterator<Entry<String, AccessToken>> iterator = tokenMap.entrySet().iterator();
    while(iterator.hasNext()){
    Entry<String, AccessToken> next = iterator.next();
    AccessToken t = next.getValue();
    if(t.getC().getId().equals(configfileId)){
    token=t;
    break;
    }
    }
    if(token==null){
    return result;
    }
    // 拼装创建菜单的url
    String url = menu_create_url.replace("ACCESS_TOKEN", getToken(token.getAppId()));
    log.info(menu);
    // 调用接口创建菜单
    JSONObject jsonObject = httpRequest(url, "POST", menu);
    if (null != jsonObject) {
    if (0 != jsonObject.getInt("errcode")) {
    result = jsonObject.getInt("errcode");
    log.info("创建菜单失败 errcode:{" + jsonObject.getInt("errcode") + "} errmsg:{" + jsonObject.getString("errmsg") + "}");
    }
    }
    return result; // 创建成功
    }

/**

  • 删除自定义菜单
  • @param accessToken
  • @return
    */
    public static int deleteMenu(String accessToken) {
    String url = menu_delete_url.replace("ACCESS_TOKEN", accessToken);
    JSONObject jsonObject = httpRequest(url, "GET", null);
    return jsonObject.getInt("errcode");

}

/**

  • 验证服务器地址的有效性,验证签名,
  • 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
  • @param signature 微信加密签名
  • @param timestamp 时间戳
  • @param nonce 随机数
  • @return
    */
    public static boolean checkSignature(String signature,String timestamp,String nonce,String appid){
    AccessToken token=tokenMap.get(appid);

if(token==null){
log.info("非法接入,无此公众号信息,appid:"+appid);
return false;
}
String[] arr = new String[] { token.getC().getToken(), timestamp, nonce };
//将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
// 将三个参数字符串拼接成一个字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = SignUtil.byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
content = null;
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}

/**获取用户信息

  • @param openid
  • @return
    */
    public static JSONObject getInfo(String openid,String appid){
    System.out.println("进入获取用户信息页面");
    String url=get_user_url.replace("ACCESS_TOKEN", getToken(appid)).replace("OPENID", openid);
    JSONObject jsonObject =httpRequest(url, "GET", null);
    return jsonObject;
    }

/**获取所有用户列表

  • @param openid
  • @return
    */
    public static JSONObject getAllUserInfo(String openid,String appid){
    String url=userInfoAll.replace("ACCESS_TOKEN", getToken(appid)).replace("NEXT_OPENID", openid);
    JSONObject jsonObject =httpRequest(url, "GET", null);
    return jsonObject;
    }

/**高级接口,获得用户openid

  • @param code
  • @return
    */
    public static AccessTokenInWeb getOpenidByCode(String code,String APPID){
    String url = access_token2.replace("APPID", APPID).replace("SECRET", tokenMap.get(APPID).getC().getAppsecret()).replace("CODE", code);
    JSONObject jsonObject =httpRequest(url, "GET", null);
    AccessTokenInWeb a=new AccessTokenInWeb();
    if(!jsonObject.containsKey("errcode")){
    a.setAccess_token(jsonObject.getString("access_token"));
    a.setExpires_in(jsonObject.getInt("expires_in"));
    a.setOpenid(jsonObject.getString("openid"));
    a.setRefresh_token(jsonObject.getString("refresh_token"));
    a.setScope(jsonObject.getString("scope"));
    a.setAppId(APPID);
    }else{
    a.setErrcode(jsonObject.getString("errcode"));
    a.setErrmsg(jsonObject.getString("errmsg"));
    }
    return a;
    }

/**跳转url,获得code

  • @param request
  • @return
  • @throws UnsupportedEncodingException
    */
    public static String getAuthorize(HttpServletRequest request,String scope,String appid) throws UnsupportedEncodingException{
    String url=authorize.replace("APPID", appid).replace("REDIRECT_URI", URLEncoder.encode(request.getRequestURL().toString(),"utf-8")).replace("SCOPE", scope);
    String queryString = request.getQueryString();
    if(StringUtils.isNotEmpty(queryString)){
    url = url.replace("STATE", request.getQueryString());
    }
    return url;
    }

/**刷新高级接口的token

  • @param token
    */
    public static void getRefreshToken(AccessTokenInWeb token,String appid){
    String url=refresh_token.replace("APPID", appid).replace("REFRESH_TOKEN", token.getRefresh_token());
    JSONObject jsonObject =httpRequest(url, "GET", null);
    if(!jsonObject.containsKey("errcode")){
    token.setAccess_token(jsonObject.getString("access_token"));
    token.setExpires_in(jsonObject.getInt("expires_in"));
    token.setOpenid(jsonObject.getString("openid"));
    token.setRefresh_token(jsonObject.getString("refresh_token"));
    token.setScope(jsonObject.getString("scope"));
    }else{
    token.setErrcode(jsonObject.getString("errcode"));
    token.setErrmsg(jsonObject.getString("errmsg"));
    }
    }

/**高级接口获取用户信息

  • @param t
  • @return
    */
    public static JSONObject getUserinfoWeb(AccessTokenInWeb t){
    String url=userinfo.replace("ACCESS_TOKEN", t.getAccess_token()).replace("OPENID", t.getOpenid());
    JSONObject jsonObject =httpRequest(url, "GET", null);
    return jsonObject;
    }

/**获取js的ticket

  • @param appid
  • @return
    */
    public static String getJsapiTick(String appid) {
    JsapiTicket ticket = jsapiTick.get(appid);
    if(ticket==null||ticket.isDisabled()){
    //失效
    String token = getToken(appid);
    if(token==null){
    throw new RuntimeException("token失效");
    }
    String requestUrl = jsapi_tick.replace("ACCESS_TOKEN",token);
    JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
    // 如果请求成功
    if (null != jsonObject) {
    try {
    if(ticket==null){
    ticket=new JsapiTicket();
    ticket.setAppId(appid);
    jsapiTick.put(appid, ticket);
    }

ticket.setJsapi_ticket(jsonObject.getString("ticket"));
ticket.setExpires_in(jsonObject.getInt("expires_in"));
} catch (Exception e) {

// 获取token失败
log.info("获取token失败 errcode:{"

  • jsonObject.getInt("errcode") + "} errmsg:{"
  • jsonObject.getString("errmsg") + "}");
    throw new RuntimeException("获取token失败");
    }
    }
    }
    return ticket.getJsapi_ticket();
    }

/**发送请求

  • @param requestUrl
  • @param requestMethod
  • @param outputStr
  • @return
    */
    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 conn = (HttpsURLConnection) url.openConnection();
// 证书
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod)){
conn.connect();
}

// 当有数据需要提交时
if (null != outputStr && !"".equals(outputStr)) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));// 写进去
outputStream.close();
}
log.info("<<<提交请求方式"+requestMethod+",url:"+requestUrl+outputStr!=null?("\r提交数据:"+outputStr):"");
// 将返回的输入流转换成字符串
InputStream inputStream = conn.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;
conn.disconnect();
log.info(">>>>>>>响应数据:"+buffer);
jsonObject = JSONObject.fromObject(buffer.toString());
log.info(jsonObject.toString());
} catch (ConnectException ce) {
log.info("Weixin server connection timed out.");
} catch (Exception e) {
// log.error("https request error:{}", e);
}
return jsonObject;
}

/**

  • 获取生成用户关注二维码所需二维码ticket
  • @param appid
  • @param scene_id 传入的参数
    */
    public static String getLsTicket(String appid,Integer scene_id ){
    String lsTicket ="";
    //1.先获取access_token
    String access_token = getToken(appid);
    //根据access_token获取的创建临时二维码ticket,expire_seconds是临时二维码有效时间,最大是30天,scene_id是传入的参数
    String jsonStr = "{\"expire_seconds\": 2592000,\"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": "+scene_id+"}}}";
    String requestUrl = ls_ticket_url.replace("ACCESS_TOKEN", access_token);
    JSONObject jsonObject = httpRequest(requestUrl, "POST", jsonStr);
    // 如果请求成功
    if (null != jsonObject) {
    try {
    lsTicket=jsonObject.getString("ticket");
    //提醒:TICKET记得进行UrlEncode
    lsTicket = java.net.URLEncoder.encode(lsTicket,"utf-8");
    } catch (Exception e) {
    // 获取ticket失败
    log.info("获取ticket失败 errcode:{"+ jsonObject.getInt("errcode") + "} errmsg:{"+ jsonObject.getString("errmsg") + "}");
    throw new RuntimeException("获取ticket失败");
    }
    }
    return lsTicket;

}

/**

  • @param args
    */
    public void init(List<TWechatConfigurationfile> list) {
    // TODO Auto-generated method stub
    System.out.println("-----------------》进入WechatUtil的init方法");

for(int i=0;i<list.size();i++){
TWechatConfigurationfile f = list.get(i);
AccessToken t=new AccessToken();
t.setAppId(f.getAppid());
t.setC(f);
tokenMap.put(t.getAppId(), t);
tokenMap.put(f.getAccountNumber(), t);
tokenMap.put(f.getId(), t);
if(StringUtils.isNotEmpty(f.getUrl())){
String contextPath=f.getUrl().substring(f.getUrl().lastIndexOf("/")+1);
tokenMap.put(contextPath, t);
}

}
System.out.println("-----------------》tokenMap的值是:"+tokenMap);
}

private static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
private static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
private static String menu_delete_url = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";
private static String chat_get_url = "https://api.weixin.qq.com/cgi-bin/customservice/getrecord?access_token=ACCESS_TOKEN";
private static String get_user_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
private static String authorize = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
private static String access_token2 = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
private static String userinfo = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
private static String refresh_token = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
private static String mchdown_real_new = "http://mch.tenpay.com/cgi-bin/mchdown_real_new.cgi";
private static String delivernotify="http://api.weixin.qq.com/cgi-bin/pay/delivernotify?access_token=ACCESS_TOKEN";
private static String userInfoAll="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";

private static String jsapi_tick="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
private static String ls_ticket_url="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";


公交车司机终于在众人的指责中将座位让给了老太太