jiapeng лет назад: 8
Родитель
Сommit
d2d110c90e

+ 8 - 0
src/main/java/com/ekexiu/portal/job/TaskJob.java

@ -13,6 +13,7 @@ import org.jfw.util.bean.BeanFactory;
13 13
import org.jfw.util.context.JfwAppContext;
14 14

15 15
import com.ekexiu.portal.service.WeixinService;
16
import com.ekexiu.push.service.PushService;
16 17

17 18
@Bean
18 19
public class TaskJob implements AfterBeanFactory {
@ -28,6 +29,7 @@ public class TaskJob implements AfterBeanFactory {
28 29
		DictTaskJobEntry dtje = (DictTaskJobEntry) bf.getBean("com_ekexiu_portal_job_DictTaskJobEntry");
29 30
		HotKeyJobEntry hkje = (HotKeyJobEntry) bf.getBean("com_ekexiu_portal_job_HotKeyJobEntry");
30 31
		final WeixinService weixin =(WeixinService)bf.getBean("com_ekexiu_portal_service_WeixinService");
32
		final PushService pushService =(PushService)bf.getBean("com_ekexiu_push_service_PushService");
31 33
		
32 34
		long delayTime = tje.getDelayTime();
33 35
		long task = getTimeMillis(tje.getTaskTime());
@ -56,6 +58,12 @@ public class TaskJob implements AfterBeanFactory {
56 58
				weixin.refresh();
57 59
			}
58 60
		}, 0, weixin.getDelayTime(), TimeUnit.SECONDS);
61
		service.scheduleAtFixedRate(new Runnable() {
62
			@Override
63
			public void run() {
64
				pushService.refresh();				
65
			}
66
		}, 0, 2,TimeUnit.SECONDS);
59 67
	}
