1. 引入依赖

<!-- 极光 -->
<dependency><groupId>cn.jpush.api</groupId><artifactId>jpush-client</artifactId><version>3.3.10</version>
</dependency>
<dependency><groupId>cn.jpush.api</groupId><artifactId>jiguang-common</artifactId><version>1.1.4</version>
</dependency>
<!-- 苹果 -->
<dependency><groupId>com.notnoop.apns</groupId><artifactId>apns</artifactId><version>1.0.0.Beta6</version>
</dependency>
<!-- 华为 -->
<dependency><groupId>com.huawei.android</groupId><artifactId>huawei-push</artifactId><version>1.1.1</version>
</dependency>
<!-- 小米,vivo 请去官网下载, 然后配置到maven私服仓库nexus -->
<dependency><groupId>com.xiaomi</groupId><artifactId>mipush</artifactId><version>2.2.20</version>
</dependency><dependency><groupId>com.vivo</groupId><artifactId>vpush</artifactId><version>1.1.0</version>
</dependency>

2.  定义推送接口

public interface PushMessage {/*** 通知栏消息推送*/public int pushNcMsg(PushMessageDTO pushMessageDTO, String content, String title) throws Exception ;/*** 透传推送*/public int pushTransMsg(PushMessageDTO pushMessageDTO, String content) throws Exception ;}
//辅助类 appName, appId, appKey ,masterSecret请去官网注册账号,添加app应用获取
@Getter
@Setter
@ToString
public class PushMessageDTO implements Serializable {private static final long serialVersionUID = 1L;private String appName; //应用名称private String appId; //应用idprivate String appKey; //应用keyprivate String masterSecret; //秘钥private String target; //推送目标private String platform; //推送平台}

3.  实现类

//苹果都是透传推送
@Component
public class ApplePushMessage implements PushMessage {@Overridepublic int pushNcMsg(PushMessageDTO pushMessageDTO, String content, String title) throws Exception {// TODO Auto-generated method stubreturn 0;}//苹果的appKey是voippush.p12文件路径, masterSecret是密码@Overridepublic int pushTransMsg(PushMessageDTO pushMessageDTO, String content) throws Exception {ApnsService service = APNS.newService().withCert(pushMessageDTO.getAppKey(), pushMessageDTO.getMasterSecret()).withSandboxDestination().withAppleDestination(true).build();String payloadApple = APNS.newPayload().alertBody(content).build();String token = pushMessageDTO.getTarget();service.push(token, payloadApple);return 1;}
}
//华为
@Component
public class HuaWeiPushMessage implements PushMessage {private static String tokenUrl = "https://login.cloud.huawei.com/oauth2/v2/token"; // 获取认证Token的URLprivate static String apiUrl = "https://api.push.hicloud.com/pushsend.do"; // 应用级消息下发APIprivate static String accessToken;// 下发通知消息的认证Tokenprivate static long tokenExpiredTime; // accessToken的过期时间@Overridepublic int pushNcMsg(PushMessageDTO pushMessageDTO, String content, String title) throws Exception {if (tokenExpiredTime <= System.currentTimeMillis()) {refreshToken(pushMessageDTO.getMasterSecret(), pushMessageDTO.getAppKey());}/* PushManager.requestToken为客户端申请token的方法,可以调用多次以防止申请token失败 *//* PushToken不支持手动编写,需使用客户端的onToken方法获取 */JSONArray deviceTokens = new JSONArray();// 目标设备TokendeviceTokens.add(pushMessageDTO.getTarget());JSONObject body = new JSONObject();// 仅通知栏消息需要设置标题和内容,透传消息key和value为用户自定义body.put("title", title);// 消息标题body.put("content", content);// 消息内容体JSONObject param = new JSONObject();param.put("appPkgName", pushMessageDTO.getAppName());// 定义需要打开的appPkgNameJSONObject action = new JSONObject();action.put("type", 3);// 类型3为打开APP,其他行为请参考接口文档设置action.put("param", param);// 消息点击动作参数JSONObject msg = new JSONObject();msg.put("type", 3);// 3: 通知栏消息,异步透传消息请根据接口文档设置msg.put("action", action);// 消息点击动作msg.put("body", body);// 通知栏消息body内容JSONObject hps = new JSONObject();// 华为PUSH消息总结构体hps.put("msg", msg);JSONObject payload = new JSONObject();payload.put("hps", hps);String postBody = MessageFormat.format("access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",URLEncoder.encode(accessToken, "UTF-8"), URLEncoder.encode("openpush.message.api.send", "UTF-8"),URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"), URLEncoder.encode(deviceTokens.toString(), "UTF-8"),URLEncoder.encode(payload.toString(), "UTF-8"));String postUrl = apiUrl + "?nsp_ctx=" + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + pushMessageDTO.getAppKey() + "\"}", "UTF-8");httpPost(postUrl, postBody, 5000, 5000);return 1;}@Overridepublic int pushTransMsg(PushMessageDTO pushMessageDTO, String context) throws Exception {if (tokenExpiredTime <= System.currentTimeMillis()) {refreshToken(pushMessageDTO.getMasterSecret(),pushMessageDTO.getAppKey());}/* PushManager.requestToken为客户端申请token的方法,可以调用多次以防止申请token失败 *//* PushToken不支持手动编写,需使用客户端的onToken方法获取 */JSONArray deviceTokens = new JSONArray();// 目标设备TokendeviceTokens.add(pushMessageDTO.getTarget());JSONObject body = new JSONObject();body.put("online", 1);JSONObject param = new JSONObject();param.put("appPkgName", pushMessageDTO.getAppName());JSONObject action = new JSONObject();action.put("type", 3);// 类型3为打开APP,其他行为请参考接口文档设置action.put("param", param);// 消息点击动作参数JSONObject msg = new JSONObject();msg.put("type", 1);// 1: 透传异步消息,通知栏消息请根据接口文档设置msg.put("body", body.toString());// body内容不一定是JSON,可以是String,若为JSON需要转化为String发送msg.put("action", action);// 消息点击动作JSONObject hps = new JSONObject();// 华为PUSH消息总结构体hps.put("msg", msg);JSONObject payload = new JSONObject();payload.put("hps", hps);String postBody = MessageFormat.format("access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",URLEncoder.encode(accessToken, "UTF-8"), URLEncoder.encode("openpush.message.api.send", "UTF-8"),URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"), URLEncoder.encode(deviceTokens.toString(), "UTF-8"),URLEncoder.encode(payload.toString(), "UTF-8"));String postUrl = apiUrl + "?nsp_ctx=" + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + pushMessageDTO.getAppKey() + "\"}", "UTF-8");httpPost(postUrl, postBody, 5000, 5000);return 1;}// 获取下发通知消息的认证Tokenprivate void refreshToken(String appSecret, String appId) throws IOException {String msgBody = MessageFormat.format("grant_type=client_credentials&client_secret={0}&client_id={1}", URLEncoder.encode(appSecret, "UTF-8"), appId);String response = httpPost(tokenUrl, msgBody, 5000, 5000);JSONObject obj = JSONObject.parseObject(response);accessToken = obj.getString("access_token");tokenExpiredTime = System.currentTimeMillis() + (obj.getLong("expires_in") - 5 * 60) * 1000;}//httpPost请求private String httpPost(String httpUrl, String data, int connectTimeout, int readTimeout) throws IOException {OutputStream outPut = null;HttpURLConnection urlConnection = null;InputStream in = null;try {URL url = new URL(httpUrl);urlConnection = (HttpURLConnection) url.openConnection();urlConnection.setRequestMethod("POST");urlConnection.setDoOutput(true);urlConnection.setDoInput(true);urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");urlConnection.setConnectTimeout(connectTimeout);urlConnection.setReadTimeout(readTimeout);urlConnection.connect();// POST dataoutPut = urlConnection.getOutputStream();outPut.write(data.getBytes("UTF-8"));outPut.flush();// read responseif (urlConnection.getResponseCode() < 400) {in = urlConnection.getInputStream();} else {in = urlConnection.getErrorStream();}List<String> lines = IOUtils.readLines(in, urlConnection.getContentEncoding());StringBuffer strBuf = new StringBuffer();for (String line : lines) {strBuf.append(line);}System.out.println(strBuf.toString());return strBuf.toString();} finally {IOUtils.closeQuietly(outPut);IOUtils.closeQuietly(in);if (urlConnection != null) {urlConnection.disconnect();}}}}

//小米

@Component
public class XiaoMiPushMessage implements PushMessage {@Overridepublic int pushNcMsg(PushMessageDTO pushMessageDTO, String content, String title) throws Exception {Constants.useOfficial();Sender sender = new Sender(pushMessageDTO.getMasterSecret());String messagePayload = "{\"online\":\"1\"}";Message message = new Message.Builder().title(title).description(content).payload(messagePayload).restrictedPackageName(pushMessageDTO.getAppName()).passThrough(0).extra(Constants.EXTRA_PARAM_NOTIFY_EFFECT, Constants.NOTIFY_LAUNCHER_ACTIVITY).notifyType(-1).build();sender.sendToAlias(message, pushMessageDTO.getTarget(), 1);return 1;}@Overridepublic int pushTransMsg(PushMessageDTO pushMessageDTO, String content) throws Exception {Constants.useOfficial();Sender sender = new Sender(pushMessageDTO.getMasterSecret());String messagePayload = "{\"online\":\"1\"}";Message message = new Message.Builder().description(content).payload(messagePayload).restrictedPackageName(pushMessageDTO.getAppName()).passThrough(1).notifyType(-1).build();sender.sendToAlias(message, pushMessageDTO.getTarget(), 1);return 1;}}

//vivo暂时只有通知栏消息推送

@Component
public class VivoPushMessage implements PushMessage {@Overridepublic int pushNcMsg(PushMessageDTO pushMessageDTO, String content, String title) throws Exception {Sender sender = new Sender(pushMessageDTO.getMasterSecret());//注册登录开发平台网站获取到的appSecretResult result = sender.getToken(Integer.valueOf(pushMessageDTO.getAppId()), pushMessageDTO.getAppKey());//注册登录开发平台网站获取到的appId和appKeySender senderMessage = new Sender(pushMessageDTO.getMasterSecret(),result.getAuthToken());Message singleMessage = new Message.Builder().regId(pushMessageDTO.getTarget())//该测试手机设备订阅推送后生成的regId.notifyType(3).title(title).content(content).timeToLive(1000).skipType(2).skipContent("http://www.vivo.com").networkType(-1).requestId("1234567890123456").build();Result resultMessage = senderMessage.sendSingle(singleMessage);return 1;}@Overridepublic int pushTransMsg(PushMessageDTO pushMessageDTO, String content) throws Exception {return 1;}}

4 .  统一消息推送接口

public void pushMessageToAllPlatform(PushMessageVO pushMessageVO) {String[] sipCodeList = pushMessageVO.getSipCode().split(",");// 查询推送信息,在数据库构建的表(见文章末尾)List<PushMessageDTO> pushMessageDTOList = rxSipPlatformTargetMapper.selectPushMessage(pushMessageVO.getAppName(), sipCodeList);// 推送消息if (null != pushMessageDTOList && !pushMessageDTOList.isEmpty()) {for (PushMessageDTO pushMessageDTO : pushMessageDTOList) {pushMessageToApp(pushMessageDTO,  pushMessageVO.getPushType(), pushMessageVO.getContent(), pushMessageVO.getTitle());}}
}private int pushMessageToApp(PushMessageDTO pushMessageDTO, String pushType,String content, String title) {try {PushMessage pushMessage = (PushMessage) SpringUtil.getBean(PlatformEnum.getNameByType(pushMessageDTO.getPlatform()));if (StringUtils.isBlank(pushType) || "NC".equals(pushType)) {pushMessage.pushNcMsg(pushMessageDTO, content, title);}if (StringUtils.isBlank(pushType) || "TS".equals(pushType)) {pushMessage.pushTransMsg(pushMessageDTO, content);}} catch (Exception e) {log.error(e.toString());return 0;}return 1;}

//辅助参数类

public enum PlatformEnum {

JIGUANG ("JIGUANG","jiGuangPushMessage"),
    HUAWEI  ("HUAWEI","huaWeiPushMessage"),
    APPLE   ("APPLE","applePushMessage"),
    XIAOMI  ("XIAOMI","xiaoMiPushMessage"),
    OPPO    ("OPPO","oppoPushMessage"),
    VIVO    ("VIVO","vivoPushMessage");

private String platformType;

private String platformName;

private PlatformEnum(String platformType, String platformName) {
        this.platformType = platformType;
        this.platformName = platformName;
    }

public String getPlatformType() {
        return platformType;
    }

public void setPlatformType(String platformType) {
        this.platformType = platformType;
    }

public String getPlatformName() {
        return platformName;
    }

public void setPlatformName(String platformName) {
        this.platformName = platformName;
    }

public static String getNameByType(String platformType) {
        for (PlatformEnum e : PlatformEnum.values()) {
            if (e.getPlatformType().equals(platformType)) {
                return e.getPlatformName();
            }
        }
        return null;
    }
}

public class PushMessageVO implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value="app名称" ,required=true)private String appName;@ApiModelProperty(value="设备编号(多个用逗号隔开)" ,required=true)private String sipCode;@ApiModelProperty(value="消息推送模式(NC-通知栏消息, TS-透传消息)" ,required=true)private String pushType;@ApiModelProperty(value="消息内容" ,required=true)private String content;@ApiModelProperty(value="消息标题")private String title;}

数据库表:

CREATE TABLE `rx_sip_platform_target` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `sip_code` varchar(255) DEFAULT NULL COMMENT '设备编号',
  `platform` varchar(255) DEFAULT '0' COMMENT '推送平台',
  `target` varchar(255) DEFAULT NULL COMMENT '推送目标',
  `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
)  COMMENT='设备登录推送目标表';

CREATE TABLE `rx_app_config` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `app_name` varchar(64) NOT NULL COMMENT '应用名称',
  `app_id` varchar(20) DEFAULT NULL COMMENT '应用ID',
  `app_key` varchar(128) NOT NULL COMMENT 'appKey',
  `master_secret` varchar(64) NOT NULL COMMENT 'masterSecret',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NULL DEFAULT NULL,
  `platform` varchar(255) DEFAULT '0' COMMENT '推送平台',
  PRIMARY KEY (`id`)
)   COMMENT='应用推送平台配置信息';

//苹果的appKey是voippush.p12文件路径, masterSecret是密码

//查询推送集sql

<select id="selectPushMessage" resultMap="PushMessageDTOMap">SELECTc.app_name,c.app_id,c.app_key,c.master_secret,c.platform,p.targetFROMrx_sip_platform_target pINNER JOIN rx_app_config c ON c.platform = p.platformWHEREc.app_name =#{appName,jdbcType=VARCHAR}AND p.sip_code IN<foreach collection="sipCodeList" item="sipCode" open="(" close=")" separator=",">#{sipCode,jdbcType=VARCHAR}</foreach>
</select>

java服务端统一消息推送(苹果, 华为, 小米, 极光,vivo)相关推荐

  1. java服务端集成信鸽推送

    java服务端集成信鸽推送 最近项目需要集成推送功能,突发奇想的选了信鸽推送(可能是最近一直在用阿里的东西),没想到这坑不是一般的多,而且关于详细的集成案例,度娘上真是没一个能入眼的.算了,别的不多说 ...

  2. springboot实现SSE服务端主动向客户端推送数据,java服务端向客户端推送数据,kotlin模拟客户端向服务端推送数据

    SSE服务端推送 服务器向浏览器推送信息,除了 WebSocket,还有一种方法:Server-Sent Events(以下简称 SSE).本文介绍它的用法. 在很多业务场景中,会涉及到服务端向客户端 ...

  3. 浅析即时通讯开发中移动端实时消息推送技术

    实时消息推送在移动端互联网时代很平常,也很重要,它的存在让智能终端真正成为全时信息传播的工具.本文将从移动端无线网络的特点来谈谈实时消息推送的技术原理及相关问题,希望能给你带来些许启发. 移动端实时消 ...

  4. 关于web端的消息推送方式转载

    引言: 在互联网高速发展的时代里,web应用大有取代桌面应用的趋势,不必再去繁琐的安装各种软件,只需一款主流浏览器即可完成大部分常规操作,这些原因都在吸引着软件厂商和消费者.而随着各大厂商浏览器版本的 ...

  5. 视频直播源码中关于服务端直播开播推送实现

    在视频直播源码中直播app开播时需向客户推送开播消息通知用户,实现方式如下: 1.申请相应的推送服务三方,如下使用极光推送,获取相应的配置资料,并做好相应的配置 2.推送代码如下: /* 极光推送 * ...

  6. sse服务器推送性能,SSE 服务端向客户端推送

    传统的ajax都是由客户端主动去请求,服务端才可以返回数据 而sse是建立一个通道,并且在断线后自动重连,由服务端去推送,不需要客户端去主动请求,只需要建立通道 websocket是双向通信 客户端可 ...

  7. 做消息推送 8 年的极光,为何做物联网 JIoT 平台?

    作者 | 伍杏玲 出品 | CSDN(ID:CSDNnews) 在移动开发里,开发者有三大刚需:统计分析.消息推送.统一登录.其中对于消息推送,有一家企业自移动开发的潮流伊始,便坚持为开发者提供这项基 ...

  8. 一加消息推送服务器,华为、荣耀、OPPO、realme、一加完成统一推送服务开发

    这意味着,符合联盟标准的统一推送服务,将覆盖华为.荣耀.OPPO.realme.一加五个品牌的手机. 具体来讲,华为.荣耀将首先在EMUI 10正式版中支持统一推送,华为和荣耀新发布机型全部支持,现有 ...

  9. 【Java开源项目】消息推送平台 日志引入

    大家好,我是3y.在正文之前,先给各位粉丝汇报下austin消息推送平台项目进度: 总的来说,我感觉这次的反响是不错的,虽然阅读量不高.但留言的人多了很多,也有很多人都担心我会不会鸽掉(更新一半中途就 ...

最新文章

  1. 新春祝福必杀计之发送短信攻略
  2. python网课阿里云_关于python视频教程的阿里云网站内容
  3. linux下配置Docker的jupyter notebook环境
  4. 作为初学者,应该如何系统学习Java呢?
  5. Ribbon-2通过代码自定义配置ribbon
  6. Attempt to present vc on vc which is already presenting vc/(null)
  7. github删除文件_github 仓库中删除历史大文件
  8. 编译安装mysql5.6.36_MySQL5.6.36编译安装
  9. ckeditor java 上传_CKEditor粘贴图片自动上传到服务器(Java版)
  10. Zabbix3.2.6之通过JMX监控Tomcat
  11. 怎么用html制作求职登记表,有步骤的编写个人简历 其效果更好
  12. 微信小程序——小程序UI框架首页
  13. 【Inpho精品教程】任务二:Inpho创建工程(创建项目、新建相机参数、导入照片、导入POS、生成航条、保存项目)
  14. 《蜘蛛侠1,2,3》
  15. 纯html+css实现点击切换tab页
  16. IDEA 使用SequenceDiagram插件绘制时序图
  17. 山东大学软件学院项目实训-创新实训-山大软院网络攻防靶场实验平台(二)-docker安装与学习
  18. 纷享销客产品副总裁李杰:连接型CRM如何支撑快消品牌企业新增长
  19. 匡威react是什么意思_react+zoom?这双牛掰的匡威似乎不如李宁?
  20. 织梦转pbootcms插件,自动pbootcms插件

热门文章

  1. Squid正向代理服务器
  2. 攻城狮,你知道闪存电压拉偏时的一些基础数据吗?
  3. 后台获取文件并在浏览器下载
  4. react中点击一个会触发全部渲染出来的的点击事件的情况(初学者)
  5. android 代码 自动锁定时间,Android系统取消自动锁定屏幕
  6. 我在冬奥会认识了各国小伙伴,怎么样才能够和他们保持联系?
  7. 2022金属非金属矿山(露天矿山)主要负责人考试模拟100题及在线模拟考试
  8. 求二叉树上结点的路径
  9. Mal-PEG-Biotin,马来酰亚胺聚乙二醇生物素,Biotion-PEG-Maleimide
  10. 程序员也应了解的Unity粒子系统