SpringBoot自搭建APNS服务
描述
前段时间研究了自搭建APNS服务,在网上也找了很长一段时间,很少有Java直接调用APNS服务的方式,有的很老了也没有用起来,自己总结下SpringBoot自搭建APNS服务。
结果显示
代码展示
一、创建ApnsClient
根据P8证书或者P12证书创建ApnsClient对象
/**
* 创建客户端
*/
public ApnsClient createApnsClient() throws Exception {
String p8_path = getCerPath() + "AuthKey.p8";
String p12_dis_path = getCerPath() + "Dis.p12";
String p12_dev_path = getCerPath() + "Dev.p12";
String config_path = getCerPath() + "apns_config.json";
if (!FileUtil.isExistFile(config_path)) {
throw new Exception("apns_config配置文件不存在!");
}
if (currentProductStatus) { //生产环境
if (FileUtil.isExistFile(p8_path)) { // P8发送
String configContent = FileUtil.readJsonFile(config_path);
JSONObject json = (JSONObject) JSONObject.parse(configContent);
if (StringUtils.isEmpty(json.getString("TeamId")) || StringUtils.isEmpty(json.getString("KeyId"))) {
throw new Exception("p8配置参数不对!");
}
apnsClient = new ApnsClientBuilder()
.setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
.setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File(p8_path),
json.getString("TeamId"), json.getString("KeyId")))
.build();
} else if (FileUtil.isExistFile(p12_dis_path)) { // P12发送 生产环境
String configContent = FileUtil.readJsonFile(config_path);
JSONObject json = (JSONObject) JSONObject.parse(configContent);
if (StringUtils.isEmpty(json.getString("DisP12Pwd"))) {
throw new Exception("p12密码没有配置!");
}
apnsClient = new ApnsClientBuilder()
.setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
.setClientCredentials(new File(p12_dis_path), json.getString("DisP12Pwd"))
.build();
} else {
throw new Exception("apnsClient创建失败,没有找到合适证书环境创建");
}
} else { //测试环境
if (FileUtil.isExistFile(p8_path)) { // P8发送
String configContent = FileUtil.readJsonFile(config_path);
JSONObject json = (JSONObject) JSONObject.parse(configContent);
if (StringUtils.isEmpty(json.getString("TeamId")) || StringUtils.isEmpty(json.getString("KeyId"))) {
throw new Exception("p8配置参数不对!");
}
apnsClient = new ApnsClientBuilder()
.setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
.setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File(p8_path),
json.getString("TeamId"), json.getString("KeyId")))
.build();
} else if (FileUtil.isExistFile(p12_dev_path)) { // P12发送 测试环境
String configContent = FileUtil.readJsonFile(config_path);
JSONObject json = (JSONObject) JSONObject.parse(configContent);
if (StringUtils.isEmpty(json.getString("DevP12Pwd"))) {
throw new Exception("p12密码没有配置!");
}
apnsClient = new ApnsClientBuilder()
.setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
.setClientCredentials(new File(p12_dev_path), json.getString("DevP12Pwd"))
.build();
} else {
throw new Exception("apnsClient创建失败,没有找到合适证书环境创建");
}
}
return apnsClient;
}
二、发送推送通知
向指定设备发送推送通知
/**
* 发送通知
*/
public JSONObject pushNotification(JSONObject params) throws Exception {
final ApnsPayloadBuilder payloadBuilder = new SimpleApnsPayloadBuilder();
HashMap notification = (HashMap) params.get("notification");
HashMap aps = (HashMap) notification.get("aps");
JSONObject backJO = new JSONObject();
if (aps != null) { // apns通知
HashMap alert = (HashMap) aps.get("alert");
String title = (String) alert.get("title");
String subtitle = (String) alert.get("subtitle");
String body = (String) alert.get("body");
String badge = (String) aps.get("badge");
String sound = (String) aps.get("sound");
if (!StringUtils.isEmpty(title)) {
payloadBuilder.setAlertTitle(title);
}
if (!StringUtils.isEmpty(subtitle)) {
payloadBuilder.setAlertSubtitle(subtitle);
}
if (!StringUtils.isEmpty(body)) {
payloadBuilder.setAlertBody(body);
}
if (!StringUtils.isEmpty(badge)) {
payloadBuilder.setBadgeNumber(Integer.parseInt(badge));
}
if (!StringUtils.isEmpty(sound)) {
payloadBuilder.setSound(sound);
}
HashMap
if (custommap != null) {
for (Map.Entry
payloadBuilder.addCustomProperty(entry.getKey(), entry.getValue());
}
}
final String payload = payloadBuilder.build();
ArrayList
String appId = params.getString("appId");
List
for (int i = 0; i < device_tokens.size(); i++) {
String device_token = device_tokens.get(i);
final String token = TokenUtil.sanitizeTokenString(device_token);
ApnsPushNotification pushNotification = new SimpleApnsPushNotification(token, appId, payload);
boolean productStatus = params.get("product") == null ? true : params.getBoolean("product");
if (apnsClient == null || productStatus != currentProductStatus) {
currentProductStatus = productStatus;
apnsClient = null;
createApnsClient();
}
// 开始推送
final PushNotificationFuture
sendNotificationFuture =
apnsClient.sendNotification(pushNotification);
final PushNotificationResponse
sendNotificationFuture.get();
JSONObject pushParam = new JSONObject();
String id = UUID.randomUUID().toString();
pushParam.put("id", id);
pushParam.put("content", notification.toString());
pushParam.put("device_token", device_token);
pushParam.put("type", "2"); //ios
pushParam.put("status", "1");
JSONObject responseObj = new JSONObject();
responseObj.put("device_token", device_token);
responseObj.put("id", id);
if (pushNotificationResponse.isAccepted()) { //成功发送
pushParam.put("push_status", "1");
pushParam.put("reason", "");
responseObj.put("push_status", "1");
} else {
pushParam.put("push_status", "2");
pushParam.put("reason", "错误码 :" + pushNotificationResponse.getStatusCode() + ";拒绝原因:" + pushNotificationResponse.getRejectionReason().toString());
responseObj.put("push_status", "2");
responseObj.put("reason", "错误码 :" + pushNotificationResponse.getStatusCode() + ";拒绝原因:" + pushNotificationResponse.getRejectionReason().toString());
System.out.println("失败发送了");
}
responseList.add(responseObj);
pushDao.addPush(pushParam);
}
backJO.put("code", "200");
backJO.put("msg", "执行完");
backJO.put("responseList", responseList);
} else { //安卓通知
throw new Exception("暂时仅支持APNS推送通知!");
}
return backJO;
}
依赖JAR包
POM 依赖的JAR包