极光推送官网的web推送页面

因为是对接它的api,所以我参照这这个样式实现了一个,效果如下:

  • 定时任务推送界面,可定制。实现了推送一次和每日定时推送,如果再扩展的话有每周、每月的功能,只是没有这个业务需求。
  • 普通的单次消息推送

极光的官方文档地址:https://docs.jiguang.cn/jpush/server/push/rest_api_v3_push

如果实在没看懂的话,也可以到官方的代码仓库把demo下下来看,有很多案例。地址:https://github.com/jpush/jpush-api-java-client.git。首先我们需要创建自己的应用程序,会给出appKeymasterSecret

下面贴一下我这边的关键代码,业务代码就省略了,具体可以根据自己的业务来实现

首先是引入jar包,由于我的是springcloud项目,所以其他的引用就省略了。
pom.xml

<dependency><groupId>cn.jpush.api</groupId><artifactId>jpush-client</artifactId><version>3.6.6</version>
</dependency>

如果报错的话,可能还需要引入以下依赖

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.3</version><scope>compile</scope>
</dependency>
<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.6.Final</version><scope>compile</scope>
</dependency>
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.3</version>
</dependency>

通用的常量 Constants,用来判断是否设置为生产环境

/*** 生产环境标识*/
public static final String PROD_ENV = "prod";

极光推送配置的读取,使用的是nacos作为配置中心,当然也可以写到本地
JPushConfig

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** 极光推送配置* @author: * @date: 2023/1/4*/
@Data
@Component
@ConfigurationProperties(prefix = "jpush.push")
public class JPushConfig {/*** AppKey*/private String appKey;/*** 密钥*/private String masterSecret;/*** 离线消息保留时长(秒)*/private int liveTime;/*** 回调url*/private String callback;
}

极光推送的常量
JPushConstants

package com.xx.config;/*** JPush常量* @author: * @date: 2023/1/4*/
public class JPushConstants {/** 任务类型 *//** 普通类型 */public static final String TASK_TYPE_COMMON = "common";/** 定时任务 */public static final String TASK_TYPE_SCHEDULE = "schedule";/** 指定推送平台 */public static final String PLATFORM_ALL = "all";public static final String PLATFORM_ANDROID = "android";public static final String PLATFORM_IOS = "ios";public static final String PLATFORM_WINPHONE = "winphone";public static final String PLATFORM_ANDROID_IOS = "android_ios";public static final String PLATFORM_ANDROID_WINPHONE = "android_winphone";public static final String PLATFORM_IOS_WINPHONE = "ios_winphone";/** 指定推送目标 *//** 广播推送(全部设备) */public static final String AUDIENCE_ALL = "all";/** 标签推送,多个标签之间是 OR 的关系,即取并集。一次推送最多 20 个。 */public static final String AUDIENCE_TAG_AND = "tag_and";/** 标签推送,多个标签之间是 AND 关系,即取交集。一次推送最多 20 个。 */public static final String AUDIENCE_TAG_NOT = "tag_not";/** 标签推送,多个标签之间,先取多标签的并集,再对该结果取补集。一次推送最多 20 个。 */public static final String AUDIENCE_TAG = "tag";/** 别名推送,多个别名之间是 OR 关系,即取并集。一次推送最多 1000 个。 */public static final String AUDIENCE_ALIAS = "alias";/** 注册ID推送,多个注册ID之间是 OR 关系,即取并集。一次推送最多 1000 个。 */public static final String AUDIENCE_REGISTRATION_ID = "registration_id";/** 用户分群ID推送,定义为数组,但目前限制一次只能推送一个。 */public static final String AUDIENCE_SEGMENT = "segment";/** A/B Test ID推送,定义为数组,但目前限制是一次只能推送一个。 */public static final String AUDIENCE_ABTEST = "abtest";/** 指定通知对象 */public static final String NOTIFICATION_ANDROID = "android";public static final String NOTIFICATION_IOS = "ios";public static final String NOTIFICATION_ANDROID_IOS = "android_ios";public static final String NOTIFICATION_WINPHONE = "winphone";
}

从前端传入的附加字段Bean
Extra

@Data
public class Extra {String label;String value;
}

