portal web service

PushService.java 20KB

    package com.ekexiu.push.service; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Type; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.jfw.apt.web.annotation.Path; import org.jfw.apt.web.annotation.operate.Get; import org.jfw.apt.web.annotation.operate.Post; import org.jfw.util.ConstData; import org.jfw.util.io.IoUtil; import org.jfw.util.json.JsonService; import org.jfw.util.log.LogFactory; import org.jfw.util.log.Logger; import org.jfw.util.reflect.TypeReference; import com.ekexiu.operation.push.getui.Message; import com.ekexiu.operation.push.getui.MsgCondition; import com.ekexiu.operation.push.getui.MsgStyle; import com.ekexiu.operation.push.getui.NotificationMessage; @Path("/push") public class PushService { private static final Logger log =LogFactory.getLog(PushService.class); private static Type RES_TYPE = new TypeReference<Map<String, Object>>() { }.getType(); private static final MsgCondition android=new MsgCondition("phonetype",new String[]{"ANDROID"},1); private static final MsgCondition ios=new MsgCondition("phonetype",new String[]{"IOS"},1); private static final MsgCondition[] onlyAndroid = new MsgCondition[]{android}; private static final MsgCondition[] onlyIos = new MsgCondition[]{ios}; private static Map<String, String> CONTENT_TYPE = new HashMap<String, String>(); private static Map<String, String> TOKEN_MAP = new ConcurrentHashMap<String, String>(); private static Map<String, String> ERR_MAP = new HashMap<String, String>(); final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; // UiIGJTfKNR8oXb8apYdGh3 private String secret = "U96j677DHoA1Pv5X0mxMU9"; private String appKey = "48nq7d7yHu8dgbzVHuisp6"; private String appId = "TUdvbnxu1c97r6Fb6cUy57"; private int timeout = 0; private boolean enable = false; private String token = null; private long lastBuildTime = 0; public String getSecret() { return secret; } public void setSecret(String secret) { this.secret = secret; } public String getAppKey() { return appKey; } public void setAppKey(String appKey) { this.appKey = appKey; } public String getAppId() { return appId; } public void setAppId(String appId) { this.appId = appId; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public boolean isEnable() { return enable; } public void setEnable(boolean enable) { this.enable = enable; } private String buildSign(long flag) { String p = this.appKey + flag + this.secret; MessageDigest messageDigest; try { messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(p.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte b : messageDigest.digest()) { sb.append(digits[(b & 0xf0) >> 4]); sb.append(digits[b & 0xf]); } return sb.toString(); } catch (Exception e) { throw new RuntimeException("jdk unsupported sh256???????????", e); } } private void checkResult(Map<String, Object> ret) { Object obj = ret.get("result"); if ("ok".equals(obj)) return; String errMsg = null; errMsg = ERR_MAP.get(obj); if (errMsg == null) errMsg = "其他错误"; log.error("调用用个推restApi,返回结果错误:" + obj + ":" + errMsg); throw new RuntimeException("调用用个推restApi,返回结果错误:" + obj + ":" + errMsg); } // private void checkToken() { // if (this.token == null) { // log.error("token is null"); // throw new RuntimeException("token is null"); // } // } public String allocateRequesstId() { UUID uuid = UUID.randomUUID(); return "A" + Long.toString(uuid.getLeastSignificantBits(), 36) + "_" + Long.toString(uuid.getMostSignificantBits(), 36); } private void buildToken() { long time = System.currentTimeMillis(); String sign = this.buildSign(time); StringBuilder sb = new StringBuilder(); sb.append("{\"sign\":\"").append(sign).append("\",\"timestamp\":\"").append(time).append("\",\"appkey\":\"").append(this.appKey).append("\"}"); try { Map<String, Object> ret = post("https://restapi.getui.com/v1/" + this.appId + "/auth_sign", CONTENT_TYPE, sb.toString().getBytes(ConstData.UTF8)); this.checkResult(ret); String otoken = (String) ret.get("auth_token"); if (otoken == null) { throw new RuntimeException("返回token is null"); } this.token = otoken; this.lastBuildTime = System.currentTimeMillis(); TOKEN_MAP.put("authtoken", this.token); } catch (Exception e) { this.token = null; log.error("build token error", e); } } public void refresh() { if ((this.token != null) && ((System.currentTimeMillis() - this.lastBuildTime) < (24 * 60 * 60 * 1000 - 5000))) { return; } if(enable) this.buildToken(); } public Map<String, Object> post(String url, Map<String, String> header, byte[] data) throws IOException { HttpURLConnection connection = getConnection(url); try { connection.setRequestMethod("POST"); connection.setUseCaches(false); for (Map.Entry<String, String> entry : header.entrySet()) { connection.setRequestProperty(entry.getKey(), entry.getValue()); } connection.setDoOutput(true); connection.setDoInput(true); if (this.timeout > 0) { connection.setConnectTimeout(this.timeout); connection.setReadTimeout(this.timeout); } connection.setFixedLengthStreamingMode(data.length); OutputStream out = connection.getOutputStream(); try { out.write(data); } finally { out.close(); } int code = connection.getResponseCode(); if (code == 200) { InputStream in = null; byte[] resData = null; try { in = connection.getInputStream(); resData = IoUtil.readStream(in, false); } catch (IOException e) { log.error("Error read http response stream,url:" + url, e); throw new IOException("Error read http response stream"); } finally { if (null != in) IoUtil.close(in); } try { return JsonService.fromJson(new String(resData, ConstData.UTF8), RES_TYPE); } catch (Exception e) { log.error("invalid response data,url:" + url, e); throw new IOException("invalid response data", e); } } log.error("Error http reponse status:" + code + ",url:" + url); throw new IOException("Error http reponse status:" + code); } finally { connection.disconnect(); } } @Path("/bindAlias") @Post public boolean bindAlias(String alias, String cid) { String url = "https://restapi.getui.com/v1/" + this.appId + "/bind_alias"; StringBuilder sb = new StringBuilder(); sb.append("{\"alias_list\" : [{\"cid\":\"").append(cid).append("\",\"alias\":\"").append(alias).append("\" }]}"); try { Map<String, Object> ret = post(url, TOKEN_MAP, sb.toString().getBytes(ConstData.UTF8)); this.checkResult(ret); return true; } catch (IOException e) { log.error("bind alias error[cid:" + cid + ",alias:" + alias + "]", e); return false; } } @Get @Path("/token") public String getToken(){ String ret = this.token; if(ret!=null){ int len = ret.length(); Random random = new Random(); int idx = random.nextInt(len-1); if(idx<1 || idx >=len){ return ret; } return ret.substring(idx)+ret.substring(0,idx)+"_"+idx; } return null; } @Path("/bindTags") @Post public boolean bindTags(String[] tags, String cid) { String url = "https://restapi.getui.com/v1/" + this.appId + "/set_tags"; Map<String,Object> msg = new HashMap<String,Object>(); msg.put("cid",cid); msg.put("tag_list",tags); try { Map<String, Object> ret = post(url, TOKEN_MAP, JsonService.toJson(msg).getBytes(ConstData.UTF8)); this.checkResult(ret); return true; } catch (IOException e) { log.error("bind tags error:"+JsonService.toJson(msg), e); return false; } } @Path("/applyBadge") @Get public void applyBadge(int badge,String cid,String devtoken){ String url = "https://restapi.getui.com/v1/" + this.appId + "/set_badge"; StringBuilder sb = new StringBuilder(); sb.append("{\"badge\":").append(badge).append(",\"cid_list\":[\"").append(cid).append("\"],\"devicetoken_list\":[\"").append(devtoken).append("\"]}"); System.out.println(sb.toString()); try { Map<String, Object> ret = post(url, TOKEN_MAP, sb.toString().getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (IOException e) { log.error("apply badge error[cid:" + cid + ",devtoken:" + devtoken + "]", e); } } private Map<String,Object > createIosMessage(String title,String content,String payload){ Map<String,Object> ret = new HashMap<String,Object>(); Map<String,Object> message= new HashMap<String,Object>(); ret.put("message", message); message.put("appkey",this.appKey); message.put("is_offline",true); message.put("msgtype", "transmission"); Map<String,Object> transmission = new HashMap<String,Object>(); ret.put("transmission", transmission); transmission.put("transmission_type", false); transmission.put("transmission_content", payload); Map<String,Object> pushInfo = new HashMap<String,Object>(); ret.put("push_info", pushInfo); Map<String,Object> aps = new HashMap<String,Object>(); pushInfo.put("aps",aps); Map<String,Object> alert = new HashMap<String,Object>(); aps.put("alert", alert); alert.put("title", title); alert.put("body",content); aps.put("autoBadge","+1"); aps.put("content-available",1); aps.put("sound","default"); pushInfo.put("payload",payload); ret.put("condition", onlyIos); return ret; } private Map<String,Object > createAndriodMessage(String title,String content,String payload){ Map<String,Object> ret = new HashMap<String,Object>(); Message message = new Message(); ret.put("message", message); message.setAppKey(this.appKey); message.setMsgtype("notification"); message.setOffline(true); message.setOfflineExpireTime(2*60*1000); message.setPushNetworkType(0); NotificationMessage notification = new NotificationMessage(); ret.put("notification", notification); notification.setTransmissionType(true); notification.setTransmissionContent(payload); MsgStyle style = new MsgStyle(); notification.setStyle(style); style.setType(0); style.setClearable(true); style.setRing(true); style.setText(content); style.setTitle(title); style.setVibrate(true); ret.put("condition", onlyAndroid); return ret; } public void toApp(String title,String content,Object payload){ String url = "https://restapi.getui.com/v1/"+this.appId+"/push_app"; String pl_str = JsonService.toJson(payload); Map<String,Object> andriodMessage = this.createAndriodMessage(title, content, pl_str); Map<String,Object> iosMessage = this.createIosMessage(title, content, pl_str); andriodMessage.put("requestid",this.allocateRequesstId()); iosMessage.put("requestid",this.allocateRequesstId()); // System.out.println(JsonService.toJson(andriodMessage)); // System.out.println(JsonService.toJson(iosMessage)); try { Map<String,Object> ret = post(url, TOKEN_MAP,JsonService.toJson(andriodMessage).getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (Exception e) { log.error("send app message error",e); } try { Map<String,Object> ret = post(url, TOKEN_MAP,JsonService.toJson(iosMessage).getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (Exception e) { log.error("send app message error",e); } } private MsgCondition createTagCondition(String[] tags){ return new MsgCondition("tag", tags, 0); } private void addTag(Map<String,Object> msg,MsgCondition tagCondition){ MsgCondition[] mcs = (MsgCondition[]) msg.get("condition"); MsgCondition[] mcsn = new MsgCondition[mcs.length+1]; System.arraycopy(mcs,0,mcsn, 0,mcs.length); mcsn[mcs.length] = tagCondition; msg.put("condition", mcsn); } public void pushWithTag(String title,String content,Object payload,String[] tags){ String url = "https://restapi.getui.com/v1/"+this.appId+"/push_app"; String pl_str = JsonService.toJson(payload); Map<String,Object> andriodMessage = this.createAndriodMessage(title, content, pl_str); Map<String,Object> iosMessage = this.createIosMessage(title, content, pl_str); andriodMessage.put("requestid",this.allocateRequesstId()); iosMessage.put("requestid",this.allocateRequesstId()); MsgCondition tagC = this.createTagCondition(tags); addTag(andriodMessage, tagC); addTag(iosMessage, tagC); try { Map<String,Object> ret = post(url, TOKEN_MAP,JsonService.toJson(andriodMessage).getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (Exception e) { log.error("send app message error",e); } try { Map<String,Object> ret = post(url, TOKEN_MAP,JsonService.toJson(iosMessage).getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (Exception e) { log.error("send app message error",e); } } public void pushWithCid(String title,String content,Object payload,String cid){ String url = "https://restapi.getui.com/v1/"+this.appId+"/push_single"; String pl_str = JsonService.toJson(payload); Map<String,Object> androidMessage = this.createAndriodMessage(title, content, pl_str); Map<String,Object> iosMessage = this.createIosMessage(title, content, pl_str); androidMessage.put("requestid",this.allocateRequesstId()); androidMessage.put("cid",cid); iosMessage.put("requestid",this.allocateRequesstId()); iosMessage.put("cid",cid); // System.out.println(JsonService.toJson(androidMessage)); // System.out.println(JsonService.toJson(iosMessage)); try { Map<String,Object> ret = post(url, TOKEN_MAP,JsonService.toJson(androidMessage).getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (Exception e) { log.error("send app message error",e); } try { Map<String,Object> ret = post(url, TOKEN_MAP,JsonService.toJson(iosMessage).getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (Exception e) { log.error("send app message error",e); } } public void pushWithAlias(String title,String content,Object payload,String alias){ String url = "https://restapi.getui.com/v1/"+this.appId+"/push_single"; String pl_str = JsonService.toJson(payload); Map<String,Object> androidMessage = this.createAndriodMessage(title, content, pl_str); Map<String,Object> iosMessage = this.createIosMessage(title, content, pl_str); androidMessage.put("requestid",this.allocateRequesstId()); androidMessage.put("alias","A_"+alias); iosMessage.put("requestid",this.allocateRequesstId()); iosMessage.put("alias","I_"+alias); // System.out.println(JsonService.toJson(androidMessage)); // System.out.println(JsonService.toJson(iosMessage)); try { Map<String,Object> ret = post(url, TOKEN_MAP,JsonService.toJson(androidMessage).getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (Exception e) { log.error("send app message error",e); } try { Map<String,Object> ret = post(url, TOKEN_MAP,JsonService.toJson(iosMessage).getBytes(ConstData.UTF8)); this.checkResult(ret); } catch (Exception e) { log.error("send app message error",e); } } public static HttpURLConnection getConnection(String urlString) throws IOException { URL url = new URL(urlString); HttpURLConnection conn = null; conn = (HttpURLConnection) url.openConnection(); String protocal = url.getProtocol(); if ((protocal != null) && (protocal.equalsIgnoreCase("https"))) { try { HttpsURLConnection httpsConn = (HttpsURLConnection) conn; httpsConn.setSSLSocketFactory(getTrustAllSSLContext().getSocketFactory()); HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String arg0, SSLSession arg1) { return true; } }; httpsConn.setHostnameVerifier(hv); } catch (Exception e) { log.warn("init httpmanager error", e); throw new RuntimeException("init httpmanager error", e); } } return conn; } public static SSLContext getTrustAllSSLContext() throws Exception { TrustManager[] trustAllCerts = new TrustManager[1]; TrustManager trust = new CustomTrustManager(); trustAllCerts[0] = trust; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, null); return sc; } static class CustomTrustManager implements TrustManager, X509TrustManager { public X509Certificate[] getAcceptedIssuers() { return null; } public boolean isServerTrusted(X509Certificate[] certs) { return true; } public boolean isClientTrusted(X509Certificate[] certs) { return true; } public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { } public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { } } static { CONTENT_TYPE.put("Content-Type", "application/json"); TOKEN_MAP.putAll(CONTENT_TYPE); TOKEN_MAP.put("authtoken", "ef60d2aa2bc3193fc99a99ef43906cee70658156dfb41156acc35f7e7b7fb3dd"); ERR_MAP.put("no_msg", "没有消息体"); ERR_MAP.put("alias_error", "找不到别名"); ERR_MAP.put("black_ip", "黑名单ip"); ERR_MAP.put("sign_error", "鉴权失败"); ERR_MAP.put("pushnum_overlimit", "推送次数超限"); ERR_MAP.put("no_appid", "找不到appid"); ERR_MAP.put("no_user", "找不到对应用户"); ERR_MAP.put("too_frequent", "推送过于频繁"); ERR_MAP.put("sensitive_word", "有敏感词出现"); ERR_MAP.put("appid_notmatch", "appid与cid或者appkey不匹配"); ERR_MAP.put("not_auth", "用户没有鉴权"); ERR_MAP.put("black_appid", "黑名单app"); ERR_MAP.put("invalid_param", "参数检验不通过"); ERR_MAP.put("alias_notbind", "别名没有绑定cid"); ERR_MAP.put("tag_over_limit", "tag个数超限"); ERR_MAP.put("successed_online", "在线下发"); ERR_MAP.put("successed_offline", "离线下发"); ERR_MAP.put("taginvalid_or_noauth", "tag无效或者没有使用权限"); ERR_MAP.put("no_valid_push", "没有有效下发"); ERR_MAP.put("successed_ignore", "忽略非活跃用户"); ERR_MAP.put("no_taskid", "找不到taskid"); } public static void main(String[] args) throws Exception { PushService s = new PushService(); // s.buildToken(); // s.checkToken(); TOKEN_MAP.put("authtoken", "c3bbeb7aac006871f228d48e5da846933bfd2109e1d20fac3c8c0a3f3ccebd7d"); long l = System.currentTimeMillis(); //s.toApp("title_" + l, "content_" + l, "payload_" + l); s.pushWithAlias("title_" + l, "content_" + l, "payload_" + l,"A21F6D7BD4C549A1A2ABC415DE7701BD"); System.out.println(l); // s.applyBadge(1, "f293af1f1cc043185ee9d921b63c4807", "D380AD6865B61F4D179DBB208EE3C7268A672AB9821385050596608A186F6023"); // for(int i = 0 ;i < 100;++i){ // UUID uuid= UUID.randomUUID(); // System.out.println( "A"+Long.toString( // uuid.getLeastSignificantBits(),36)+"_"+Long.toString(uuid.getMostSignificantBits(), // 36)); // } } }