60 68
	private static long getTimeMillis(String time) {  
61 69
	    try {  

+ 303 - 0
src/main/java/com/ekexiu/push/service/PushService.java

@ -0,0 +1,303 @@
1
package com.ekexiu.push.service;
2

3
import java.io.IOException;
4
import java.io.InputStream;
5
import java.io.OutputStream;
6
import java.lang.reflect.Type;
7
import java.net.HttpURLConnection;
8
import java.net.URL;
9
import java.security.MessageDigest;
10
import java.security.cert.CertificateException;
11
import java.security.cert.X509Certificate;
12
import java.util.HashMap;
13
import java.util.Map;
14
import java.util.concurrent.ConcurrentHashMap;
15

16
import javax.net.ssl.HostnameVerifier;
17
import javax.net.ssl.HttpsURLConnection;
18
import javax.net.ssl.SSLContext;
19
import javax.net.ssl.SSLSession;
20
import javax.net.ssl.TrustManager;
21
import javax.net.ssl.X509TrustManager;
22

23
import org.jfw.apt.web.annotation.Path;
24
import org.jfw.apt.web.annotation.operate.Post;
25
import org.jfw.util.ConstData;
26
import org.jfw.util.io.IoUtil;
27
import org.jfw.util.json.JsonService;
28
import org.jfw.util.reflect.TypeReference;
29

30
@Path("/push")
31
public class PushService {
32
	private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(PushService.class);
33

34
	private static Type RES_TYPE = new TypeReference<Map<String, Object>>() {
35
	}.getType();
36

37
	private static Map<String, String> CONTENT_TYPE = new HashMap<String, String>();
38
	private static Map<String,String>  TOKEN_MAP = new ConcurrentHashMap<String,String>();
39
	private static Map<String, String> ERR_MAP = new HashMap<String, String>();
40

41
	final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
42
	// UiIGJTfKNR8oXb8apYdGh3
43
	private String secret = "UiIGJTfKNR8oXb8apYdGh3";
44
	private String appKey = "FnwUFkK2nt9BLgQ0XjtOl4";
45
	private String appId = "G3L3npt6LU92DZHkdNxuL4";
46
	private int timeout = 0;
47

48
	private String token = null;
49
	private long lastBuildTime = 0;
50

51
	public String getSecret() {
52
		return secret;
53
	}
54

55
	public void setSecret(String secret) {
56
		this.secret = secret;
57
	}
58

59
	public String getAppKey() {
60
		return appKey;
61
	}
62

63
	public void setAppKey(String appKey) {
64
		this.appKey = appKey;
65
	}
66

67
	public String getAppId() {
68
		return appId;
69
	}
70

71
	public void setAppId(String appId) {
72
		this.appId = appId;
73
	}
74

75
	public int getTimeout() {
76
		return timeout;
77
	}
78

79
	public void setTimeout(int timeout) {
80
		this.timeout = timeout;
81
	}
82

83
	private String buildSign(long flag) {
84
		String p = this.appKey + flag + this.secret;
85
		MessageDigest messageDigest;
86
		try {
87
			messageDigest = MessageDigest.getInstance("SHA-256");
88
			messageDigest.update(p.getBytes("UTF-8"));
89
			StringBuilder sb = new StringBuilder();
90
			for (byte b : messageDigest.digest()) {
91
				sb.append(digits[(b & 0xf0) >> 4]);
92
				sb.append(digits[b & 0xf]);
93
			}
94
			return sb.toString();
95
		} catch (Exception e) {
96
			throw new RuntimeException("jdk unsupported sh256???????????", e);
97
		}
98
	}
99

100
	private void checkResult(Map<String, Object> ret) {
101
		Object obj = ret.get("result");
102
		if ("ok".equals(obj))
103
			return;
104
		String errMsg = null;
105
		errMsg = ERR_MAP.get(obj);
106
		if (errMsg == null)
107
			errMsg = "其他错误";
108
		log.error("调用用个推restApi,返回结果错误:" + obj + ":" + errMsg);
109
		throw new RuntimeException("调用用个推restApi,返回结果错误:" + obj + ":" + errMsg);
110
	}
111
	
112
	private void checkToken()
113
	{
114
		if(this.token==null){
115
			log.error("token is null");
116
			throw new RuntimeException("token is null");
117
		}
118
	}
119

120
	private void buildToken() {
121
		long time = System.currentTimeMillis();
122
		String sign = this.buildSign(time);
123
		StringBuilder sb = new StringBuilder();
124
		sb.append("{\"sign\":\"").append(sign).append("\",\"timestamp\":\"").append(time).append("\",\"appkey\":\"").append(this.appKey).append("\"}");
125
		try {
126
			Map<String, Object> ret = post("https://restapi.getui.com/v1/" + this.appId + "/auth_sign", CONTENT_TYPE, sb.toString().getBytes(ConstData.UTF8));
127
			this.checkResult(ret);
128
			String otoken = (String) ret.get("auth_token");
129
			if (otoken == null) {
130
				throw new RuntimeException("返回token is null");
131
			}
132
			this.token = otoken;
133
			this.lastBuildTime = System.currentTimeMillis();
134
			TOKEN_MAP.put("authtoken", this.token);
135
		} catch (Exception e) {
136
			this.token = null;
137
			log.error("build token error", e);
138
		}
139
	}
140

141
	public void refresh(){
142
		if((this.token!=null)  && ((System.currentTimeMillis() -  this.lastBuildTime) < (24*60 *60*1000-5000))){
143
			return ;
144
		}
145
		this.buildToken();
146
	}
147
	
148
	public Map<String, Object> post(String url, Map<String, String> header, byte[] data) throws IOException {
149
		HttpURLConnection connection = getConnection(url);
150
		try {
151
			connection.setRequestMethod("POST");
152
			connection.setUseCaches(false);
153
			for (Map.Entry<String, String> entry : header.entrySet()) {
154
				connection.setRequestProperty(entry.getKey(), entry.getValue());
155
			}
156
			connection.setDoOutput(true);
157
			connection.setDoInput(true);
158
			if (this.timeout > 0) {
159
				connection.setConnectTimeout(this.timeout);
160
				connection.setReadTimeout(this.timeout);
161
			}
162
			connection.setFixedLengthStreamingMode(data.length);
163
			OutputStream out = connection.getOutputStream();
164
			try {
165
				out.write(data);
166
			} finally {
167
				out.close();
168
			}
169
			int code = connection.getResponseCode();
170

171
			if (code == 200) {
172
				InputStream in = null;
173
				byte[] resData = null;
174
				try {
175
					in = connection.getInputStream();
176
					resData = IoUtil.readStream(in, false);
177
				} catch (IOException e) {
178
					log.error("Error read http response stream,url:" + url, e);
179
					throw new IOException("Error read http response stream");
180
				} finally {
181
					if (null != in)
182
						IoUtil.close(in);
183
				}
184
				try {
185
					return JsonService.fromJson(new String(resData, ConstData.UTF8), RES_TYPE);
186
				} catch (Exception e) {
187
					log.error("invalid response data,url:" + url, e);
188
					throw new IOException("invalid response data", e);
189
				}
190
			}
191
			log.error("Error http reponse status:" + code + ",url:" + url);
192
			throw new IOException("Error http reponse status:" + code);
193
		} finally {
194
			connection.disconnect();
195
		}
196
	}
197

198
	
199
	
200
	@Path("/bindAlias")
201
	@Post
202
	public boolean bindAlias(String alias,String cid){
203
		String url = "https://restapi.getui.com/v1/"+this.appId+"/bind_alias";
204
		StringBuilder sb = new StringBuilder();
205
		sb.append("{\"alias_list\" : [{\"cid\":\"").append(cid).append("\",\"alias\":\"").append(alias).append("\" }]}");
206
		try {
207
			Map<String,Object> ret = post(url, TOKEN_MAP,sb.toString().getBytes(ConstData.UTF8));
208
			this.checkResult(ret);
209
			return true;
210
		} catch (IOException e) {
211
			log.error("bind alias error[cid:"+cid+",alias:"+alias+"]",e);
212
			return false;
213
		}
214
	}
215
	
216
	
217
	
218
	public static HttpURLConnection getConnection(String urlString) throws IOException {
219
		URL url = new URL(urlString);
220
		HttpURLConnection conn = null;
221
		conn = (HttpURLConnection) url.openConnection();
222
		String protocal = url.getProtocol();
223
		if ((protocal != null) && (protocal.equalsIgnoreCase("https"))) {
224
			try {
225
				HttpsURLConnection httpsConn = (HttpsURLConnection) conn;
226
				httpsConn.setSSLSocketFactory(getTrustAllSSLContext().getSocketFactory());
227

228
				HostnameVerifier hv = new HostnameVerifier() {
229
					public boolean verify(String arg0, SSLSession arg1) {
230
						return true;
231
					}
232
				};
233
				httpsConn.setHostnameVerifier(hv);
234
			} catch (Exception e) {
235
				log.warn("init httpmanager error", e);
236
				throw new RuntimeException("init httpmanager error", e);
237
			}
238
		}
239
		return conn;
240
	}
241

242
	public static SSLContext getTrustAllSSLContext() throws Exception {
243
		TrustManager[] trustAllCerts = new TrustManager[1];
244
		TrustManager trust = new CustomTrustManager();
245
		trustAllCerts[0] = trust;
246
		SSLContext sc = SSLContext.getInstance("SSL");
247
		sc.init(null, trustAllCerts, null);
248
		return sc;
249
	}
250

251
	static class CustomTrustManager implements TrustManager, X509TrustManager {
252
		public X509Certificate[] getAcceptedIssuers() {
253
			return null;
254
		}
255

256
		public boolean isServerTrusted(X509Certificate[] certs) {
257
			return true;
258
		}
259

260
		public boolean isClientTrusted(X509Certificate[] certs) {
261
			return true;
262
		}
263

264
		public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
265
		}
266

267
		public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
268
		}
269
	}
270

271
	static {
272
		CONTENT_TYPE.put("Content-Type", "application/json");
273
		TOKEN_MAP.putAll(CONTENT_TYPE);
274

275
		ERR_MAP.put("no_msg", "没有消息体");
276
		ERR_MAP.put("alias_error", "找不到别名");
277
		ERR_MAP.put("black_ip", "黑名单ip");
278
		ERR_MAP.put("sign_error", "鉴权失败");
279
		ERR_MAP.put("pushnum_overlimit", "推送次数超限");
280
		ERR_MAP.put("no_appid", "找不到appid");
281
		ERR_MAP.put("no_user", "找不到对应用户");
282
		ERR_MAP.put("too_frequent", "推送过于频繁");
283
		ERR_MAP.put("sensitive_word", "有敏感词出现");
284
		ERR_MAP.put("appid_notmatch", "appid与cid或者appkey不匹配");
285
		ERR_MAP.put("not_auth", "用户没有鉴权");
286
		ERR_MAP.put("black_appid", "黑名单app");
287
		ERR_MAP.put("invalid_param", "参数检验不通过");
288
		ERR_MAP.put("alias_notbind", "别名没有绑定cid");
289
		ERR_MAP.put("tag_over_limit", "tag个数超限");
290
		ERR_MAP.put("successed_online", "在线下发");
291
		ERR_MAP.put("successed_offline", "离线下发");
292
		ERR_MAP.put("taginvalid_or_noauth", "tag无效或者没有使用权限");
293
		ERR_MAP.put("no_valid_push", "没有有效下发");
294
		ERR_MAP.put("successed_ignore", "忽略非活跃用户");
295
		ERR_MAP.put("no_taskid", "找不到taskid");
296
	}
297

298
	public static void main(String[] args) throws Exception {
299
		PushService s = new PushService();
300
		s.buildToken();
301
		s.checkToken();
302
	}
303
}