从前端传入的推送消息Bean,下面出现的SysMessage结构与其类似,故省略。
PushBean

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;/*** @author: * @date: 2023/1/4*/
@Data
public class PushBean {/*** 主键*/private Long id;/*** 必填, 通知内容, 内容可以为空字符串,则表示不展示到通知栏*/@NotBlankprivate String content;/*** 可选, 附加信息, 供业务使用*/private List<Extra> extras;/*** android专用 可选, 通知标题,如果指定了,则通知里原来展示 App名称的地方,将展示成这个字段*/private String title;/*** 指定推送平台*/private String platform;/*** 指定推送范围*/private String audience;/*** 指定推送目标*/private List<String> audienceValues;/*** 任务类型: common(普通类型)、schedule(定时任务)*/private String taskType;/*** 定时推送*/private String time;/*** 请求参数*/@JsonInclude(JsonInclude.Include.NON_EMPTY)private Map<String, String> params;
}

极光推送的关键代码,这里包含了推送业务和数据库的存储、读取(代码省略)。
JPushService

import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.ServiceHelper;
import cn.jiguang.common.connection.NativeHttpClient;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jiguang.common.resp.DefaultResult;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.*;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import cn.jpush.api.report.MessagesResult;
import cn.jpush.api.report.ReceivedsResult;
import cn.jpush.api.schedule.ScheduleMsgIdsResult;
import cn.jpush.api.schedule.ScheduleResult;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.gson.JsonObject;
import com.xx.common.Constants;
import com.xx.exception.ServiceException;
import com.xx.utils.id.UUID;
import com.xx.utils.SecurityUtils;
import com.xx.config.JPushConfig;
import com.xx.config.JPushConstants;
import com.xx.domain.Extra;
import com.xx.domain.PushBean;
import com.xx.domain.SysMessage;
import com.xx.domain.SysMessageTarget;
import com.xx.mapper.SysMessageMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** 极光推送* 封装第三方API** @author: * @date: 2023/1/4*/
@Service
@Slf4j
public class JPushService {@Value("${spring.profiles.active}")private String profile;/*** 一次推送最大数量 (极光限制1000)*/private static final int MAX_SIZE = 1000;@Autowiredprivate JPushConfig config;@Autowiredprivate SysMessageMapper messageMapper;/*** 向所有用户推送push消息** @param pushBean* @return boolean*/public boolean sendPush(PushBean pushBean) {SysMessage message = genSysMessage(pushBean);// 默认全部用户pushBean.setAudience(JPushConstants.AUDIENCE_ALL);PushPayload payload = buildPushPayload(pushBean, null, message.getCode());message.setSendNo(payload.getSendno());message.setPayload(payload.toString());boolean result;if (JPushConstants.TASK_TYPE_COMMON.equals(pushBean.getTaskType())) {result = sendPush(payload, message);} else {//定时推送String time = pushBean.getTime();Map<String, String> params = pushBean.getParams();result = createSchedule(params, time, payload, message);}if (pushBean.getId() != null) {messageMapper.updateMessage(message);} else {messageMapper.insertMessage(message);}return result;}/*** 分批推送push消息** @param pushBean* @param audienceValues* @return boolean*/public boolean sendPush(PushBean pushBean, List<String> audienceValues) {SysMessage message = genSysMessage(pushBean);boolean result = false;//由于jpush接口最大限制1000,需要分批推送List<List<String>> partition = Lists.partition(audienceValues, MAX_SIZE);// 推送push消息for (List<String> values : partition) {// 构建推送对象PushPayload payload = buildPushPayload(pushBean, values, message.getCode());message.setPayload(payload.toString());if (StringUtils.isBlank(message.getSendNo())) {message.setSendNo(payload.getSendno());}if (JPushConstants.TASK_TYPE_COMMON.equals(pushBean.getTaskType())) {result = sendPush(payload, message);} else {//定时推送String time = pushBean.getTime();Map<String, String> params = pushBean.getParams();result = createSchedule(params, time, payload, message);}if (result) {if (pushBean.getId() != null) {//如果是修改,则把历史数据全部删除,然后再重新插入SysMessage sysMessage = messageMapper.getMessageById(pushBean.getId());messageMapper.deleteMessageTargetByCode(sysMessage.getCode());}// 批量保存指定用户的IDList<SysMessageTarget> list = new ArrayList<>(MAX_SIZE);values.forEach(item -> {SysMessageTarget target = new SysMessageTarget();target.setCode(message.getCode());//未读状态target.setStatus(0);target.setTarget(item);list.add(target);});messageMapper.batchAddMessageTarget(list);}}if (pushBean.getId() != null) {messageMapper.updateMessage(message);} else {messageMapper.insertMessage(message);}return result;}/*** 定时推送push消息** @param time    定时* @param payload 推送对象* @return int*/public boolean createSchedule(Map<String, String> params, String time, PushPayload payload, SysMessage message) {log.info("开始定时推送push消息:{}", payload);JPushClient jpushClient = buildJPushClient();try {ScheduleResult result;if (params == null || params.isEmpty()) {// 定时推送String name = "schedule_push_task";result = jpushClient.createSingleSchedule(name, time, payload, config.getMasterSecret(), config.getAppKey());} else {// 每日定时推送String name = "daily_schedule_push_task";// 开始日期String start = params.get("start");// 结束日期String end = params.get("end");message.setStart(start);message.setEnd(end);result = jpushClient.createDailySchedule(name, start, end, time, payload, config.getMasterSecret(), config.getAppKey());}log.info("定时推送请求完成: {}", result);message.setTime(time);message.setScheduleId(result.getSchedule_id());message.setEnabled(result.isResultOK());message.setStatus(result.isResultOK() ? 0 : 1);return result.isResultOK();} catch (APIConnectionException e) {log.error("Connection error. Should retry later. ", e);throw new ServiceException(e.getMessage());} catch (APIRequestException e) {log.error("Error response from JPush server. Should review and fix it. ", e);log.info("Error Code: " + e.getErrorCode());throw new ServiceException(e.getErrorMessage());}}/*** 推送push消息** @param payload 推送对象* @return int*/public boolean sendPush(PushPayload payload, SysMessage message) {log.info("开始推送push消息:{}", payload);JPushClient jpushClient = buildJPushClient();try {PushResult result = jpushClient.sendPush(payload);log.info("推送请求完成: {}", result);message.setMsgId(result.msg_id + "");message.setStatus(result.isResultOK() ? 0 : 1);return result.isResultOK();} catch (APIConnectionException e) {log.error("Connection error. Should retry later. ", e);throw new ServiceException(e.getMessage());} catch (APIRequestException e) {log.error("Error response from JPush server. Should review and fix it. {}", e.getErrorMessage());log.info("Error Code: " + e.getStatus());throw new ServiceException(e.getErrorMessage());}}/*** 生成JpushClient** @return*/private JPushClient buildJPushClient() {ClientConfig clientConfig = ClientConfig.getInstance();// ClientConfig.getInstance().setPushHostName("https://api.jpush.cn/v3/push");// ClientConfig.getInstance().setPushHostName("https://bjapi.push.jiguang.cn");clientConfig.setMaxRetryTimes(5);// 10 secondsclientConfig.setConnectionTimeout(10 * 1000);// JPush server supports SSLv3, TLSv1, TLSv1.1, TLSv1.2clientConfig.setSSLVersion("TLSv1.2");String authCode = ServiceHelper.getBasicAuthorization(config.getAppKey(), config.getMasterSecret());NativeHttpClient httpClient = new NativeHttpClient(authCode, null, clientConfig);JPushClient jpushClient = new JPushClient(config.getMasterSecret(), config.getAppKey(), null, clientConfig);jpushClient.getPushClient().setHttpClient(httpClient);return jpushClient;}/*** 构建推送对象** @param pushBean 参数* @return PushPayload*/private PushPayload buildPushPayload(PushBean pushBean, List<String> audienceValues, String code) {List<Extra> extrasArr = pushBean.getExtras();Map<String, String> extras = CollectionUtils.isEmpty(extrasArr) ? null : extrasArr.stream().collect(Collectors.toMap(Extra::getLabel, Extra::getValue));return PushPayload.newBuilder()// Platform指定推送平台.setPlatform(buildPlatform(pushBean.getPlatform()))// Audience指定推送目标.setAudience(buildAudience(pushBean.getAudience(), audienceValues))// Notification推送通知内容体.setNotification(buildNotification(pushBean, extras))// 构建回调信息.addCustom("callback", buildCallback(config.getCallback(), code))// Message推送通知内容体.setMessage(buildMessage(pushBean.getContent(), extras))// 应用内提醒,当用户前台运行 APP 时,会通过应用内消息的方式展示通知栏消息内容.setInappMessage(InappMessage.newBuilder().setInappMessage(true).build())// Options推送参数,设置离线消息保留时长.setOptions(Options.newBuilder()//推送当前用户不在线时,为该用户保留多长时间的离线消息,以便其上线时再次推送。默认 86400 (1 天).setTimeToLive(config.getLiveTime())//该字段仅对 iOS 的 Notification 有效,  true:表示推送生产环境。false:表示推送开发环境, 默认.setApnsProduction(Constants.PROD_ENV.equals(profile))//API 调用标识//.setSendno().build()).build();}/*** 构建通知内容体** @param pushBean 通知* @param extras   扩展字段* @return Notification*/private Notification buildNotification(PushBean pushBean, Map<String, String> extras) {Notification.Builder notification = Notification.newBuilder()// alert通知,推送到Platform指定的多个平台.setAlert(pushBean.getContent())// 构建Android平台上的通知结构.addPlatformNotification(androidNotificationBuilder(pushBean, extras))// 构建iOS平台上的通知结构.addPlatformNotification(iosNotificationBuilder(pushBean, extras));return notification.build();}/*** 构建通知内容体** @param message 通知内容* @param extras  扩展字段* @return Notification*/private Message buildMessage(String message, Map<String, String> extras) {if (extras == null || extras.isEmpty()) {return Message.newBuilder().setMsgContent(message).build();}return Message.newBuilder().setMsgContent(message).addExtras(extras).build();}/*** 处理附加信息** @param extras* @return*/private IosNotification iosNotificationBuilder(PushBean pushBean, Map<String, String> extras) {if (extras == null || extras.isEmpty()) {return IosNotification.newBuilder().setAlert(pushBean.getContent()).incrBadge(1).build();}return IosNotification.newBuilder().setAlert(pushBean.getContent())//通知扩展,说明是支持 iOS 10 的 UNNotificationServiceExtension//.setMutableContent(true).incrBadge(1)// 这个 key(my-attachment)值,需要与客户端的值对应,客户端工程拿到 key 值对应的 url 图标加载出来// .addExtra("my-attachment","https://raw.githubusercontent.com/Tikon/imgRepo/master/ic_launcher.png").addExtras(extras).build();}/*** 处理附加信息** @param extras* @return*/private AndroidNotification androidNotificationBuilder(PushBean pushBean, Map<String, String> extras) {String title = pushBean.getTitle();String msg = pushBean.getContent();//文本条目通知栏样式JsonObject inbox = new JsonObject();inbox.addProperty("key", "value");//跳转路径,应用首页JsonObject intent = new JsonObject();intent.addProperty("url", "intent:#Intent;action=android.intent.action.MAIN;end");if (extras == null || extras.isEmpty()) {return AndroidNotification.newBuilder()//通知内容.setAlert(msg)//通知提醒方式, 可选范围为 -1~7 ,默认-1, 即0111二进制,左数第二位代表 light,第三位代表 vibrate,第四位代表 sound。 0:不生效,1:生效.setAlertType(-1)//通知标题.setTitle(title)//通知栏展示优先级,默认为 0,范围为 -2~2.setPriority(0)//通知栏样式类型,默认为 0, 1-bigText; 2-Inbox; 3-bigPicture//.setStyle(3)//大文本通知栏样式,style=1时生效//.setBigText(msg)//文本条目通知栏样式,style=2时生效,json 的每个 key 对应的 value 会被当作文本条目逐条展示//.setInbox(inbox)//大图片通知栏样式,style=3时生效//.setBigPicPath("")//通知栏大图标//.setLargeIcon("")//通知栏小图标//.setSmallIconUri("")//指定跳转页面,三种类型:// 1. 跳转到目标页: intent:#Intent;action=action 路径;component= 包名 /Activity 全名;end      (OPPO 和 FCM 通道必须传 "action 路径", 其他厂商必须传 "Activity 全名", 否则将出现对应厂商无法跳转问题)// 2. 跳转到deeplink地址: scheme://test?key1=val1&key2=val2// 3. 应用首页: intent:#Intent;action=android.intent.action.MAIN;end  (固定为此地址)//.setIntent(intent)//通知栏样式 ID.setBuilderId(2)//定时展示开始时间(yyyy-MM-dd HH:mm:ss),默认立即展示//.setShowBeginTime("").build();}return AndroidNotification.newBuilder()//通知内容.setAlert(msg)//通知提醒方式, 可选范围为 -1~7 ,默认-1, 即0111二进制,左数第二位代表 light,第三位代表 vibrate,第四位代表 sound。 0:不生效,1:生效.setAlertType(-1)//通知标题.setTitle(title)//通知栏展示优先级,默认为 0,范围为 -2~2.setPriority(0)//通知栏样式类型,默认为 0, 1-bigText; 2-Inbox; 3-bigPicture//.setStyle(3)//大文本通知栏样式,style=1时生效//.setBigText(msg)//文本条目通知栏样式,style=2时生效,json 的每个 key 对应的 value 会被当作文本条目逐条展示//.setInbox(inbox)//大图片通知栏样式,style=3时生效//.setBigPicPath("https://lmg.jj20.com/up/allimg/1114/040221103339/210402103339-10-1200.jpg")//通知栏大图标//.setLargeIcon("")//通知栏小图标//.setSmallIconUri("")//指定跳转页面,三种类型:// 1. 跳转到目标页: intent:#Intent;action=action 路径;component= 包名 /Activity 全名;end      (OPPO 和 FCM 通道必须传 "action 路径", 其他厂商必须传 "Activity 全名", 否则将出现对应厂商无法跳转问题)// 2. 跳转到deeplink地址: scheme://test?key1=val1&key2=val2// 3. 应用首页: intent:#Intent;action=android.intent.action.MAIN;end  (固定为此地址)//.setIntent(intent)//通知栏样式 ID.setBuilderId(2)//定时展示开始时间(yyyy-MM-dd HH:mm:ss),默认立即展示//.setShowBeginTime("")//扩展字段.addExtras(extras).build();}/*** 构建推送平台** @param platform 指定推送平台* @return Platform*/private Platform buildPlatform(String platform) {switch (platform) {case JPushConstants.PLATFORM_ANDROID:return Platform.android();case JPushConstants.PLATFORM_IOS:return Platform.ios();case JPushConstants.PLATFORM_WINPHONE:return Platform.winphone();case JPushConstants.PLATFORM_ANDROID_IOS:return Platform.android_ios();case JPushConstants.PLATFORM_ANDROID_WINPHONE:return Platform.android_winphone();case JPushConstants.PLATFORM_IOS_WINPHONE:return Platform.ios_winphone();default:return Platform.all();}}/*** 构建推送目标** @param audience       指定推送范围* @param audienceValues 指定推送目标* @return Audience*/private Audience buildAudience(String audience, List<String> audienceValues) {switch (audience) {case JPushConstants.AUDIENCE_TAG:return Audience.tag(audienceValues);case JPushConstants.AUDIENCE_TAG_AND:return Audience.tag_and(audienceValues);case JPushConstants.AUDIENCE_TAG_NOT:return Audience.tag_not(audienceValues);case JPushConstants.AUDIENCE_ALIAS:return Audience.alias(audienceValues);case JPushConstants.AUDIENCE_REGISTRATION_ID:return Audience.registrationId(audienceValues);case JPushConstants.AUDIENCE_SEGMENT:return Audience.segment(audienceValues);case JPushConstants.AUDIENCE_ABTEST:return Audience.abTest(audienceValues);default:return Audience.all();}}/*** 构建回调信息** @return*/private JsonObject buildCallback(String url, String code) {JsonObject callback = new JsonObject();//回调urlcallback.addProperty("url", url);JsonObject params = new JsonObject();//唯一标识params.addProperty("code", code);callback.add("params", params);// 可选,1: 送达回执, 2: 点击回执, 3: 送达和点击回执, 8: 推送成功回执, 9: 成功和送达回执, 10: 成功和点击回执, 11: 成功和送达以及点击回执callback.addProperty("type", 3);return callback;}/*** 装配SysMessage** @param pushBean 前端传的参数* @return SysMessage*/private SysMessage genSysMessage(PushBean pushBean) {SysMessage message = new SysMessage();if (pushBean.getId() != null) {message = messageMapper.getMessageById(pushBean.getId());} else {message.setCode(UUID.fastUUID().toString(true));}message.setAudience(pushBean.getAudience());message.setContent(pushBean.getContent());message.setTitle(pushBean.getTitle());message.setPlatform(pushBean.getPlatform());message.setType("notification");message.setTaskType(pushBean.getTaskType());if (!CollectionUtils.isEmpty(pushBean.getExtras())) {message.setExtras(JSONObject.toJSONString(pushBean.getExtras()));}message.setCreateBy(SecurityUtils.getUsername());return message;}/*** 撤回推送消息** @param msgId* @return* @throws APIConnectionException* @throws APIRequestException*/public boolean delMessage(String msgId) {try {JPushClient jpushClient = buildJPushClient();DefaultResult result = jpushClient.deletePush(msgId);log.info("撤回推送消息请求完成: {}", result);return result.isResultOK();} catch (APIConnectionException e) {log.error("Connection error. Should retry later. ", e);throw new ServiceException(e.getMessage());} catch (APIRequestException e) {log.error("Error response from JPush server. Should review and fix it. {}", e.getErrorMessage());log.info("Error Code: " + e.getStatus());throw new ServiceException(e.getErrorMessage());}}/*** 删除定时任务** @param scheduleId* @return* @throws APIConnectionException* @throws APIRequestException*/public boolean delSchedule(String scheduleId) {try {JPushClient jpushClient = buildJPushClient();jpushClient.deleteSchedule(scheduleId);return Boolean.TRUE;} catch (APIConnectionException e) {log.error("Connection error. Should retry later. ", e);throw new ServiceException(e.getMessage());} catch (APIRequestException e) {log.error("Error response from JPush server. Should review and fix it. {}", e.getErrorMessage());log.info("Error Code: " + e.getStatus());throw new ServiceException(e.getErrorMessage());}}/*** 禁用定时任务** @param scheduleId* @return* @throws APIConnectionException* @throws APIRequestException*/public boolean disableSchedule(String scheduleId) {try {JPushClient jpushClient = buildJPushClient();ScheduleResult result = jpushClient.disableSchedule(scheduleId);log.info("禁用定时任务请求完成: {}", result);boolean ok = result.isResultOK();return ok;} catch (APIConnectionException e) {log.error("Connection error. Should retry later. ", e);throw new ServiceException(e.getMessage());} catch (APIRequestException e) {log.error("Error response from JPush server. Should review and fix it. {}", e.getErrorMessage());log.info("Error Code: " + e.getStatus());throw new ServiceException(e.getErrorMessage());}}/*** 启用定时任务** @param scheduleId* @return* @throws APIConnectionException* @throws APIRequestException*/public boolean enableSchedule(String scheduleId) {try {JPushClient jpushClient = buildJPushClient();ScheduleResult result = jpushClient.enableSchedule(scheduleId);log.info("启用定时任务请求完成: {}", result);boolean ok = result.isResultOK();return ok;} catch (APIConnectionException e) {log.error("Connection error. Should retry later. ", e);throw new ServiceException(e.getMessage());} catch (APIRequestException e) {log.error("Error response from JPush server. Should review and fix it. {}", e.getErrorMessage());log.info("Error Code: " + e.getStatus());throw new ServiceException(e.getErrorMessage());}}/*** 获取定时任务的的msgIds** @param scheduleId* @return* @throws APIConnectionException* @throws APIRequestException*/public ScheduleMsgIdsResult getScheduleMsgIds(String scheduleId) {try {JPushClient jpushClient = buildJPushClient();ScheduleMsgIdsResult result = jpushClient.getScheduleMsgIds(scheduleId);log.info("获取定时任务的的msgIds请求完成: {}", result);return result;} catch (APIConnectionException e) {log.error("Connection error. Should retry later. ", e);throw new ServiceException(e.getMessage());} catch (APIRequestException e) {log.error("Error response from JPush server. Should review and fix it. {}", e.getErrorMessage());log.info("Error Code: " + e.getStatus());throw new ServiceException(e.getErrorMessage());}}/*** 根据msgId获取推送统计** @param msgId* @return* @throws APIConnectionException* @throws APIRequestException*/public ReceivedsResult getReport(String msgId) {try {JPushClient jpushClient = buildJPushClient();ReceivedsResult result = jpushClient.getReportReceiveds(msgId);//测试账号没有下面这个api的权限,会报错MessagesResult messages = jpushClient.getReportMessages(msgId);return result;} catch (APIConnectionException e) {log.error("Connection error. Should retry later. ", e);throw new ServiceException(e.getMessage());} catch (APIRequestException e) {log.error("Error response from JPush server. Should review and fix it. {}", e.getErrorMessage());log.info("Error Code: " + e.getStatus());throw new ServiceException(e.getErrorMessage());}}}

本篇就介绍到这里了。

极光推送REST API与Java后台对接相关推荐

  1. android极光推送】—从客户端到后台,一文通吃

    http://blog.csdn.net http://blog.csdn.net/w8897282/article/details/52690379 版权声明:本文为博主原创文章,未经博主允许不得转 ...

  2. 【android极光推送】—从客户端到后台,一文通吃

    前记 推送原理浅析 平台说明 概念解释 推送的三种实现方式 客户端直接向推送服务方发送Http请求 项目服务器通过Http转发推送请求至推送服务方 项目服务端使用SDK进行功能集成 关于推送的种类概述 ...

  3. 小程序消息推送及客服(JAVA后台)

    小程序客服及消息推送开发(后台JAVA) 最近公司在做小程序,涉及到客服及消息推送,简单的记录下开发过程及心得 客服 小程序自带的有客服功能只需要开启就行了. 选择开启后即可使用. 消息推送 首先在开 ...

  4. 极光推送REST API 实例(分等级推送,使用别名推送)

    在一个推送功能中,给不同等级的用户推送不同的消息 /// <summary>     /// 取得发送人员名单     /// </summary>     /// <p ...

  5. 极光推送REST API

    string JPushURI = "https://api.jpush.cn/v3/push";        string app_key = "808a3e149a ...

  6. 华为推送(Push)API实现(Java语言)

    在上一个FCM推送发布上线后,我开始了下一个开发任务.这次需要我接入华为服务器实现消息推送,其实接入华为要比接入fcm容易很多,因为华为的内部代码构建结构较为明了,可以很好地让开发者进行阅读和理解,从 ...

  7. 小米推送java_idea + springboot 的java后台服务器通过小米推送

    public class XiaomiPush { // 1.小米推送(我只推送Android且只应用regId发起推送,所以下面只有推送Android的代码 private static final ...

  8. 极光推送零基础极速上手开发指南,快速搭建后台推送服务

    一.基础配置 1.依赖配置 <!-- 极光推送开始 --> <dependency><groupId>cn.jpush.api</groupId>< ...

  9. 极光推送java服务端-通知(2)

    1.下载SDK REST API为极光推送开发API 2.下载好后,maven导入后可以参考示例 官方demo 4.小demo // 设置好账号的app_key和masterSecret是必须的pri ...

最新文章

  1. log4j打印mybatis sql语句
  2. Spark详解(一):Spark及其生态圈概述
  3. 175. 组合两个表
  4. 2017.9.25 Xor 失败总结
  5. 俯瞰大雾弥漫下的鄱阳湖二桥
  6. qml设置Text中的文字居中(不是整个Text居中)
  7. 网络的小区号和网络tac_网络问政|城基路老旧小区排污管长期堵塞没人管?
  8. 雷达人体存在感应器方案,智能物联网感知技术,实时感应人体存在
  9. Crontab定时任务表达式
  10. 华为安装gsm框架_华为Mate20手机怎么下载安装谷歌服务助手,GMS框架安装教程
  11. DNS分类与区别-权威DNS、递归DNS、转发DNS
  12. 外包干了三年,真废了。。。
  13. kubernetespod控制器详解上
  14. python + opencv微博图片去水印
  15. discuz帖子最后编辑时间如何取消显示
  16. LTE-TDD随机接入过程(4)-RIV的解析和Preamble资源的选择
  17. 倍控G30-J4125工控机开箱
  18. 计算机网络——数字数据的数字编码
  19. 英语6级选词填空全部选A和随机不重复填空选哪个?
  20. 如何实现一套优雅的Baas查询语言?

热门文章

  1. 格创东智亮相高端制造业CIO上海论坛,助推制造业智慧建设
  2. Mysql之DQL,各种查查查
  3. 6月程序员平均工资出炉,这个水平我慕了!
  4. 为什么要用 picture 标签代替 img 标签?
  5. opencv: 图像缩放(cv2.resize)
  6. antd表格添加序号
  7. 大疆无人机安卓Mobile Sdk开发(三)制定航点任务WaypointMission
  8. 信通院牵头数列科技参与主编的《信息系统稳定性保障能力建设指南》正式发布
  9. 2020.08.14日常总结——Trie树的实际应用
  10. Scrapy爬取中国地震台网1年内地震数据