├── .gitignore ├── CHANGES.md ├── LICENSE ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── getui │ └── push │ └── v2 │ └── sdk │ ├── ApiHelper.java │ ├── GtApiConfiguration.java │ ├── GtHttpProxyConfig.java │ ├── IJson.java │ ├── anno │ ├── GtApi.java │ ├── method │ │ ├── GtDelete.java │ │ ├── GtGet.java │ │ ├── GtPost.java │ │ └── GtPut.java │ └── param │ │ ├── GtBodyParam.java │ │ ├── GtHeaderParam.java │ │ ├── GtPathParam.java │ │ └── GtQueryParam.java │ ├── api │ ├── AuthApi.java │ ├── PushApi.java │ ├── StatisticApi.java │ └── UserApi.java │ ├── common │ ├── ApiException.java │ ├── ApiResult.java │ ├── Assert.java │ ├── Config.java │ ├── Monitor.java │ ├── Strings.java │ ├── http │ │ ├── GtHttpClient.java │ │ ├── GtHttpDelete.java │ │ └── HttpManager.java │ ├── type │ │ ├── ParameterizedTypeImpl.java │ │ └── TypeReference.java │ └── util │ │ └── Utils.java │ ├── core │ ├── Configs.java │ ├── DefaultJson.java │ ├── client │ │ └── DefaultApiClient.java │ ├── domain │ │ ├── DomainCheck.java │ │ ├── DomainListBO.java │ │ ├── IDomainCheck.java │ │ └── RasDomainBO.java │ ├── factory │ │ └── GtApiProxyFactory.java │ ├── handler │ │ ├── GtInterceptor.java │ │ ├── IHandler.java │ │ ├── header │ │ │ └── IHeaderHandler.java │ │ └── impl │ │ │ └── DefaultGtInterceptor.java │ ├── manager │ │ └── HostManager.java │ ├── registry │ │ ├── DefaultGtApiRegistry.java │ │ └── GtApiRegistry.java │ └── status │ │ ├── ServiceState.java │ │ └── StateWrapper.java │ ├── dto │ ├── BaseDTO.java │ ├── CommonEnum.java │ ├── req │ │ ├── Audience.java │ │ ├── AudienceDTO.java │ │ ├── AuthDTO.java │ │ ├── BadgeDTO.java │ │ ├── BaseReqDTO.java │ │ ├── CidAliasListDTO.java │ │ ├── CidByTagDTO.java │ │ ├── Condition.java │ │ ├── ConditionListDTO.java │ │ ├── QueryAliasDTO.java │ │ ├── Settings.java │ │ ├── Strategy.java │ │ ├── TagDTO.java │ │ ├── UserDTO.java │ │ └── message │ │ │ ├── CustomBean.java │ │ │ ├── PushBatchDTO.java │ │ │ ├── PushChannel.java │ │ │ ├── PushDTO.java │ │ │ ├── PushMessage.java │ │ │ ├── RevokeBean.java │ │ │ ├── android │ │ │ ├── AndroidDTO.java │ │ │ ├── GTNotification.java │ │ │ ├── ThirdNotification.java │ │ │ ├── ThirdRevokeBean.java │ │ │ └── Ups.java │ │ │ ├── harmony │ │ │ ├── HarmonyDTO.java │ │ │ └── HarmonyNotification.java │ │ │ └── ios │ │ │ ├── Alert.java │ │ │ ├── Aps.java │ │ │ ├── IosDTO.java │ │ │ └── Multimedia.java │ └── res │ │ ├── AliasResDTO.java │ │ ├── CidStatusDTO.java │ │ ├── PushCountDTO.java │ │ ├── QueryCidResDTO.java │ │ ├── ScheduleTaskDTO.java │ │ ├── TaskIdDTO.java │ │ ├── TokenDTO.java │ │ └── statistic │ │ ├── StatisticDTO.java │ │ └── UserStatisticDTO.java │ └── spring │ └── GtBeanFactory.java └── test ├── java └── com │ └── getui │ └── push │ └── v2 │ └── sdk │ └── api │ ├── Jsons.java │ ├── PushApiTest.java │ ├── StatisticApiTest.java │ ├── UserApiTest.java │ ├── env │ └── ApiContext.java │ └── util │ └── Utils.java └── resource └── Spring-config.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse project files 2 | .classpath 3 | .project 4 | .settings/ 5 | 6 | 7 | # Intellij project files 8 | *.iml 9 | .idea/ 10 | 11 | # Others 12 | target/ 13 | logs/ 14 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## 1.0.6.0 4 | 5 | ### update 6 | 7 | * 鸿蒙厂商通道通知消息支持自定义消息、消息覆盖和消息撤回 8 | * 关闭CloseableHttpClient内默认的重试机制 9 | 10 | ## 1.0.5.0 11 | 12 | ### update 13 | 14 | * 鸿蒙厂商通道通知消息click_type新增支持payload 15 | * 鸿蒙个推通道通知消息支持设置通知渠道类型slotType 16 | * GtHttpClient支持设置maxConnTotal和maxConnPerRoute 17 | 18 | ## 1.0.4.0 19 | 20 | ### update 21 | 22 | * 支持活跃行为过滤功能 23 | * 新增pushToSingleCidByTag和pushListCidByTag推送接口 24 | 25 | ## 1.0.3.0 26 | 27 | ### update 28 | 29 | * 支持灵动岛 30 | 31 | ## 1.0.2.1 32 | 33 | ### update 34 | 35 | * 升级依赖,修复检测漏洞 36 | 37 | ## 1.0.2.0 38 | 39 | ### update 40 | 41 | * 鸿蒙离线支持传参want 42 | 43 | ## 1.0.1.0 44 | 45 | ### update 46 | 47 | * 支持jdk版本 1.8及以上版本,不再支持jdk1.6 48 | * 重试支持切换域名 49 | * 支持设置接口维度的超时时间 50 | * 修改默认的连接超时时间,60s改为10s 51 | * 内部异常,会拼接到apiResult的msg上,eg. 原来接口超时返回`{"code":5000, "message":"http error::5000"}`,修改后返回`{" 52 | code":5000, "message":"http error:Read timed out::5000"} 53 | 54 | ## 1.0.0.17 55 | 56 | ### update 57 | 58 | * 鸿蒙在线支持传参want 59 | 60 | ## 1.0.0.16 61 | 62 | ### update 63 | 64 | * 支持别名类型 65 | * 增加鸿蒙平台厂商参数 66 | 67 | ## 1.0.0.15 68 | 69 | ### update 70 | 71 | * 支持本地消息分类 72 | * 最稳定域名检测开关支持通过启动项配置 73 | * 设置非个推域名时强制关闭稳定域名检测 74 | 75 | ## 1.0.0.14 76 | 77 | ### update 78 | 79 | * 支持消息重弹功能 80 | 81 | ## 1.0.0.13 82 | 83 | ### update 84 | 85 | * 厂商智能配额策略支持兜底 86 | * 修复反参数据类型解析问题 87 | 88 | ## 1.0.0.12 89 | 90 | ### update 91 | 92 | * 支持厂商智能配额策略 93 | * 支持通知关闭过滤 94 | 95 | ## 1.0.0.11 96 | 97 | ### update 98 | 99 | * 支持安卓厂商消息撤回 100 | * HTTPS协议更换(SSLv3 -> TLSv1.2) 101 | 102 | ## 1.0.0.10 103 | 104 | ### update 105 | 106 | * 新增查询推送量和获取推送实时结果接口 107 | * 报表相关接口反参解析问题修复 108 | * 部分接口入参规范 109 | 110 | ## 1.0.0.9 111 | 112 | ### update 113 | 114 | * 新增自定义回执字段SVIP功能 115 | 116 | ## 1.0.0.8 117 | 118 | ### update 119 | 120 | * ApiHelper和DefaultApiClient 缓存key支持设置自定义前缀,满足客户特殊使用场景 121 | * 完善参数和注释 122 | 123 | ## 1.0.0.7 124 | 125 | ### Fix 126 | 127 | * 修复超时重试http连接未释放问题 128 | 129 | ### update 130 | 131 | * 移除guava依赖 132 | * 支持设置获取连接池中http连接超时时间 133 | 134 | ## 1.0.0.6 135 | 136 | ### Fix 137 | 138 | 修复并发请求消息体异常问题 139 | 140 | ## 1.0.0.5 141 | 142 | ### Fix 143 | 144 | 修复长连接单位错误问题 由分钟改为秒 145 | 146 | ## 1.0.0.4 147 | 148 | ### Features 149 | 150 | 支持设置长连接有效期 151 | 152 | ## 1.0.0.3 153 | 154 | ### Features 155 | 156 | 1. ios支持自定义参数 157 | 158 | ### Fix 159 | 160 | 1. 修复jdk11 json反序列化报错问题: ParameterizedTypeImpl 类找不到 161 | 2. 修复jdk1.6 https证书错误问题 162 | 3. 服务端返回500支持重试 163 | 4. 修复首次鉴权失败后空指针异常 164 | 165 | ## 1.0.0.2 166 | 167 | ### Features 168 | 169 | 1. 支持设置httpclient最大连接数,解决并发大时获取连接慢问题 170 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.getui.push 8 | restful-sdk 9 | jar 10 | 1.0.6.0 11 | https://github.com/GetuiLaboratory/getui-pushapi-java-client-v2 12 | Getui Push API Java Client 13 | Getui's officially supported Java client library for accessing Getui APIs. 14 | 15 | 16 | 17 | The Apache Software License, Version 2.0 18 | http://www.apache.org/licenses/LICENSE-2.0.txt 19 | repo 20 | 21 | 22 | 23 | 24 | 25 | getui 26 | developer@getui.com 27 | getui 28 | https://www.getui.com/ 29 | 30 | 31 | 32 | 33 | scm:git:https://github.com/GetuiLaboratory/getui-pushapi-java-client-v2.git 34 | scm:git:ssh://github.com:GetuiLaboratory/getui-pushapi-java-client-v2.git 35 | https://github.com/GetuiLaboratory/getui-pushapi-java-client-v2 36 | 37 | 38 | 39 | 4.3.9.RELEASE 40 | 1.7.25 41 | 42 | 43 | 44 | 45 | 46 | org.springframework 47 | spring-context 48 | ${spring.version} 49 | provided 50 | 51 | 52 | 53 | 54 | 55 | 56 | org.slf4j 57 | slf4j-api 58 | ${slf4j.version} 59 | compile 60 | 61 | 62 | ch.qos.logback 63 | logback-classic 64 | 1.2.3 65 | provided 66 | 67 | 68 | 69 | org.apache.httpcomponents 70 | httpclient 71 | 4.5.13 72 | 73 | 74 | 75 | com.google.code.gson 76 | gson 77 | 2.10.1 78 | 79 | 80 | junit 81 | junit 82 | 4.13.2 83 | test 84 | 85 | 86 | 87 | 88 | 89 | 90 | org.apache.maven.plugins 91 | maven-compiler-plugin 92 | 2.3.2 93 | 94 | 1.8 95 | 1.8 96 | utf-8 97 | 98 | 99 | 100 | maven-resources-plugin 101 | 2.4.3 102 | 103 | utf-8 104 | 105 | 106 | 107 | maven-source-plugin 108 | 2.1 109 | 110 | true 111 | 112 | 113 | 114 | compile 115 | 116 | jar 117 | 118 | 119 | 120 | 121 | 122 | 123 | org.apache.maven.plugins 124 | maven-gpg-plugin 125 | 1.5 126 | 127 | 128 | verify 129 | 130 | sign 131 | 132 | 133 | 134 | 135 | 136 | 137 | org.apache.maven.plugins 138 | maven-javadoc-plugin 139 | 2.9.1 140 | 141 | true 142 | UTF-8 143 | UTF-8 144 | UTF-8 145 | -Xdoclint:none 146 | 147 | 148 | 149 | attach-javadocs 150 | 151 | jar 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | sonatype-nexus-snapshots 162 | https://oss.sonatype.org/content/repositories/snapshots 163 | 164 | 165 | sonatype-nexus-staging 166 | https://oss.sonatype.org/service/local/staging/deploy/maven2 167 | 168 | 169 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/ApiHelper.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk; 2 | 3 | import com.getui.push.v2.sdk.api.AuthApi; 4 | import com.getui.push.v2.sdk.api.PushApi; 5 | import com.getui.push.v2.sdk.api.UserApi; 6 | import com.getui.push.v2.sdk.common.Assert; 7 | import com.getui.push.v2.sdk.core.DefaultJson; 8 | import com.getui.push.v2.sdk.core.client.DefaultApiClient; 9 | import com.getui.push.v2.sdk.core.factory.GtApiProxyFactory; 10 | import com.getui.push.v2.sdk.core.handler.GtInterceptor; 11 | 12 | import java.util.Map; 13 | import java.util.concurrent.ConcurrentHashMap; 14 | 15 | /** 16 | * create by getui on 2020/6/7 17 | * 18 | * @author getui 19 | */ 20 | public class ApiHelper { 21 | 22 | private final GtApiProxyFactory gtApiProxyFactory; 23 | 24 | private static final Object BUILD_LOCK = new Object(); 25 | 26 | private static final Map apiHelperCache = new ConcurrentHashMap(4); 27 | 28 | /** 29 | * @param configuration 配置信息类 30 | * @return 31 | */ 32 | public static ApiHelper build(GtApiConfiguration configuration) { 33 | return build(configuration, new DefaultJson()); 34 | } 35 | 36 | /** 37 | * @param configuration 配置信息类 38 | * @return 39 | */ 40 | public static ApiHelper build(GtApiConfiguration configuration, IJson json) { 41 | return build(configuration, json, null); 42 | } 43 | 44 | /** 45 | * @param configuration 配置信息类 46 | * @return 47 | */ 48 | public static ApiHelper build(GtApiConfiguration configuration, IJson json, GtInterceptor interceptor) { 49 | Assert.notNull(configuration, "configuration"); 50 | configuration.check(); 51 | String key = configuration.keyOfCache(); 52 | ApiHelper apiHelper = apiHelperCache.get(key); 53 | if (apiHelper != null) { 54 | return apiHelper; 55 | } 56 | if (json == null) { 57 | json = new DefaultJson(); 58 | } 59 | synchronized (BUILD_LOCK) { 60 | apiHelper = apiHelperCache.get(key); 61 | if (apiHelper != null) { 62 | return apiHelper; 63 | } 64 | final DefaultApiClient defaultApiClient = DefaultApiClient.build(configuration, json); 65 | if (interceptor != null) { 66 | defaultApiClient.addGtInterceptor(interceptor); 67 | } 68 | GtApiProxyFactory factory = GtApiProxyFactory.build(defaultApiClient); 69 | final AuthApi authApi = factory.createProxy(AuthApi.class); 70 | defaultApiClient.setAuthApiAndAuth(authApi); 71 | apiHelper = new ApiHelper(factory); 72 | apiHelperCache.put(key, apiHelper); 73 | return apiHelper; 74 | } 75 | } 76 | 77 | /** 78 | * 删除缓存,并关闭守护线程,不影响已创建的Api的使用 79 | * 80 | * @param configuration 81 | */ 82 | public static void close(GtApiConfiguration configuration) { 83 | Assert.notNull(configuration, "configuration"); 84 | configuration.check(); 85 | String key = configuration.keyOfCache(); 86 | ApiHelper apiHelper = apiHelperCache.remove(key); 87 | if (apiHelper != null) { 88 | apiHelper.gtApiProxyFactory.close(); 89 | } 90 | } 91 | 92 | private ApiHelper(GtApiProxyFactory gtApiProxyFactory) { 93 | this.gtApiProxyFactory = gtApiProxyFactory; 94 | } 95 | 96 | /** 97 | * 创建接口实例 98 | * 99 | * @param apiClass {@link UserApi} {@link PushApi} 100 | * @param 101 | * @return 102 | */ 103 | public T creatApi(Class apiClass) { 104 | return this.gtApiProxyFactory.createProxy(apiClass); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/GtHttpProxyConfig.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk; 2 | 3 | /** 4 | * 代理配置项 5 | * 6 | * @author getui 7 | */ 8 | public class GtHttpProxyConfig { 9 | private String host; 10 | private int port; 11 | private String username; 12 | private String password; 13 | 14 | public GtHttpProxyConfig(String host, int port) { 15 | this.host = host; 16 | this.port = port; 17 | } 18 | 19 | public GtHttpProxyConfig(String host, int port, String username, String password) { 20 | this.host = host; 21 | this.port = port; 22 | this.username = username; 23 | this.password = password; 24 | } 25 | 26 | public String getHost() { 27 | return host; 28 | } 29 | 30 | public void setHost(String host) { 31 | this.host = host; 32 | } 33 | 34 | public int getPort() { 35 | return port; 36 | } 37 | 38 | public void setPort(int port) { 39 | this.port = port; 40 | } 41 | 42 | public String getUsername() { 43 | return username; 44 | } 45 | 46 | public void setUsername(String username) { 47 | this.username = username; 48 | } 49 | 50 | public String getPassword() { 51 | return password; 52 | } 53 | 54 | public void setPassword(String password) { 55 | this.password = password; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/IJson.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk; 2 | 3 | import java.lang.reflect.Type; 4 | 5 | /** 6 | * 开发者实现此接口可用于自定义json转换方式 7 | * 注意:要保证线程安全 8 | * create by getui on 2020/9/25 9 | * 10 | * @author getui 11 | */ 12 | public interface IJson { 13 | 14 | /** 15 | * 对象转json 16 | * 17 | * @param obj 18 | * @return 19 | */ 20 | String toJson(Object obj); 21 | 22 | /** 23 | * json转对象 24 | * 25 | * @param jsonString 26 | * @param type 27 | * @param 28 | * @return 29 | */ 30 | T fromJson(String jsonString, Type type); 31 | 32 | T fromJson(String jsonString, Class tClass); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/GtApi.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 使用此注解修饰的类代表个推API接口,会在应用启动时,提前初始化,初始化的过程中,会检测接口规范 10 | * create by getui on 2020/6/7 11 | * 12 | * @author getui 13 | */ 14 | @Target({ElementType.TYPE}) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface GtApi { 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/method/GtDelete.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno.method; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * create by getui on 2020/6/4 10 | * 11 | * @author getui 12 | */ 13 | @Target({ElementType.METHOD}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface GtDelete { 16 | 17 | /** 18 | * 接口相对路径, 不包含路径参数 19 | * 20 | * @return 21 | */ 22 | String uri(); 23 | 24 | /** 25 | * 是否需要token,默认需要 26 | * 27 | * @return 28 | */ 29 | boolean needToken() default true; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/method/GtGet.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno.method; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * create by getui on 2020/6/4 10 | * 11 | * @author getui 12 | */ 13 | @Target({ElementType.METHOD}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface GtGet { 16 | 17 | /** 18 | * 接口相对路径, 不包含路径参数 19 | * eg. /auth 20 | * 21 | * @return 22 | */ 23 | String uri(); 24 | 25 | /** 26 | * 是否需要token,默认需要 27 | * 28 | * @return 29 | */ 30 | boolean needToken() default true; 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/method/GtPost.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno.method; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * create by getui on 2020/6/4 10 | * 11 | * @author getui 12 | */ 13 | @Target({ElementType.METHOD}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface GtPost { 16 | 17 | /** 18 | * 接口相对路径, 不包含路径参数 19 | * 20 | * @return 21 | */ 22 | String uri(); 23 | 24 | /** 25 | * 是否需要token,默认需要 26 | * 27 | * @return 28 | */ 29 | boolean needToken() default true; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/method/GtPut.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno.method; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * create by getui on 2020/6/4 10 | * 11 | * @author getui 12 | */ 13 | @Target({ElementType.METHOD}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface GtPut { 16 | 17 | /** 18 | * 接口相对路径, 不包含路径参数 19 | * 20 | * @return 21 | */ 22 | String uri(); 23 | 24 | /** 25 | * 是否需要token,默认需要 26 | * 27 | * @return 28 | */ 29 | boolean needToken() default true; 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/param/GtBodyParam.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno.param; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 修饰HTTP请求中的body参数 10 | * create by getui on 2020/6/4 11 | * 12 | * @author getui 13 | */ 14 | @Target({ElementType.PARAMETER}) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface GtBodyParam { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/param/GtHeaderParam.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno.param; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 修饰HTTP请求中的header参数 10 | * create by getui on 2020/6/4 11 | * 12 | * @author getui 13 | */ 14 | @Target({ElementType.PARAMETER}) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface GtHeaderParam { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/param/GtPathParam.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno.param; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 秀水HTTP请求中的路径参数 10 | * create by getui on 2020/6/4 11 | * 12 | * @author getui 13 | */ 14 | @Target({ElementType.PARAMETER}) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface GtPathParam { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/anno/param/GtQueryParam.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.anno.param; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 修饰HTTP请求中的query参数 10 | * create by getui on 2020/6/4 11 | * 12 | * @author getui 13 | */ 14 | @Target({ElementType.PARAMETER}) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface GtQueryParam { 17 | /** 18 | * 参数名 19 | * 20 | * @return 21 | */ 22 | String name(); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/api/AuthApi.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api; 2 | 3 | import com.getui.push.v2.sdk.anno.GtApi; 4 | import com.getui.push.v2.sdk.anno.method.GtDelete; 5 | import com.getui.push.v2.sdk.anno.method.GtPost; 6 | import com.getui.push.v2.sdk.anno.param.GtBodyParam; 7 | import com.getui.push.v2.sdk.anno.param.GtPathParam; 8 | import com.getui.push.v2.sdk.common.ApiResult; 9 | import com.getui.push.v2.sdk.dto.req.AuthDTO; 10 | import com.getui.push.v2.sdk.dto.res.TokenDTO; 11 | 12 | /** 13 | * 鉴权api 14 | * create by getui on 2020/6/4 15 | * 16 | * @author getui 17 | */ 18 | @GtApi 19 | public interface AuthApi { 20 | 21 | /** 22 | * 获取鉴权token接口 23 | * 24 | * @param authDTO 25 | * @return 26 | */ 27 | @GtPost(uri = "/auth", needToken = false) 28 | ApiResult auth(@GtBodyParam AuthDTO authDTO); 29 | 30 | /** 31 | * 关闭鉴权token 32 | * 33 | * @param token 34 | * @return 35 | */ 36 | @GtDelete(uri = "/auth") 37 | ApiResult close(@GtPathParam String token); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/api/PushApi.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api; 2 | 3 | import com.getui.push.v2.sdk.anno.method.GtDelete; 4 | import com.getui.push.v2.sdk.anno.method.GtGet; 5 | import com.getui.push.v2.sdk.anno.method.GtPost; 6 | import com.getui.push.v2.sdk.anno.param.GtBodyParam; 7 | import com.getui.push.v2.sdk.anno.param.GtPathParam; 8 | import com.getui.push.v2.sdk.common.ApiResult; 9 | import com.getui.push.v2.sdk.dto.req.Audience; 10 | import com.getui.push.v2.sdk.dto.req.AudienceDTO; 11 | import com.getui.push.v2.sdk.dto.req.message.PushBatchDTO; 12 | import com.getui.push.v2.sdk.dto.req.message.PushDTO; 13 | import com.getui.push.v2.sdk.dto.res.ScheduleTaskDTO; 14 | import com.getui.push.v2.sdk.dto.res.TaskIdDTO; 15 | 16 | import java.util.Map; 17 | 18 | /** 19 | * create by getui on 2020/6/7 20 | * 21 | * @author getui 22 | */ 23 | public interface PushApi { 24 | 25 | String singleCidUri = "/push/single/cid"; 26 | String singleCidByTagUri = "/push/single/cid_by_tag"; 27 | String singleAliasUri = "/push/single/alias"; 28 | String singleBatchCidUri = "/push/single/batch/cid"; 29 | String singleBatchAliasUri = "/push/single/batch/alias"; 30 | String pushListMessageUri = "/push/list/message"; 31 | String pushListCidUri = "/push/list/cid"; 32 | String pushListCidByTagUri = "/push/list/cid_by_tag"; 33 | String pushListAliasUri = "/push/list/alias"; 34 | 35 | /** 36 | * 根据cid推送 37 | * 38 | * @param pushDTO 39 | * @return k: cid, v: status 40 | */ 41 | @GtPost(uri = singleCidUri) 42 | ApiResult>> pushToSingleByCid(@GtBodyParam PushDTO pushDTO); 43 | 44 | /** 45 | * 根据标签条件过滤后的cid推送(异步) 46 | * 定制接口,需申请开通才可以使用 47 | * 48 | * @param pushDTO pushDTO 49 | * @return ApiResult 50 | */ 51 | @GtPost(uri = singleCidByTagUri) 52 | ApiResult>> pushToSingleCidByTag(@GtBodyParam PushDTO pushDTO); 53 | 54 | /** 55 | * 根据别名推送 56 | * 57 | * @param pushDTO 58 | * @return 59 | */ 60 | @GtPost(uri = singleAliasUri) 61 | ApiResult>> pushToSingleByAlias(@GtBodyParam PushDTO pushDTO); 62 | 63 | /** 64 | * 根据cid批量推送 65 | * 66 | * @param pushBatchDTO 67 | * @return 68 | */ 69 | @GtPost(uri = singleBatchCidUri) 70 | ApiResult>> pushBatchByCid(@GtBodyParam PushBatchDTO pushBatchDTO); 71 | 72 | /** 73 | * 根据标签条件过滤后的cid批量推送(异步) 74 | * 定制接口,需申请开通才可以使用 75 | * 76 | * @param audienceDTO audienceDTO 77 | * @return ApiResult 78 | */ 79 | @GtPost(uri = pushListCidByTagUri) 80 | ApiResult>> pushListCidByTag(@GtBodyParam AudienceDTO audienceDTO); 81 | 82 | /** 83 | * 根据别名批量推送 84 | * 85 | * @param pushBatchDTO 86 | * @return 87 | */ 88 | @GtPost(uri = singleBatchAliasUri) 89 | ApiResult>> pushBatchByAlias(@GtBodyParam PushBatchDTO pushBatchDTO); 90 | 91 | /** 92 | * 创建消息体 93 | * 94 | * @param pushDTO 95 | * @return 96 | */ 97 | @GtPost(uri = pushListMessageUri) 98 | ApiResult createMsg(@GtBodyParam PushDTO pushDTO); 99 | 100 | /** 101 | * 根据cid批量推送 102 | * 103 | * @param audienceDTO 104 | * @return 105 | */ 106 | @GtPost(uri = pushListCidUri) 107 | ApiResult>> pushListByCid(@GtBodyParam AudienceDTO audienceDTO); 108 | 109 | /** 110 | * 根据别名批量推送 111 | * 112 | * @param audienceDTO 113 | * @return 114 | */ 115 | @GtPost(uri = pushListAliasUri) 116 | ApiResult>> pushListByAlias(@GtBodyParam AudienceDTO audienceDTO); 117 | 118 | /** 119 | * 执行群推 120 | * 121 | * @param pushDTO 122 | * @return 123 | */ 124 | @GtPost(uri = "/push/all") 125 | ApiResult pushAll(@GtBodyParam PushDTO pushDTO); 126 | 127 | /** 128 | * 根据条件筛选用户推送 129 | * 130 | * @param pushDTO 131 | * @return 132 | */ 133 | @GtPost(uri = "/push/tag") 134 | ApiResult pushByTag(@GtBodyParam PushDTO pushDTO); 135 | 136 | /** 137 | * 使用标签快速推送 138 | * 139 | * @param pushDTO 140 | * @return 141 | */ 142 | @GtPost(uri = "/push/fast_custom_tag") 143 | ApiResult pushByFastCustomTag(@GtBodyParam PushDTO pushDTO); 144 | 145 | /** 146 | * 停止任务 147 | * 148 | * @param taskId 149 | * @return 150 | */ 151 | @GtDelete(uri = "/task") 152 | ApiResult stopPush(@GtPathParam String taskId); 153 | 154 | /** 155 | * 查询任务 156 | * 157 | * @param taskId 158 | * @return 159 | */ 160 | @GtGet(uri = "/task/schedule/") 161 | ApiResult> queryScheduleTask(@GtPathParam String taskId); 162 | 163 | /** 164 | * 删除定时任务 165 | * 166 | * @param taskId 167 | * @return 168 | */ 169 | @GtDelete(uri = "/task/schedule") 170 | ApiResult deleteScheduleTask(@GtPathParam String taskId); 171 | 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/api/StatisticApi.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api; 2 | 3 | import com.getui.push.v2.sdk.anno.method.GtGet; 4 | import com.getui.push.v2.sdk.anno.param.GtPathParam; 5 | import com.getui.push.v2.sdk.anno.param.GtQueryParam; 6 | import com.getui.push.v2.sdk.common.ApiResult; 7 | import com.getui.push.v2.sdk.dto.res.PushCountDTO; 8 | import com.getui.push.v2.sdk.dto.res.statistic.StatisticDTO; 9 | import com.getui.push.v2.sdk.dto.res.statistic.UserStatisticDTO; 10 | 11 | import java.util.Map; 12 | import java.util.Set; 13 | 14 | /** 15 | * 统计API 16 | * create by getui on 2020/6/7 17 | * 18 | * @author getui 19 | */ 20 | public interface StatisticApi { 21 | 22 | /** 23 | * 获取推送结果 24 | * 25 | * @param taskIds 26 | * @return 27 | */ 28 | @GtGet(uri = "/report/push/task/") 29 | ApiResult>> queryPushResultByTaskIds(@GtPathParam Set taskIds); 30 | 31 | /** 32 | * 获取推送结果 33 | * 34 | * @param taskIds 35 | * @param actionIds 36 | * @return 37 | */ 38 | @GtGet(uri = "/report/push/task/") 39 | ApiResult>> queryPushResultByTaskIdsAndActionIds(@GtPathParam Set taskIds, @GtQueryParam(name = "actionIdList") Set actionIds); 40 | 41 | /** 42 | * 根据组名查询报表 43 | * 44 | * @param groupName 45 | * @return 46 | */ 47 | @GtGet(uri = "/report/push/task_group/") 48 | ApiResult>> queryPushResultByGroupName(@GtPathParam String groupName); 49 | 50 | /** 51 | * 获取单日推送数据 52 | * 53 | * @param date formatted as yyyy-MM-dd 54 | * @return 55 | */ 56 | @GtGet(uri = "/report/push/date/") 57 | ApiResult>> queryPushResultByDate(@GtPathParam String date); 58 | 59 | /** 60 | * 获取单日用户数据 61 | * 62 | * @param date formatted as yyyy-MM-dd 63 | * @return 64 | */ 65 | @GtGet(uri = "/report/user/date/") 66 | ApiResult>> queryUserDataByDate(@GtPathParam String date); 67 | 68 | /** 69 | * 获取24小时在线用户数 70 | * 71 | * @return 72 | */ 73 | @GtGet(uri = "/report/online_user") 74 | ApiResult>> queryOnlineUserData(); 75 | 76 | 77 | /** 78 | * 查询推送量 79 | * 80 | * @return 81 | */ 82 | @GtGet(uri = "/report/push/count") 83 | ApiResult>> queryPushCountData(); 84 | 85 | /** 86 | * 获取推送实时结果 87 | * 88 | * @param taskIds 89 | * @return 90 | */ 91 | @GtGet(uri = "/report/push/task/${taskid}/detail") 92 | ApiResult>> queryPushTaskDetailData(@GtPathParam Set taskIds); 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/api/UserApi.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api; 2 | 3 | import com.getui.push.v2.sdk.anno.method.GtDelete; 4 | import com.getui.push.v2.sdk.anno.method.GtGet; 5 | import com.getui.push.v2.sdk.anno.method.GtPost; 6 | import com.getui.push.v2.sdk.anno.method.GtPut; 7 | import com.getui.push.v2.sdk.anno.param.GtBodyParam; 8 | import com.getui.push.v2.sdk.anno.param.GtPathParam; 9 | import com.getui.push.v2.sdk.anno.param.GtQueryParam; 10 | import com.getui.push.v2.sdk.common.ApiResult; 11 | import com.getui.push.v2.sdk.dto.req.*; 12 | import com.getui.push.v2.sdk.dto.res.AliasResDTO; 13 | import com.getui.push.v2.sdk.dto.res.CidStatusDTO; 14 | import com.getui.push.v2.sdk.dto.res.QueryCidResDTO; 15 | 16 | import java.util.List; 17 | import java.util.Map; 18 | import java.util.Set; 19 | 20 | /** 21 | * create by getui on 2020/6/4 22 | * 23 | * @author getui 24 | */ 25 | public interface UserApi { 26 | 27 | /** 28 | * 绑定别名 29 | * 30 | * @param cidAliasListDTO 31 | * @return 32 | */ 33 | @GtPost(uri = "/user/alias") 34 | ApiResult bindAlias(@GtBodyParam CidAliasListDTO cidAliasListDTO); 35 | 36 | /** 37 | * 根据cid查询别名 38 | * 39 | * @param cid 40 | * @return 41 | */ 42 | @GtGet(uri = "/user/alias/cid/") 43 | ApiResult queryAliasByCid(@GtPathParam String cid); 44 | 45 | /** 46 | * 根据cid查询指定别名类型下的别名 47 | * 48 | * @param cid 49 | * @param aliasType 别名类型 50 | * @return 51 | */ 52 | @GtGet(uri = "/user/alias/cid/") 53 | ApiResult queryAliasByCid(@GtPathParam String cid, @GtQueryParam(name = "alias_type") String aliasType); 54 | 55 | /** 56 | * 根据别名查询cid 57 | * 58 | * @param alias 59 | * @return 60 | */ 61 | @GtGet(uri = "/user/cid/alias/") 62 | ApiResult queryCidByAlias(@GtPathParam String alias); 63 | 64 | /** 65 | * 根据别名类型与别名查询cid 66 | * 67 | * @param alias 68 | * @param aliasType 69 | * @return 70 | */ 71 | @GtGet(uri = "/user/cid/alias/") 72 | ApiResult queryCidByAlias(@GtPathParam String alias, @GtQueryParam(name = "alias_type") String aliasType); 73 | 74 | /** 75 | * 批量解绑别名 76 | * 77 | * @param cidAliasListDTO 78 | * @return 79 | */ 80 | @GtDelete(uri = "/user/alias") 81 | ApiResult batchUnbindAlias(@GtBodyParam CidAliasListDTO cidAliasListDTO); 82 | 83 | /** 84 | * 解绑所有别名 85 | * 86 | * @param alias 别名 87 | * @return 88 | */ 89 | @GtDelete(uri = "/user/alias") 90 | ApiResult unbindAllAlias(@GtPathParam String alias); 91 | 92 | /** 93 | * 一个用户绑定一批标签 94 | * 95 | * @param cid 96 | * @param tagDTO 97 | * @return 98 | */ 99 | @GtPost(uri = "/user/custom_tag/cid/") 100 | ApiResult userBindTags(@GtPathParam String cid, @GtBodyParam TagDTO tagDTO); 101 | 102 | /** 103 | * 解绑指定别名类型下的别名 104 | * 105 | * @param alias 106 | * @param aliasType 107 | * @return 108 | */ 109 | @GtDelete(uri = "/user/alias") 110 | ApiResult unbindAllAlias(@GtPathParam String alias, @GtQueryParam(name = "alias_type") String aliasType); 111 | 112 | /** 113 | * 一批用户绑定一个标签 114 | * 115 | * @param customerTag 标签 116 | * @param userDTO 117 | * @return 118 | */ 119 | @GtPut(uri = "/user/custom_tag/batch/") 120 | ApiResult> usersBindTag(@GtPathParam String customerTag, @GtBodyParam UserDTO userDTO); 121 | 122 | /** 123 | * 删除标签 124 | * 125 | * @param customerTag 标签 126 | * @param userDTO 127 | * @return {@link ApiResult#getData()} map, k: cid; v: 删除状态 128 | */ 129 | @GtDelete(uri = "/user/custom_tag/batch/") 130 | ApiResult> deleteUsersTag(@GtPathParam String customerTag, @GtBodyParam UserDTO userDTO); 131 | 132 | /** 133 | * 查询用户标签 134 | * 135 | * @param cid 136 | * @return 137 | */ 138 | @GtGet(uri = "/user/custom_tag/cid/") 139 | ApiResult>> queryUserTags(@GtPathParam String cid); 140 | 141 | /** 142 | * 添加黑名单用户 143 | * 144 | * @param cidSet 145 | * @return 146 | */ 147 | @GtPost(uri = "/user/black/cid") 148 | ApiResult addBlackUser(@GtPathParam Set cidSet); 149 | 150 | /** 151 | * 移除黑名单用户 152 | * 153 | * @param cidSet 154 | * @return 155 | */ 156 | @GtDelete(uri = "/user/black/cid") 157 | ApiResult removeBlackUser(@GtPathParam Set cidSet); 158 | 159 | /** 160 | * 查询用户状态 161 | * 162 | * @param cidSet 163 | * @return 164 | */ 165 | @GtGet(uri = "/user/status") 166 | ApiResult> queryUserStatus(@GtPathParam Set cidSet); 167 | 168 | /** 169 | * 设置角标 170 | * 171 | * @param cidSet 172 | * @param badgeDTO 173 | * @return 174 | */ 175 | @GtPost(uri = "/user/badge/cid/") 176 | ApiResult setBadge(@GtPathParam Set cidSet, @GtBodyParam BadgeDTO badgeDTO); 177 | 178 | /** 179 | * 查询符合条件的用户总量 180 | * 181 | * @param conditionListDTO 查询条件 182 | * @return 183 | */ 184 | @GtPost(uri = "/user/count/") 185 | ApiResult> queryUser(@GtBodyParam ConditionListDTO conditionListDTO); 186 | 187 | } 188 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/ApiException.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common; 2 | 3 | /** 4 | * 此异常类不会打印堆栈 5 | * create by getui on 2020/4/25 6 | * 7 | * @author getui 8 | */ 9 | public class ApiException extends RuntimeException { 10 | 11 | private int code = 500; 12 | 13 | private String message; 14 | 15 | public ApiException(String message) { 16 | super(message, null); 17 | this.message = message; 18 | } 19 | 20 | public ApiException(String message, boolean writableStackTrace) { 21 | super(message, null); 22 | this.message = message; 23 | } 24 | 25 | public ApiException(String message, Throwable cause) { 26 | super(message, cause); 27 | this.message = message; 28 | } 29 | 30 | public ApiException(String message, int code) { 31 | super(message + "::" + code, null); 32 | this.code = code; 33 | this.message = message; 34 | } 35 | 36 | public ApiException(String message, int code, boolean writableStackTrace) { 37 | super(message + "::" + code, null); 38 | this.code = code; 39 | this.message = message; 40 | } 41 | 42 | public ApiException(String message, int code, Throwable throwable) { 43 | super(message + "::" + code, throwable); 44 | this.code = code; 45 | this.message = message; 46 | } 47 | 48 | public int getCode() { 49 | return code; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/ApiResult.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common; 2 | 3 | /** 4 | * create by getui on 2020/6/2 5 | * 6 | * @author getui 7 | */ 8 | public class ApiResult { 9 | 10 | protected int code; 11 | protected String msg; 12 | protected T data; 13 | 14 | public ApiResult() { 15 | } 16 | 17 | public ApiResult(String message, int code) { 18 | this.msg = message; 19 | this.code = code; 20 | } 21 | 22 | public static ApiResult success(T data) { 23 | return new ApiResult(data); 24 | } 25 | 26 | public static ApiResult success() { 27 | ApiResult apiResult = new ApiResult(); 28 | apiResult.code = 200; 29 | return apiResult; 30 | } 31 | 32 | public ApiResult(T data) { 33 | this.code = 200; 34 | this.data = data; 35 | } 36 | 37 | public static ApiResult fail(String msg, int code) { 38 | return new ApiResult(msg, code); 39 | } 40 | 41 | public boolean isSuccess() { 42 | return code == 0; 43 | } 44 | 45 | public int getCode() { 46 | return code; 47 | } 48 | 49 | public void setCode(int code) { 50 | this.code = code; 51 | } 52 | 53 | public String getMsg() { 54 | return msg; 55 | } 56 | 57 | public void setMsg(String msg) { 58 | this.msg = msg; 59 | } 60 | 61 | public T getData() { 62 | return data; 63 | } 64 | 65 | public void setData(T data) { 66 | this.data = data; 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return "ApiResult{" + 72 | "code=" + code + 73 | ", msg='" + msg + '\'' + 74 | ", data=" + data + 75 | '}'; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/Assert.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common; 2 | 3 | import com.getui.push.v2.sdk.common.util.Utils; 4 | 5 | import java.util.Collection; 6 | 7 | /** 8 | * create by getui on 2020/6/3 9 | * 10 | * @author getui 11 | */ 12 | public class Assert { 13 | 14 | public static void notEmpty(String param, String paramName, boolean writableStackTrace) { 15 | if (Utils.isEmpty(param)) { 16 | throw new ApiException(paramName + " 不能为空", 400, writableStackTrace); 17 | } 18 | } 19 | 20 | public static void notBlank(String param, String paramName) { 21 | if (Utils.isEmpty(param)) { 22 | throw new ApiException(paramName + " 不能为空", 400); 23 | } 24 | } 25 | 26 | public static void notBlank(String param) { 27 | if (Utils.isEmpty(param)) { 28 | throw new ApiException("参数不能为空", 400); 29 | } 30 | } 31 | 32 | public static void notBlank(String param, boolean writableStackTrace) { 33 | if (Utils.isEmpty(param)) { 34 | throw new ApiException("参数不能为空", 400, writableStackTrace); 35 | } 36 | } 37 | 38 | public static void notEmpty(Collection collection, String paramName) { 39 | if (Utils.isEmpty(collection)) { 40 | throw new ApiException(paramName + " 不能为空", 400); 41 | } 42 | } 43 | 44 | public static void notEmpty(Collection collection, String paramName, boolean writableStackTrace) { 45 | if (Utils.isEmpty(collection)) { 46 | throw new ApiException(paramName + " 不能为空", 400, writableStackTrace); 47 | } 48 | } 49 | 50 | public static void notNull(Object obj, String paramName) { 51 | if (obj == null) { 52 | throw new ApiException(paramName + " 不能为null", 400); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/Config.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common; 2 | 3 | import com.getui.push.v2.sdk.GtApiConfiguration; 4 | 5 | import java.nio.charset.Charset; 6 | 7 | /** 8 | * create by getui on 2020/10/26 9 | * 10 | * @author getui 11 | */ 12 | public class Config { 13 | public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); 14 | public static final Charset UTF_8 = Charset.forName("UTF-8"); 15 | public final static String CHECK_HEALTH_DATA_SWITCH_KEY = GtApiConfiguration.CHECK_HEALTH_DATA_SWITCH_KEY; 16 | public static final String AUTH_URI = "/auth"; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/Monitor.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common; 2 | 3 | import com.getui.push.v2.sdk.common.util.Utils; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.util.Iterator; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | import java.util.concurrent.atomic.AtomicInteger; 11 | 12 | /** 13 | * create by getui on 2024/4/8 14 | * 15 | * @author getui 16 | */ 17 | public class Monitor { 18 | private static Logger log = LoggerFactory.getLogger(Monitor.class); 19 | /** 20 | * 单位时间内失败总数 21 | */ 22 | static volatile Map hostToFailedNumMap; 23 | static volatile boolean MONITOR_ENABLE = false; 24 | 25 | public static void init(long refreshTimes) { 26 | hostToFailedNumMap = new ConcurrentHashMap<>(16); 27 | MONITOR_ENABLE = true; 28 | Thread thread = new Thread(() -> { 29 | while (true) { 30 | try { 31 | Thread.sleep(refreshTimes); 32 | log.debug("will reset monitor|{}", hostToFailedNumMap); 33 | Iterator> iterator = hostToFailedNumMap.entrySet().iterator(); 34 | while (iterator.hasNext()) { 35 | iterator.next().getValue().set(0); 36 | } 37 | } catch (Throwable e) { 38 | } 39 | } 40 | }); 41 | thread.setDaemon(true); 42 | thread.setName("gtResetMonitor"); 43 | thread.start(); 44 | } 45 | 46 | public static int get(String host) { 47 | if (!MONITOR_ENABLE || host == null) { 48 | return 0; 49 | } 50 | AtomicInteger num = hostToFailedNumMap.computeIfAbsent(Utils.v2UrlToHost(host), (k) -> new AtomicInteger()); 51 | return num.get(); 52 | } 53 | 54 | public static void reset(String host) { 55 | if (!MONITOR_ENABLE || host == null) { 56 | return; 57 | } 58 | AtomicInteger num = hostToFailedNumMap.computeIfAbsent(Utils.v2UrlToHost(host), (k) -> new AtomicInteger()); 59 | num.set(0); 60 | } 61 | 62 | public static void incrementFailedNum(String host) { 63 | if (!MONITOR_ENABLE || host == null) { 64 | return; 65 | } 66 | AtomicInteger num = hostToFailedNumMap.computeIfAbsent(Utils.v2UrlToHost(host), (k) -> new AtomicInteger()); 67 | num.incrementAndGet(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/Strings.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.StringTokenizer; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | /** 10 | * Created by xiaoxu.yxx on 2014/6/23. 11 | */ 12 | public final class Strings { 13 | /** 14 | * 连接字符串数组, 15 | * 16 | * @param array 17 | * @return 18 | */ 19 | public static String join(CharSequence... array) { 20 | return join(array, ""); 21 | } 22 | 23 | /** 24 | * 连接字符串数组, 25 | * 26 | * @return 27 | */ 28 | public static String join(String separator, CharSequence... array) { 29 | return join(array, separator); 30 | } 31 | 32 | /** 33 | * 连接字符串数组, 34 | * 35 | * @return 36 | */ 37 | public static String join(Object[] array) { 38 | return join(array, ""); 39 | } 40 | 41 | /** 42 | * 连接字符串数组, 43 | * 44 | * @return 45 | */ 46 | public static String join(Object[] array, String separator) { 47 | return join(array, separator, 0, array.length); 48 | } 49 | 50 | /** 51 | * 连接字符串数组, 52 | * 53 | * @return 54 | */ 55 | public static String join(Object[] array, char separator) { 56 | return join(array, separator, 0, array.length); 57 | } 58 | 59 | /** 60 | * 连接字符串数组, 61 | * 62 | * @return 63 | */ 64 | public static String join(Object[] array, String separator, int startIndex, int endIndex) { 65 | if (array == null) return null; 66 | if (separator == null) separator = ""; 67 | int L = endIndex - startIndex; 68 | if (L <= 0) return ""; 69 | StringBuilder sb = new StringBuilder(L * (array[startIndex] == null ? 16 : array[startIndex].toString().length()) 70 | + separator.length()); 71 | for (int i = startIndex; i < endIndex; i++) { 72 | if (array[i] != null) { 73 | sb.append(array[i]).append(separator); 74 | } 75 | } 76 | int index = sb.lastIndexOf(separator); 77 | if (index != -1) sb.delete(index, sb.length()); 78 | return sb.toString(); 79 | } 80 | 81 | /** 82 | * 连接字符串数组, 83 | * 84 | * @return 85 | */ 86 | public static String join(Object[] array, char separator, int startIndex, int endIndex) { 87 | if (array == null) return null; 88 | int L = endIndex - startIndex; 89 | if (L <= 0) return ""; 90 | StringBuilder sb = new StringBuilder(L * (array[startIndex] == null ? 16 : array[startIndex].toString().length()) + 1); 91 | for (int i = startIndex; i < endIndex; i++) { 92 | if (array[i] != null) { 93 | sb.append(array[i]).append(separator); 94 | } 95 | } 96 | int index = sb.lastIndexOf(separator + ""); 97 | if (index != -1) sb.deleteCharAt(index); 98 | return sb.toString(); 99 | } 100 | 101 | /** 102 | * 连接字符串数组, 103 | * 104 | * @return 105 | */ 106 | public static String join(Iterable iterable, String separator) { 107 | if (iterable == null) return null; 108 | StringBuilder sb = new StringBuilder(); 109 | for (T t : iterable) { 110 | if (t != null) sb.append(t).append(separator); 111 | } 112 | int index = sb.lastIndexOf(separator); 113 | if (index != -1) sb.delete(index, separator.length() + index); 114 | return sb.toString(); 115 | } 116 | 117 | public static List split(String regex, CharSequence input) { 118 | int index = 0; 119 | List matchList = new ArrayList(); 120 | Matcher m = Pattern.compile(regex).matcher(input); 121 | while (m.find()) { 122 | matchList.add(input.subSequence(index, m.start()).toString()); 123 | index = m.end(); 124 | } 125 | if (index < input.length()) 126 | matchList.add(input.subSequence(index, input.length()).toString()); 127 | return matchList; 128 | } 129 | 130 | 131 | /** 132 | * 将字符串每个单词首字母大写 133 | * 134 | * @param s 字符串 135 | * @return 首字母大写后的新字符串 136 | */ 137 | public static String capitalize(CharSequence s) { 138 | return capitalize(s, " \t\r\n"); 139 | } 140 | 141 | public static String capitalize(CharSequence s, String separator) { 142 | StringTokenizer st = new StringTokenizer(s.toString(), separator, true); 143 | StringBuilder sb = new StringBuilder(s.length()); 144 | while (st.hasMoreTokens()) { 145 | String tok = st.nextToken(); 146 | sb.append(tok.substring(0, 1).toUpperCase()) 147 | .append(tok.substring(1).toLowerCase()); 148 | } 149 | return sb.toString(); 150 | } 151 | 152 | /** 153 | * 将字符串首字母小写 154 | * 155 | * @param s 字符串 156 | * @return 首字母小写后的新字符串 157 | */ 158 | public static String lowerFirst(CharSequence s) { 159 | int len = s.length(); 160 | if (len == 0) return ""; 161 | char c = s.charAt(0); 162 | if (Character.isLowerCase(c)) return s.toString(); 163 | return new StringBuilder(len).append(Character.toLowerCase(c)) 164 | .append(s.subSequence(1, len)).toString(); 165 | } 166 | 167 | /** 168 | * 将字符串首字母大写 169 | * 170 | * @param s 171 | * @return 172 | */ 173 | public static String upperFirst(CharSequence s) { 174 | int len = s.length(); 175 | if (len == 0) return ""; 176 | char c = s.charAt(0); 177 | if (Character.isUpperCase(c)) return s.toString(); 178 | return new StringBuilder(len).append(Character.toUpperCase(c)) 179 | .append(s.subSequence(1, len)).toString(); 180 | } 181 | 182 | /** 183 | * 检查两个字符串的忽略大小写后是否相等. 184 | * 185 | * @param s1 字符串A 186 | * @param s2 字符串B 187 | * @return true 如果两个字符串忽略大小写后相等,且两个字符串均不为null 188 | */ 189 | public static boolean equalsIgnoreCase(String s1, String s2) { 190 | return s1 == null ? s2 == null : s1.equalsIgnoreCase(s2); 191 | } 192 | 193 | public static boolean equalsIgnoreCase(Object obj, String str) { 194 | return obj == null ? str == null : valueOf(obj).equalsIgnoreCase(str); 195 | } 196 | 197 | /** 198 | * 检查两个字符串是否相等. 199 | * 200 | * @param s1 字符串A 201 | * @param s2 字符串B 202 | * @return true 如果两个字符串相等,且两个字符串均不为null 203 | */ 204 | public static boolean equals(CharSequence s1, CharSequence s2) { 205 | return s1 == null ? s2 == null : s1.equals(s2); 206 | } 207 | 208 | /** 209 | * 判断字符串是否以特殊字符开头 210 | * 211 | * @param s 字符串 212 | * @param c 特殊字符 213 | * @return 是否以特殊字符开头 214 | */ 215 | public static boolean startsWithChar(CharSequence s, char c) { 216 | return null != s && (s.length() != 0 && s.charAt(0) == c); 217 | } 218 | 219 | /** 220 | * 判断字符串是否以特殊字符结尾 221 | * 222 | * @param s 字符串 223 | * @param c 特殊字符 224 | * @return 是否以特殊字符结尾 225 | */ 226 | public static boolean endsWithChar(CharSequence s, char c) { 227 | return null != s && (s.length() != 0 && s.charAt(s.length() - 1) == c); 228 | } 229 | 230 | public static boolean isEmpty(CharSequence... css) { 231 | for (CharSequence cs : css) { 232 | if (isEmpty(cs)) return true; 233 | } 234 | return false; 235 | } 236 | 237 | /** 238 | * @param cs 字符串 239 | * @return 是不是为空字符串 240 | */ 241 | public static boolean isEmpty(CharSequence cs) { 242 | return null == cs || cs.length() == 0; 243 | } 244 | 245 | public static boolean isNotEmpty(CharSequence cs) { 246 | return null != cs && cs.length() > 0; 247 | } 248 | 249 | public static boolean isNotEmpty(CharSequence... css) { 250 | for (CharSequence cs : css) { 251 | if (isEmpty(cs)) return false; 252 | } 253 | return true; 254 | } 255 | 256 | /** 257 | * @param cs 字符串 258 | * @return 是不是为空白字符串 259 | */ 260 | public static boolean isBlank(CharSequence cs) { 261 | int L; 262 | if (cs == null || (L = cs.length()) == 0) 263 | return true; 264 | for (int i = 0; i < L; i++) { 265 | if (!Character.isWhitespace(cs.charAt(i))) { 266 | return false; 267 | } 268 | } 269 | return true; 270 | } 271 | 272 | public static boolean isNotBlank(CharSequence str) { 273 | return !isBlank(str); 274 | } 275 | 276 | /** 277 | * 去掉字符串前后空白 278 | * 279 | * @param cs 字符串 280 | * @return 新字符串 281 | */ 282 | public static String trim(CharSequence cs) { 283 | if (null == cs) 284 | return null; 285 | if (cs instanceof String) 286 | return ((String) cs).trim(); 287 | int length = cs.length(); 288 | if (length == 0) 289 | return cs.toString(); 290 | int l = 0; 291 | int last = length - 1; 292 | int r = last; 293 | for (; l < length; l++) { 294 | if (!Character.isWhitespace(cs.charAt(l))) 295 | break; 296 | } 297 | for (; r > l; r--) { 298 | if (!Character.isWhitespace(cs.charAt(r))) 299 | break; 300 | } 301 | if (l > r) 302 | return ""; 303 | else if (l == 0 && r == last) 304 | return cs.toString(); 305 | return cs.subSequence(l, r + 1).toString(); 306 | } 307 | 308 | public static String valueOf(Object o, String defaultVal) { 309 | return o == null ? defaultVal : o.toString(); 310 | } 311 | 312 | public static String valueOf(Object o) { 313 | return Strings.valueOf(o, ""); 314 | } 315 | 316 | } 317 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/http/GtHttpDelete.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common.http; 2 | 3 | import org.apache.http.client.methods.HttpDelete; 4 | import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; 5 | 6 | import java.net.URI; 7 | 8 | /** 9 | * create by getui on 2020/10/28 10 | * 11 | * @author getui 12 | */ 13 | public class GtHttpDelete extends HttpEntityEnclosingRequestBase { 14 | 15 | public GtHttpDelete(final String uri) { 16 | super(); 17 | setURI(URI.create(uri)); 18 | } 19 | 20 | @Override 21 | public String getMethod() { 22 | return HttpDelete.METHOD_NAME; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/http/HttpManager.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common.http; 2 | 3 | import com.getui.push.v2.sdk.GtApiConfiguration; 4 | import com.getui.push.v2.sdk.GtHttpProxyConfig; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author lg 11 | * @version V1.0 12 | * @Title: HttpManager.java 13 | * @Package com.gexin.rp.sdk.http 14 | * @date 2012-9-5 下午4:46:50 15 | */ 16 | public class HttpManager { 17 | 18 | private GtHttpClient client; 19 | 20 | /** 21 | * @param connectionTimeOut 连接超时时间 22 | * @param readTimeout 读超时时间 23 | * @param connectionRequestTimeout 从连接池中获取连接的超时时间 24 | * @param maxHttpTryTime 失败最大尝试次数 25 | * @param trustSSL 26 | */ 27 | public HttpManager(int connectionTimeOut, int readTimeout, int connectionRequestTimeout, int maxHttpTryTime, long keepAliveSeconds, GtHttpProxyConfig proxyConfig, boolean trustSSL) { 28 | this.client = new GtHttpClient(connectionTimeOut, readTimeout, connectionRequestTimeout, maxHttpTryTime, keepAliveSeconds, proxyConfig, trustSSL); 29 | } 30 | 31 | public String syncHttps(String url, String method, Map headers, String body, String contentType) { 32 | return syncHttps(url, null, 0, method, headers, body, contentType); 33 | } 34 | 35 | /** 36 | * @param url 37 | * @param rasDomain 天上的域名,失败重试时,会修改域名。空或null时失败重试不切换域名 38 | * @param socketTimeout 接口超时时间,0表示默认,默认值为{@link GtApiConfiguration#getSoTimeout()} 39 | * @param method 40 | * @param headers 41 | * @param body 42 | * @param contentType 43 | * @return 44 | */ 45 | public String syncHttps(String url, List rasDomain, int socketTimeout, String method, Map headers, String body, String contentType) { 46 | return client.execute(url, rasDomain, socketTimeout, method, headers, body, contentType); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/type/ParameterizedTypeImpl.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common.type; 2 | 3 | import java.lang.reflect.MalformedParameterizedTypeException; 4 | import java.lang.reflect.ParameterizedType; 5 | import java.lang.reflect.Type; 6 | import java.lang.reflect.TypeVariable; 7 | import java.util.Arrays; 8 | 9 | /** 10 | * Implementing class for ParameterizedType interface. 11 | * 具体请看 {@link sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl} 12 | */ 13 | public class ParameterizedTypeImpl implements ParameterizedType { 14 | private final Type[] actualTypeArguments; 15 | private final Class rawType; 16 | private final Type ownerType; 17 | 18 | private ParameterizedTypeImpl(Class rawType, 19 | Type[] actualTypeArguments, 20 | Type ownerType) { 21 | this.actualTypeArguments = actualTypeArguments; 22 | this.rawType = rawType; 23 | this.ownerType = (ownerType != null) ? ownerType : rawType.getDeclaringClass(); 24 | validateConstructorArguments(); 25 | } 26 | 27 | private void validateConstructorArguments() { 28 | TypeVariable[] formals = rawType.getTypeParameters(); 29 | // check correct arity of actual type args 30 | if (formals.length != actualTypeArguments.length) { 31 | throw new MalformedParameterizedTypeException(); 32 | } 33 | for (int i = 0; i < actualTypeArguments.length; i++) { 34 | // check actuals against formals' bounds 35 | } 36 | } 37 | 38 | /** 39 | * Static factory. Given a (generic) class, actual type arguments 40 | * and an owner type, creates a parameterized type. 41 | * This class can be instantiated with a raw type that does not 42 | * represent a generic type, provided the list of actual type 43 | * arguments is empty. 44 | * If the ownerType argument is null, the declaring class of the 45 | * raw type is used as the owner type. 46 | *

This method throws a MalformedParameterizedTypeException 47 | * under the following circumstances: 48 | * If the number of actual type arguments (i.e., the size of the 49 | * array {@code typeArgs}) does not correspond to the number of 50 | * formal type arguments. 51 | * If any of the actual type arguments is not an instance of the 52 | * bounds on the corresponding formal. 53 | * 54 | * @param rawType the Class representing the generic type declaration being 55 | * instantiated 56 | * @param actualTypeArguments a (possibly empty) array of types 57 | * representing the actual type arguments to the parameterized type 58 | * @param ownerType the enclosing type, if known. 59 | * @return An instance of {@code ParameterizedType} 60 | * @throws MalformedParameterizedTypeException if the instantiation 61 | * is invalid 62 | */ 63 | public static ParameterizedTypeImpl make(Class rawType, 64 | Type[] actualTypeArguments, 65 | Type ownerType) { 66 | return new ParameterizedTypeImpl(rawType, actualTypeArguments, 67 | ownerType); 68 | } 69 | 70 | 71 | /** 72 | * Returns an array of {@code Type} objects representing the actual type 73 | * arguments to this type. 74 | * 75 | *

Note that in some cases, the returned array be empty. This can occur 76 | * if this type represents a non-parameterized type nested within 77 | * a parameterized type. 78 | * 79 | * @return an array of {@code Type} objects representing the actual type 80 | * arguments to this type 81 | * @throws TypeNotPresentException if any of the 82 | * actual type arguments refers to a non-existent type declaration 83 | * @throws MalformedParameterizedTypeException if any of the 84 | * actual type parameters refer to a parameterized type that cannot 85 | * be instantiated for any reason 86 | * @since 1.5 87 | */ 88 | @Override 89 | public Type[] getActualTypeArguments() { 90 | return actualTypeArguments.clone(); 91 | } 92 | 93 | /** 94 | * Returns the {@code Type} object representing the class or interface 95 | * that declared this type. 96 | * 97 | * @return the {@code Type} object representing the class or interface 98 | * that declared this type 99 | */ 100 | @Override 101 | public Class getRawType() { 102 | return rawType; 103 | } 104 | 105 | 106 | /** 107 | * Returns a {@code Type} object representing the type that this type 108 | * is a member of. For example, if this type is {@code O.I}, 109 | * return a representation of {@code O}. 110 | * 111 | *

If this type is a top-level type, {@code null} is returned. 112 | * 113 | * @return a {@code Type} object representing the type that 114 | * this type is a member of. If this type is a top-level type, 115 | * {@code null} is returned 116 | * @throws TypeNotPresentException if the owner type 117 | * refers to a non-existent type declaration 118 | * @throws MalformedParameterizedTypeException if the owner type 119 | * refers to a parameterized type that cannot be instantiated 120 | * for any reason 121 | */ 122 | @Override 123 | public Type getOwnerType() { 124 | return ownerType; 125 | } 126 | 127 | /** 128 | * From the JavaDoc for java.lang.reflect.ParameterizedType 129 | * "Instances of classes that implement this interface must 130 | * implement an equals() method that equates any two instances 131 | * that share the same generic type declaration and have equal 132 | * type parameters." 133 | */ 134 | @Override 135 | public boolean equals(Object o) { 136 | if (o instanceof ParameterizedType) { 137 | // Check that information is equivalent 138 | ParameterizedType that = (ParameterizedType) o; 139 | 140 | if (this == that) { 141 | return true; 142 | } 143 | 144 | Type thatOwner = that.getOwnerType(); 145 | Type thatRawType = that.getRawType(); 146 | 147 | return 148 | equals(ownerType, thatOwner) && 149 | equals(rawType, thatRawType) && 150 | Arrays.equals(actualTypeArguments, 151 | that.getActualTypeArguments()); 152 | } else { 153 | return false; 154 | } 155 | } 156 | 157 | @Override 158 | public int hashCode() { 159 | return 160 | Arrays.hashCode(actualTypeArguments) ^ 161 | hashCode(ownerType) ^ 162 | hashCode(rawType); 163 | } 164 | 165 | boolean equals(Object a, Object b) { 166 | return (a == b) || (a != null && a.equals(b)); 167 | } 168 | 169 | int hashCode(Object o) { 170 | return o != null ? o.hashCode() : 0; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/type/TypeReference.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common.type; 2 | 3 | 4 | import java.lang.reflect.ParameterizedType; 5 | import java.lang.reflect.Type; 6 | 7 | /** 8 | * This generic abstract class is used for obtaining full generics type information 9 | * by sub-classing; it must be converted to {@code com.fasterxml.jackson.core.type.ResolvedType} implementation 10 | * (implemented by JavaType from "databind" bundle) to be used. 11 | * Class is based on ideas from 12 | * http://gafter.blogspot.com/2006/12/super-type-tokens.html, 14 | * Additional idea (from a suggestion made in comments of the article) 15 | * is to require bogus implementation of Comparable 16 | * (any such generic interface would do, as long as it forces a method 17 | * with generic type to be implemented). 18 | * to ensure that a Type argument is indeed given. 19 | *

20 | * Usage is by sub-classing: here is one way to instantiate reference 21 | * to generic type List<Integer>: 22 | *

23 |  *  TypeReference ref = new TypeReference<List<Integer>>() { };
24 |  * 
25 | * which can be passed to methods that accept TypeReference, or resolved 26 | * using TypeFactory to obtain {@code com.fasterxml.jackson.core.type.ResolvedType}. 27 | */ 28 | public abstract class TypeReference implements Comparable> { 29 | protected final Type _type; 30 | 31 | protected TypeReference() { 32 | Type superClass = getClass().getGenericSuperclass(); 33 | if (superClass instanceof Class) { // sanity check, should never happen 34 | throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information"); 35 | } 36 | /* 22-Dec-2008, tatu: Not sure if this case is safe -- I suspect 37 | * it is possible to make it fail? 38 | * But let's deal with specific 39 | * case when we know an actual use case, and thereby suitable 40 | * workarounds for valid case(s) and/or error to throw 41 | * on invalid one(s). 42 | */ 43 | _type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; 44 | } 45 | 46 | public Type getType() { 47 | return _type; 48 | } 49 | 50 | /** 51 | * The only reason we define this method (and require implementation 52 | * of Comparable) is to prevent constructing a 53 | * reference without type information. 54 | */ 55 | @Override 56 | public int compareTo(TypeReference o) { 57 | return 0; 58 | } 59 | // just need an implementation, not a good one... hence ^^^ 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/common/util/Utils.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.common.util; 2 | 3 | import com.getui.push.v2.sdk.common.Strings; 4 | 5 | import java.util.Collection; 6 | import java.util.Map; 7 | 8 | public final class Utils { 9 | 10 | public static boolean isEmpty(Map map) { 11 | return map == null || map.size() == 0; 12 | } 13 | 14 | public static boolean isNotEmpty(Map map) { 15 | return map != null && map.size() > 0; 16 | } 17 | 18 | public static boolean isEmpty(Collection collection) { 19 | return collection == null || collection.size() == 0; 20 | } 21 | 22 | public static boolean isNotEmpty(Collection collection) { 23 | return collection != null && collection.size() > 0; 24 | } 25 | 26 | public static boolean isEmpty(CharSequence sequence) { 27 | return Strings.isBlank(sequence); 28 | } 29 | 30 | public static boolean isNotEmpty(CharSequence sequence) { 31 | return Strings.isNotBlank(sequence); 32 | } 33 | 34 | public static boolean isEmpty(Object[] array) { 35 | return array == null || array.length == 0; 36 | } 37 | 38 | public static boolean isNotEmpty(Object[] array) { 39 | return array != null && array.length > 0; 40 | } 41 | 42 | public static boolean isEmpty(byte[] array) { 43 | return array == null || array.length == 0; 44 | } 45 | 46 | public static boolean isNotEmpty(byte[] array) { 47 | return array != null && array.length > 0; 48 | } 49 | 50 | 51 | public static boolean isNumeric(final CharSequence cs) { 52 | if (isEmpty(cs)) { 53 | return false; 54 | } 55 | final int sz = cs.length(); 56 | for (int i = 0; i < sz; i++) { 57 | if (!Character.isDigit(cs.charAt(i))) { 58 | return false; 59 | } 60 | } 61 | return true; 62 | } 63 | 64 | static final String v2UrlPrefix = "/v2"; 65 | 66 | /** 67 | * 对于v2的接口,一定存在/v2前缀 68 | * 69 | * @param url 70 | * @return 71 | */ 72 | public static String v2UrlToHost(String url) { 73 | int v2Index = url.indexOf(v2UrlPrefix); 74 | if (v2Index > 0) { 75 | return url.substring(0, v2Index); 76 | } else { 77 | return url; 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/Configs.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * create by getui on 2020/9/28 8 | * 9 | * @author getui 10 | */ 11 | public interface Configs { 12 | int MAX_FAIL_CONTINUOUSLY = 3; 13 | 14 | String HEADER_DOMAIN_HASH_KEY = "domainHash"; 15 | String HEADER_OPEN_STABLE_DOMAIN = "openStableDomain"; 16 | String SDK_VERSION = "1.0.6.0"; 17 | /** 18 | * 预置域名列表 19 | */ 20 | List URLS = new ArrayList() { 21 | { 22 | this.add("https://restapi.getui.com/v2/"); 23 | this.add("https://cncrestapi.getui.com/v2/"); 24 | this.add("https://nzrestapi.getui.com/v2/"); 25 | } 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/DefaultJson.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core; 2 | 3 | import com.getui.push.v2.sdk.IJson; 4 | import com.getui.push.v2.sdk.dto.res.statistic.StatisticDTO; 5 | import com.google.gson.*; 6 | 7 | import java.lang.reflect.Type; 8 | import java.text.NumberFormat; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | 13 | /** 14 | * create by getui on 2020/9/25 15 | * 16 | * @author getui 17 | */ 18 | public class DefaultJson implements IJson { 19 | private static final Gson GSON = createGson(); 20 | 21 | public static Gson createGson() { 22 | GsonBuilder gsonBuilder = new GsonBuilder(); 23 | gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); 24 | gsonBuilder.registerTypeAdapter(StatisticDTO.class, new JsonDeserializer() { 25 | @Override 26 | public StatisticDTO deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 27 | StatisticDTO statisticDTO = new StatisticDTO(); 28 | JsonObject jo = json.getAsJsonObject(); 29 | for (Map.Entry mx : jo.entrySet()) { 30 | String key = mx.getKey(); 31 | JsonElement v = mx.getValue(); 32 | if (v.isJsonArray()) { 33 | statisticDTO.put(key, context.deserialize(v, List.class)); 34 | } else if (v.isJsonPrimitive()) { 35 | Object value = v.getAsString(); 36 | try { 37 | Number numValue = NumberFormat.getInstance().parse((String) value); 38 | if (numValue != null && numValue.toString().equals(value)) { 39 | if (numValue instanceof Long && (Long) numValue <= Integer.MAX_VALUE && (Long) numValue >= Integer.MIN_VALUE) { 40 | value = Integer.valueOf((String) value); 41 | } else { 42 | value = numValue; 43 | } 44 | } 45 | } catch (Exception ignored) { 46 | } 47 | statisticDTO.put(key, value); 48 | } else if (v.isJsonObject()) { 49 | statisticDTO.put(key, context.deserialize(v, Map.class)); 50 | } 51 | } 52 | return statisticDTO; 53 | } 54 | }); 55 | return gsonBuilder.create(); 56 | } 57 | 58 | 59 | @Override 60 | public String toJson(Object obj) { 61 | if (obj == null) { 62 | return null; 63 | } 64 | return GSON.toJson(obj); 65 | } 66 | 67 | @Override 68 | public T fromJson(String jsonString, Type type) { 69 | return GSON.fromJson(jsonString, type); 70 | } 71 | 72 | @Override 73 | public T fromJson(String jsonString, Class tClass) { 74 | return GSON.fromJson(jsonString, tClass); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/domain/DomainCheck.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.domain; 2 | 3 | import com.getui.push.v2.sdk.common.util.Utils; 4 | 5 | import java.util.*; 6 | 7 | /** 8 | * create by getui on 2020/7/21 9 | * 10 | * @author getui 11 | */ 12 | public class DomainCheck { 13 | 14 | private IDomainCheck check; 15 | 16 | /** 17 | * 检测次数 18 | */ 19 | private final int checkSize; 20 | 21 | public DomainCheck(IDomainCheck check) { 22 | this(check, 20); 23 | } 24 | 25 | public DomainCheck(IDomainCheck check, int checkSize) { 26 | this.check = check; 27 | this.checkSize = checkSize; 28 | } 29 | 30 | /** 31 | * 优先级+稳定性 域名排序 32 | */ 33 | public List sort(List list) { 34 | Map domainTOGapMap = initGap(list); 35 | List domainList = getALlDomain(list); 36 | Map map = doCheck(domainList, domainTOGapMap); 37 | return doSort(map); 38 | } 39 | 40 | /** 41 | * @param list 42 | * @return 43 | */ 44 | private List getALlDomain(List list) { 45 | List domainList = new ArrayList(); 46 | for (DomainListBO domainListBO : list) { 47 | if (Utils.isNotEmpty(domainListBO.getDomainList())) { 48 | domainList.addAll(domainListBO.getDomainList()); 49 | } 50 | } 51 | return domainList; 52 | } 53 | 54 | private Map doCheck(List domainList, Map domainToGapMap) { 55 | Map detectMap = new HashMap(domainList.size(), 1); 56 | for (int i = 0; i < checkSize; i++) { 57 | //遍历所有的域名进行探测 58 | for (String domain : domainList) { 59 | //遍历所有的域名进行探测 60 | if (detectMap.get(domain) == null) { 61 | detectMap.put(domain, 0); 62 | } 63 | boolean rst = false; 64 | try { 65 | rst = check.check(domain); 66 | } catch (Exception e) { 67 | } 68 | if (rst) { 69 | detectMap.put(domain, detectMap.get(domain) + 1); 70 | } 71 | } 72 | try { 73 | //拉长时间保证稳定性 74 | Thread.sleep(1000); 75 | } catch (InterruptedException e) { 76 | e.printStackTrace(); 77 | } 78 | } 79 | //是否所有域名不可用 80 | boolean allBad = true; 81 | //算出 域名-稳定分数 82 | for (Map.Entry entry : detectMap.entrySet()) { 83 | if (entry.getValue() != 0) { 84 | allBad = false; 85 | } 86 | String key = entry.getKey(); 87 | int score = (entry.getValue() * 100) / checkSize + domainToGapMap.get(key); 88 | detectMap.put(key, score); 89 | } 90 | if (allBad) { 91 | return Collections.emptyMap(); 92 | } 93 | return detectMap; 94 | } 95 | 96 | /** 97 | * 排序 98 | */ 99 | private List doSort(Map detectMap) { 100 | List result = new ArrayList(); 101 | if (detectMap == null || detectMap.size() == 0) { 102 | return null; 103 | } 104 | String domain = null; 105 | Integer max = 0; 106 | while (detectMap.size() != 0) { 107 | for (Map.Entry entry : detectMap.entrySet()) { 108 | if (entry.getValue() >= max) { 109 | max = entry.getValue(); 110 | domain = entry.getKey(); 111 | } 112 | } 113 | max = 0; 114 | result.add(domain); 115 | detectMap.remove(domain); 116 | } 117 | return result; 118 | } 119 | 120 | private Map initGap(List list) { 121 | //获取所有的 域名-优先级gap 122 | Map map = new HashMap(list.size(), 1); 123 | int gap = 0; 124 | for (int i = list.size() - 1; i >= 0; i--) { 125 | if (i != list.size() - 1) { 126 | gap += list.get(i).getPriorityGap(); 127 | } 128 | for (String t : list.get(i).getDomainList()) { 129 | map.put(t, gap); 130 | } 131 | } 132 | return map; 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/domain/DomainListBO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.domain; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class DomainListBO { 7 | private List domainList; 8 | private Integer priorityGap = 30; 9 | 10 | public List getDomainList() { 11 | return domainList; 12 | } 13 | 14 | public void setDomainList(List domainList) { 15 | this.domainList = domainList; 16 | } 17 | 18 | public Integer getPriorityGap() { 19 | return priorityGap; 20 | } 21 | 22 | public void setPriorityGap(Integer priorityGap) { 23 | this.priorityGap = priorityGap; 24 | } 25 | 26 | public void addDomain(String domainBO) { 27 | if (domainList == null) { 28 | domainList = new ArrayList(); 29 | } 30 | domainList.add(domainBO); 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | final StringBuffer sb = new StringBuffer("DomainListBO{"); 36 | sb.append("domainList=").append(domainList); 37 | sb.append(", priorityGap=").append(priorityGap); 38 | sb.append('}'); 39 | return sb.toString(); 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/domain/IDomainCheck.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.domain; 2 | 3 | /** 4 | * create by getui on 2020/7/21 5 | * 6 | * @author getui 7 | */ 8 | public interface IDomainCheck { 9 | 10 | /** 11 | * 域名检测 12 | * 13 | * @param url 14 | * @return true表示成功,false表示失败,成功数越多,表示域名可用性越高 15 | */ 16 | boolean check(String url); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/domain/RasDomainBO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.domain; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * create by getui on 2020/9/28 7 | * 8 | * @author getui 9 | */ 10 | public class RasDomainBO { 11 | private List hostList; 12 | /** 13 | * MD5({@link #hostList}) 14 | */ 15 | private String domainHash; 16 | 17 | public List getHostList() { 18 | return hostList; 19 | } 20 | 21 | public void setHostList(List hostList) { 22 | this.hostList = hostList; 23 | } 24 | 25 | public String getDomainHash() { 26 | return domainHash; 27 | } 28 | 29 | public void setDomainHash(String domainHash) { 30 | this.domainHash = domainHash; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | final StringBuffer sb = new StringBuffer("RasDomainBO{"); 36 | sb.append("rasHostList=").append(hostList); 37 | sb.append(", domainHash='").append(domainHash).append('\''); 38 | sb.append('}'); 39 | return sb.toString(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/factory/GtApiProxyFactory.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.factory; 2 | 3 | import com.getui.push.v2.sdk.anno.param.GtBodyParam; 4 | import com.getui.push.v2.sdk.anno.param.GtPathParam; 5 | import com.getui.push.v2.sdk.anno.param.GtQueryParam; 6 | import com.getui.push.v2.sdk.common.ApiException; 7 | import com.getui.push.v2.sdk.common.Assert; 8 | import com.getui.push.v2.sdk.core.client.DefaultApiClient; 9 | import com.getui.push.v2.sdk.core.registry.DefaultGtApiRegistry; 10 | import com.getui.push.v2.sdk.core.registry.GtApiRegistry; 11 | 12 | import java.lang.annotation.Annotation; 13 | import java.lang.reflect.InvocationHandler; 14 | import java.lang.reflect.Method; 15 | import java.lang.reflect.Proxy; 16 | import java.lang.reflect.Type; 17 | import java.util.ArrayList; 18 | import java.util.Iterator; 19 | import java.util.List; 20 | import java.util.concurrent.ConcurrentHashMap; 21 | import java.util.concurrent.ConcurrentMap; 22 | 23 | /** 24 | * create by getui on 2020/6/4 25 | * 26 | * @author getui 27 | */ 28 | public class GtApiProxyFactory { 29 | 30 | /** 31 | * 保证一个{@link DefaultApiClient}对象对应一个{@link GtApiProxyFactory}对象 32 | */ 33 | private static ConcurrentMap cache = new ConcurrentHashMap(2); 34 | 35 | DefaultApiClient defaultApiClient; 36 | 37 | /** 38 | * 缓存接口的相关数据,减小解析成本 39 | */ 40 | private GtApiRegistry gtApiRegistry; 41 | 42 | public void setGtApiRegistry(GtApiRegistry gtApiRegistry) { 43 | this.gtApiRegistry = gtApiRegistry; 44 | } 45 | 46 | public static GtApiProxyFactory build(DefaultApiClient defaultApiClient) { 47 | GtApiProxyFactory gtApiProxyFactory = cache.get(defaultApiClient); 48 | if (gtApiProxyFactory == null) { 49 | synchronized (cache) { 50 | gtApiProxyFactory = new GtApiProxyFactory(defaultApiClient); 51 | cache.put(defaultApiClient, gtApiProxyFactory); 52 | } 53 | } 54 | return gtApiProxyFactory; 55 | } 56 | 57 | private GtApiProxyFactory(DefaultApiClient defaultApiClient) { 58 | if (defaultApiClient == null) { 59 | throw new ApiException("defaultApiClient cannot be null.", true); 60 | } 61 | this.defaultApiClient = defaultApiClient; 62 | gtApiRegistry = new DefaultGtApiRegistry(); 63 | } 64 | 65 | /** 66 | * 创建代理对象 67 | * 68 | * @param apiService 69 | * @param 70 | * @return 71 | */ 72 | public T createProxy(Class apiService) { 73 | return (T) Proxy.newProxyInstance(apiService.getClassLoader(), new Class[]{apiService}, new ApiProxyHandler()); 74 | } 75 | 76 | class ApiProxyHandler implements InvocationHandler { 77 | @Override 78 | public Object invoke(Object proxy, Method method, Object[] args) { 79 | try { 80 | if (Object.class.equals(method.getDeclaringClass())) { 81 | return method.invoke(this, args); 82 | } 83 | } catch (Throwable t) { 84 | throw new RuntimeException(t); 85 | } 86 | final BaseParam baseParam = gtApiRegistry.get(method); 87 | ApiParam apiParam = new ApiParam(baseParam); 88 | // 解析参数 -> HTTP参数 89 | handleApiParam(method, args, apiParam); 90 | return defaultApiClient.execute(apiParam); 91 | } 92 | } 93 | 94 | /** 95 | * 处理参数, HTTP调用路径参数和body参数 96 | * 97 | * @param method 用于获取方法上的注解 98 | * @param args 99 | * @return notnull 100 | */ 101 | private void handleApiParam(Method method, Object[] args, ApiParam apiParam) { 102 | Annotation[][] parameterAnnotations = method.getParameterAnnotations(); 103 | for (int i = 0; i < parameterAnnotations.length; i++) { 104 | for (Annotation annotation : parameterAnnotations[i]) { 105 | if (annotation instanceof GtPathParam) { 106 | apiParam.handlePathParam(args[i]); 107 | } else if (annotation instanceof GtQueryParam) { 108 | apiParam.handleQueryParam(args[i], ((GtQueryParam) annotation).name()); 109 | } else if (annotation instanceof GtBodyParam) { 110 | apiParam.setBody(args[i]); 111 | } 112 | } 113 | } 114 | } 115 | 116 | /** 117 | * 释放 {@link #cache}中的对象,但是此对象仍然可以使用,直到没有内存引用被回收 118 | */ 119 | public void close() { 120 | this.defaultApiClient.close(); 121 | cache.remove(this.defaultApiClient); 122 | } 123 | 124 | /** 125 | * HTTP请求的参数 126 | */ 127 | public static class ApiParam { 128 | /** 129 | * 基础参数,从方法注解中解析 130 | */ 131 | private final BaseParam baseParam; 132 | /** 133 | * 路径参数 134 | */ 135 | private String pathParams; 136 | /** 137 | * query参数 138 | */ 139 | private List queryParams; 140 | /** 141 | * body参数 142 | */ 143 | private Object body; 144 | 145 | public ApiParam(BaseParam baseParam) { 146 | this.baseParam = baseParam; 147 | } 148 | 149 | /** 150 | * 处理路径参数 151 | * 152 | * @param arg 153 | */ 154 | public void handlePathParam(Object arg) { 155 | Assert.notNull(arg, "路径参数"); 156 | setPathParams(handleArg(arg)); 157 | } 158 | 159 | private void addQueryParams(String name, String param) { 160 | if (queryParams == null) { 161 | queryParams = new ArrayList(); 162 | } 163 | queryParams.add(name + "=" + param); 164 | } 165 | 166 | public void handleQueryParam(Object arg, String name) { 167 | Assert.notNull(arg, "query参数"); 168 | final String param = handleArg(arg); 169 | addQueryParams(name, param); 170 | } 171 | 172 | private String handleArg(Object arg) { 173 | if (arg instanceof Iterable) { 174 | final Iterator iterator = ((Iterable) arg).iterator(); 175 | StringBuilder sb = new StringBuilder(); 176 | while (iterator.hasNext()) { 177 | sb.append(iterator.next()).append(','); 178 | } 179 | String param = sb.toString(); 180 | if (param.endsWith(",")) { 181 | param = param.substring(0, param.length() - 1); 182 | } 183 | return param; 184 | } else if (arg instanceof Number) { 185 | return arg.toString(); 186 | } else if (arg instanceof String) { 187 | return (String) arg; 188 | } else { 189 | throw new ApiException("路径参数(加GtPathParam注解的参数)和query参数(加GtQueryParam注解的参数)只能为 Iterable/Number/String的三种类型或其子类型"); 190 | } 191 | } 192 | 193 | public String getUri() { 194 | return baseParam.getUri(); 195 | } 196 | 197 | public String getMethod() { 198 | return baseParam.getMethod(); 199 | } 200 | 201 | public Boolean getNeedToken() { 202 | return baseParam.getNeedToken(); 203 | } 204 | 205 | public Type getReturnType() { 206 | return baseParam.getReturnType(); 207 | } 208 | 209 | public BaseParam getBaseParam() { 210 | return baseParam; 211 | } 212 | 213 | public String getPathParams() { 214 | return pathParams; 215 | } 216 | 217 | public void setPathParams(String pathParams) { 218 | this.pathParams = pathParams; 219 | } 220 | 221 | public List getQueryParams() { 222 | return queryParams; 223 | } 224 | 225 | public void setQueryParams(List queryParams) { 226 | this.queryParams = queryParams; 227 | } 228 | 229 | public Object getBody() { 230 | return body; 231 | } 232 | 233 | public void setBody(Object body) { 234 | this.body = body; 235 | } 236 | 237 | 238 | @Override 239 | public String toString() { 240 | final StringBuilder sb = new StringBuilder("ApiParam{"); 241 | sb.append("baseParam=").append(baseParam); 242 | sb.append(", pathParams='").append(pathParams).append('\''); 243 | sb.append(", queryParams=").append(queryParams); 244 | sb.append(", body=").append(body); 245 | sb.append('}'); 246 | return sb.toString(); 247 | } 248 | } 249 | 250 | /** 251 | * HTTP请求的参数 252 | */ 253 | public static class BaseParam { 254 | /** 255 | * 接口调用相对路径 256 | * eg. /auth 257 | */ 258 | private String uri; 259 | /** 260 | * 接口请求方式 GET/POST/PUT/DELETE 261 | */ 262 | private String method; 263 | 264 | /** 265 | * 是否需要token 266 | */ 267 | private Boolean needToken; 268 | /** 269 | * 返回值类型 270 | */ 271 | private Type returnType; 272 | 273 | public String getUri() { 274 | return uri; 275 | } 276 | 277 | public void setUri(String uri) { 278 | this.uri = uri; 279 | } 280 | 281 | public String getMethod() { 282 | return method; 283 | } 284 | 285 | public void setMethod(String method) { 286 | this.method = method; 287 | } 288 | 289 | public Boolean getNeedToken() { 290 | return needToken; 291 | } 292 | 293 | public void setNeedToken(Boolean needToken) { 294 | this.needToken = needToken; 295 | } 296 | 297 | public Type getReturnType() { 298 | return returnType; 299 | } 300 | 301 | public void setReturnType(Type returnType) { 302 | this.returnType = returnType; 303 | } 304 | 305 | @Override 306 | public String toString() { 307 | return "BaseParam{" + 308 | "uri='" + uri + '\'' + 309 | ", method='" + method + '\'' + 310 | ", needToken=" + needToken + 311 | ", returnType=" + returnType + 312 | '}'; 313 | } 314 | } 315 | 316 | } 317 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/handler/GtInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.handler; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | import com.getui.push.v2.sdk.core.factory.GtApiProxyFactory; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * create by getui on 2020/9/28 10 | * 11 | * @author getui 12 | */ 13 | public interface GtInterceptor { 14 | /** 15 | * http请求前调用 16 | * 17 | * @param apiParam 请求参数 18 | * @param header 请求header 19 | * @param body 请求body 20 | */ 21 | void pre(GtApiProxyFactory.ApiParam apiParam, Map header, String body); 22 | 23 | /** 24 | * http请求成功后调用此方法 25 | * 26 | * @param apiParam 请求参数 27 | * @param header 请求header 28 | * @param body 请求body 29 | * @param result 返回值 30 | */ 31 | void post(GtApiProxyFactory.ApiParam apiParam, Map header, String body, String result); 32 | 33 | /** 34 | * 报错时调用此方法 35 | * 36 | * @param host 当前使用的host 37 | * @param apiParam 请求参数 38 | * @param header 请求header 39 | * @param body 请求body 40 | * @param e 异常信息 41 | */ 42 | void handleException(String host, GtApiProxyFactory.ApiParam apiParam, Map header, String body, ApiException e); 43 | 44 | /** 45 | * http请求后调用,不管成功或者失败都会调用 46 | * 47 | * @param host 当前使用的host 48 | * @param apiParam 请求参数 49 | * @param header 请求header 50 | * @param body 请求body 51 | * @param result 返回值 52 | */ 53 | void afterCompletion(String host, GtApiProxyFactory.ApiParam apiParam, Map header, String body, String result); 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/handler/IHandler.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.handler; 2 | 3 | /** 4 | * create by getui on 2020/6/15 5 | * 6 | * @author getui 7 | */ 8 | public interface IHandler { 9 | 10 | /** 11 | * 处理器接口 12 | * 13 | * @param t 14 | * @return 15 | */ 16 | T handle(T t); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/handler/header/IHeaderHandler.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.handler.header; 2 | 3 | import com.getui.push.v2.sdk.core.handler.IHandler; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * 处理header参数的handler 9 | * create by getui on 2020/6/15 10 | * 11 | * @author getui 12 | */ 13 | public interface IHeaderHandler extends IHandler> { 14 | /** 15 | * 处理header参数 16 | * 17 | * @param header header,可能为null 18 | * @return 将作为新的header参数 19 | */ 20 | @Override 21 | Map handle(Map header); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/handler/impl/DefaultGtInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.handler.impl; 2 | 3 | import com.getui.push.v2.sdk.GtApiConfiguration; 4 | import com.getui.push.v2.sdk.common.ApiException; 5 | import com.getui.push.v2.sdk.common.Monitor; 6 | import com.getui.push.v2.sdk.core.factory.GtApiProxyFactory; 7 | import com.getui.push.v2.sdk.core.handler.GtInterceptor; 8 | import com.getui.push.v2.sdk.core.manager.HostManager; 9 | import com.getui.push.v2.sdk.core.status.ServiceState; 10 | import com.getui.push.v2.sdk.core.status.StateWrapper; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.util.Map; 15 | import java.util.concurrent.BlockingQueue; 16 | import java.util.concurrent.ConcurrentHashMap; 17 | import java.util.concurrent.ConcurrentMap; 18 | import java.util.concurrent.atomic.AtomicInteger; 19 | import java.util.concurrent.locks.Lock; 20 | import java.util.concurrent.locks.ReentrantLock; 21 | 22 | /** 23 | * create by getui on 2020/9/28 24 | * 25 | * @author getui 26 | */ 27 | public class DefaultGtInterceptor implements GtInterceptor { 28 | 29 | private Logger log = LoggerFactory.getLogger(this.getClass()); 30 | private static final ThreadLocal START_TIME = new ThreadLocal<>(); 31 | 32 | private final ConcurrentMap stateWrapperMap = new ConcurrentHashMap(); 33 | 34 | private final AtomicInteger failNum = new AtomicInteger(0); 35 | 36 | private final HostManager hostManager; 37 | private final BlockingQueue reportDataQueue; 38 | private final GtApiConfiguration configuration; 39 | 40 | /** 41 | * 域名切换时加锁,防止短时间内重复切换 42 | */ 43 | final Lock switchLock = new ReentrantLock(); 44 | 45 | public DefaultGtInterceptor(HostManager hostManager, BlockingQueue reportDataQueue, GtApiConfiguration configuration) { 46 | this.hostManager = hostManager; 47 | this.reportDataQueue = reportDataQueue; 48 | this.configuration = configuration; 49 | if (configuration.isOpenAnalyseStableDomainSwitch()) { 50 | Monitor.init(configuration.getCheckMaxFailedNumInterval()); 51 | } 52 | } 53 | 54 | @Override 55 | public void pre(GtApiProxyFactory.ApiParam apiParam, Map header, String body) { 56 | START_TIME.set(System.currentTimeMillis()); 57 | } 58 | 59 | @Override 60 | public void post(GtApiProxyFactory.ApiParam apiParam, Map header, String body, String result) { 61 | log.debug("success. param: {}, result: {}.", apiParam, result); 62 | failNum.set(0); 63 | } 64 | 65 | @Override 66 | public void handleException(String host, GtApiProxyFactory.ApiParam apiParam, Map header, String body, ApiException e) { 67 | log.error("http error. param: {}, body: {}.", apiParam, body, e); 68 | if (configuration.isOpenCheckHealthDataSwitch()) { 69 | ServiceState serviceState = get(hostManager.getUsing()).get(apiParam.getUri()); 70 | serviceState.incrFailedTimes(); 71 | } 72 | // 连续失败次数达到阈值 73 | int num = failNum.incrementAndGet(); 74 | if (num > configuration.getContinuousFailedNum()) { 75 | resetAndSwitchHost(host, "continuous", num); 76 | } 77 | } 78 | 79 | @Override 80 | public void afterCompletion(String host, GtApiProxyFactory.ApiParam apiParam, Map header, String body, String result) { 81 | try { 82 | if (configuration.isOpenCheckHealthDataSwitch()) { 83 | long cost = System.currentTimeMillis() - START_TIME.get(); 84 | final ServiceState serviceState = get(host).get(apiParam.getUri()); 85 | serviceState.addCallTime(cost); 86 | serviceState.incrCallTimes(); 87 | } 88 | // 单位时间内失败次数达到阈值,切换域名 89 | long failedTotal = Monitor.get(host); 90 | if (failedTotal > configuration.getMaxFailedNum()) { 91 | resetAndSwitchHost(host, "total", failedTotal); 92 | } 93 | } finally { 94 | START_TIME.remove(); 95 | } 96 | } 97 | 98 | void resetAndSwitchHost(String host, String reason, long failedNum) { 99 | boolean locked = switchLock.tryLock(); 100 | if (!locked) { 101 | return; 102 | } 103 | try { 104 | // 失败次数重置 105 | Monitor.reset(host); 106 | failNum.set(0); 107 | if (configuration.isOpenCheckHealthDataSwitch()) { 108 | this.reportDataQueue.offer(getAndRemove(host)); 109 | } 110 | if (configuration.isOpenAnalyseStableDomainSwitch()) { 111 | log.debug("The number of failures has reached the threshold, will switch host. reason:{}, failedNum:{}", reason, failedNum); 112 | // 切换域名 113 | hostManager.switchHost(host); 114 | } 115 | } finally { 116 | switchLock.unlock(); 117 | } 118 | } 119 | 120 | private StateWrapper get(String host) { 121 | StateWrapper stateWrapper = stateWrapperMap.get(host); 122 | if (stateWrapper != null) { 123 | return stateWrapper; 124 | } 125 | synchronized (stateWrapperMap) { 126 | stateWrapper = stateWrapperMap.get(host); 127 | if (stateWrapper != null) { 128 | return stateWrapper; 129 | } 130 | stateWrapper = new StateWrapper(host); 131 | stateWrapperMap.put(host, stateWrapper); 132 | return stateWrapper; 133 | } 134 | } 135 | 136 | public StateWrapper getAndRemove(String host) { 137 | return stateWrapperMap.remove(host); 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/manager/HostManager.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.manager; 2 | 3 | import com.getui.push.v2.sdk.GtApiConfiguration; 4 | import com.getui.push.v2.sdk.common.http.HttpManager; 5 | import com.getui.push.v2.sdk.common.util.Utils; 6 | import com.getui.push.v2.sdk.core.Configs; 7 | import com.getui.push.v2.sdk.core.domain.DomainCheck; 8 | import com.getui.push.v2.sdk.core.domain.DomainListBO; 9 | import com.getui.push.v2.sdk.core.domain.IDomainCheck; 10 | import com.getui.push.v2.sdk.core.domain.RasDomainBO; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.util.ArrayList; 15 | import java.util.Collections; 16 | import java.util.List; 17 | import java.util.concurrent.*; 18 | import java.util.concurrent.atomic.AtomicInteger; 19 | import java.util.concurrent.locks.Lock; 20 | import java.util.concurrent.locks.ReentrantLock; 21 | 22 | /** 23 | * create by getui on 2020/9/28 24 | * 25 | * @author getui 26 | */ 27 | public class HostManager { 28 | 29 | private Logger logger = LoggerFactory.getLogger(this.getClass()); 30 | 31 | volatile ThreadPoolExecutor analyseStableDomainExecutor; 32 | 33 | public HostManager(GtApiConfiguration configuration, HttpManager httpManager) { 34 | this.configuration = configuration; 35 | this.using = configuration.getDomain(); 36 | this.httpManager = httpManager; 37 | } 38 | 39 | private final HttpManager httpManager; 40 | 41 | private final GtApiConfiguration configuration; 42 | 43 | /** 44 | * 正在使用的域名 45 | */ 46 | private volatile String using; 47 | /** 48 | * 切换域名的锁 49 | */ 50 | private final Lock switchUsingLock = new ReentrantLock(); 51 | 52 | /** 53 | * 天上拉下来的域名 54 | */ 55 | private volatile RasDomainBO rasDomain; 56 | private final Object setRasDomainLock = new Object(); 57 | 58 | /** 59 | * {@link #rasDomain} 经过优先级算法排序后的结果 60 | */ 61 | private volatile List sortedDomains; 62 | 63 | /** 64 | * 域名优先级队列 65 | */ 66 | private volatile BlockingQueue sortedHostQueue; 67 | 68 | /** 69 | * 增量,域名切换次数 70 | */ 71 | private final AtomicInteger switchIncr = new AtomicInteger(0); 72 | /** 73 | * 总量,域名切换次数 74 | */ 75 | private final AtomicInteger switchTotal = new AtomicInteger(0); 76 | 77 | public String getUsing() { 78 | return this.using; 79 | } 80 | 81 | /** 82 | * 处理天上返回的域名 83 | * 84 | * @param domainBO 85 | */ 86 | public void handleDomain(RasDomainBO domainBO) { 87 | if (domainBO == null || Utils.isEmpty(domainBO.getHostList())) { 88 | return; 89 | } 90 | if (setRasDomainBO(domainBO)) { 91 | // 清空已有域名,确保域名队列中天上域名在最前面(本地域名可能存在跨机房等问题) 92 | if (!Utils.isEmpty(sortedDomains)) { 93 | sortedDomains.clear(); 94 | } 95 | resetHostQueue(); 96 | if (Utils.isEmpty(domainBO.getHostList().get(0).getDomainList())) { 97 | logger.warn("domain list is empty, please check"); 98 | return; 99 | } 100 | // 不确定是域名改变还是跨机房,所以必须切域名(如果天上域名不可用,重试会换域名) 101 | switchTo(domainBO.getHostList().get(0).getDomainList().get(0)); 102 | } 103 | } 104 | 105 | /** 106 | * @param willUse 107 | */ 108 | private void switchTo(String willUse) { 109 | if (Utils.isNotEmpty(willUse) && willUse.equals(this.using)) { 110 | return; 111 | } 112 | logger.debug("switch host. old: {}, new: {}.", this.using, willUse); 113 | switchIncr.incrementAndGet(); 114 | switchTotal.incrementAndGet(); 115 | this.using = willUse; 116 | } 117 | 118 | /** 119 | * 切换域名 120 | * 121 | * @param oldHost 上次使用的域名 122 | */ 123 | public void switchHost(String oldHost) { 124 | if (oldHost != null && !oldHost.equalsIgnoreCase(using)) { 125 | // 表示已切换 126 | return; 127 | } 128 | switchHost(); 129 | } 130 | 131 | /** 132 | * 切换域名 133 | */ 134 | public void switchHost() { 135 | if (Utils.isEmpty(sortedHostQueue)) { 136 | resetHostQueue(); 137 | } 138 | if (!switchUsingLock.tryLock()) { 139 | return; 140 | } 141 | try { 142 | final String host = sortedHostQueue.poll(); 143 | if (Utils.isNotEmpty(host)) { 144 | switchTo(host); 145 | } else { 146 | logger.debug("switchHost. hostQueue.poll() return null. host: {}.", host); 147 | switchTo(configuration.getDomain()); 148 | } 149 | } finally { 150 | switchUsingLock.unlock(); 151 | } 152 | } 153 | 154 | /** 155 | * 当 {@link #sortedHostQueue}为空时重置 156 | */ 157 | private synchronized void resetHostQueue() { 158 | if (Utils.isNotEmpty(sortedHostQueue)) { 159 | return; 160 | } 161 | resetHostQueueHard(); 162 | } 163 | 164 | /** 165 | * 获取天上的域名列表 166 | * 167 | * @return 168 | */ 169 | public List getCustomizedDomains() { 170 | RasDomainBO rasDomain = this.rasDomain; 171 | if (rasDomain == null || rasDomain.getHostList() == null) { 172 | return Collections.emptyList(); 173 | } 174 | List domains = new ArrayList(); 175 | for (DomainListBO domainListBO : rasDomain.getHostList()) { 176 | if (domainListBO == null || domainListBO.getDomainList() == null) { 177 | continue; 178 | } 179 | domains.addAll(domainListBO.getDomainList()); 180 | } 181 | return domains; 182 | } 183 | 184 | private void resetHostQueueHard() { 185 | RasDomainBO rasDomain = this.rasDomain; 186 | BlockingQueue queue = new LinkedBlockingDeque(); 187 | if (Utils.isEmpty(sortedDomains)) { 188 | // 优先使用天上的域名,如果跨机房,客户设置的域名就会有问题 189 | if (rasDomain != null && 190 | Utils.isNotEmpty(rasDomain.getHostList())) { 191 | for (DomainListBO domainListBO : rasDomain.getHostList()) { 192 | if (Utils.isNotEmpty(domainListBO.getDomainList())) { 193 | queue.addAll(domainListBO.getDomainList()); 194 | } 195 | } 196 | } 197 | } else { 198 | queue.addAll(sortedDomains); 199 | } 200 | if (Utils.isNotEmpty(configuration.getDomain())) { 201 | queue.add(configuration.getDomain()); 202 | } 203 | if (Utils.isNotEmpty(Configs.URLS)) { 204 | queue.addAll(Configs.URLS); 205 | } 206 | this.sortedHostQueue = queue; 207 | } 208 | 209 | public RasDomainBO getRasDomain() { 210 | return rasDomain; 211 | } 212 | 213 | public boolean setRasDomainBO(RasDomainBO rasDomainBO) { 214 | if (rasDomainBO == null || 215 | Utils.isEmpty(rasDomainBO.getHostList()) || 216 | Utils.isEmpty(rasDomainBO.getDomainHash())) { 217 | return false; 218 | } 219 | if (this.rasDomain != null && 220 | rasDomainBO.getDomainHash().equalsIgnoreCase(this.rasDomain.getDomainHash())) { 221 | return false; 222 | } 223 | synchronized (setRasDomainLock) { 224 | if (this.rasDomain != null && 225 | rasDomainBO.getDomainHash().equalsIgnoreCase(this.rasDomain.getDomainHash())) { 226 | return false; 227 | } 228 | this.rasDomain = rasDomainBO; 229 | return true; 230 | } 231 | } 232 | 233 | public BlockingQueue getSortedHostQueue() { 234 | return sortedHostQueue; 235 | } 236 | 237 | public void setSortedHostQueue(BlockingQueue sortedHostQueue) { 238 | this.sortedHostQueue = sortedHostQueue; 239 | } 240 | 241 | public String domainHash() { 242 | return rasDomain == null ? null : rasDomain.getDomainHash(); 243 | } 244 | 245 | /** 246 | * 分析最稳定域名 247 | */ 248 | public void analyseStableDomain() { 249 | if (rasDomain == null || Utils.isEmpty(rasDomain.getHostList())) { 250 | logger.debug("Analysing stopped because the hostList is empty."); 251 | return; 252 | } 253 | if (analyseStableDomainExecutor == null) { 254 | analyseStableDomainExecutor = new ThreadPoolExecutor(4, 4, 1, TimeUnit.HOURS, new LinkedBlockingQueue(10), new ThreadFactory() { 255 | private final AtomicInteger threadNumber = new AtomicInteger(1); 256 | private final String namePrefix = "analyseStableDomain-"; 257 | 258 | @Override 259 | public Thread newThread(Runnable r) { 260 | Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement()); 261 | t.setDaemon(true); 262 | return t; 263 | } 264 | }, new ThreadPoolExecutor.DiscardPolicy()); 265 | } 266 | final List sortedHost = new DomainCheck(new IDomainCheck() { 267 | @Override 268 | public boolean check(final String url) { 269 | int socketTimeout = configuration.getHttpCheckTimeout(); 270 | Future future = analyseStableDomainExecutor.submit(() -> { 271 | httpManager.syncHttps(url + "/v2/check", null, socketTimeout, "head", null, null, null); 272 | return true; 273 | }); 274 | try { 275 | return future.get(socketTimeout, TimeUnit.MILLISECONDS); 276 | } catch (TimeoutException e) { 277 | future.cancel(true); 278 | } catch (Exception e) { 279 | } 280 | return false; 281 | } 282 | }).sort(rasDomain.getHostList()); 283 | if (Utils.isNotEmpty(sortedHost)) { 284 | this.sortedDomains = sortedHost; 285 | } 286 | logger.debug("analyseStableDomain finished. domains: {}, result: {}.", rasDomain.getHostList(), sortedHost); 287 | resetHostQueueHard(); 288 | switchHost(); 289 | } 290 | 291 | public int getSwitchIncrNum() { 292 | return switchIncr.getAndSet(0); 293 | } 294 | 295 | public int getSwitchTotalNum() { 296 | return switchTotal.get(); 297 | } 298 | } 299 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/registry/DefaultGtApiRegistry.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.registry; 2 | 3 | import com.getui.push.v2.sdk.anno.method.GtDelete; 4 | import com.getui.push.v2.sdk.anno.method.GtGet; 5 | import com.getui.push.v2.sdk.anno.method.GtPost; 6 | import com.getui.push.v2.sdk.anno.method.GtPut; 7 | import com.getui.push.v2.sdk.common.ApiException; 8 | import com.getui.push.v2.sdk.common.type.ParameterizedTypeImpl; 9 | import com.getui.push.v2.sdk.common.type.TypeReference; 10 | import com.getui.push.v2.sdk.common.util.Utils; 11 | import com.getui.push.v2.sdk.core.factory.GtApiProxyFactory; 12 | 13 | import java.lang.annotation.Annotation; 14 | import java.lang.reflect.Method; 15 | import java.lang.reflect.ParameterizedType; 16 | import java.lang.reflect.Type; 17 | import java.util.Map; 18 | import java.util.concurrent.ConcurrentHashMap; 19 | 20 | /** 21 | * create by getui on 2020/6/8 22 | * 23 | * @author getui 24 | */ 25 | public class DefaultGtApiRegistry implements GtApiRegistry { 26 | 27 | private Map cache = new ConcurrentHashMap(); 28 | 29 | @Override 30 | public void register(Method method) { 31 | get(method); 32 | } 33 | 34 | @Override 35 | public GtApiProxyFactory.BaseParam get(Method method) { 36 | GtApiProxyFactory.BaseParam param = cache.get(method.toString()); 37 | if (param != null) { 38 | return param; 39 | } 40 | synchronized (cache) { 41 | param = cache.get(method.toString()); 42 | if (param != null) { 43 | return param; 44 | } 45 | param = doAnalise(method); 46 | cache.put(method.toString(), param); 47 | return param; 48 | } 49 | } 50 | 51 | private GtApiProxyFactory.BaseParam doAnalise(Method method) { 52 | GtApiProxyFactory.BaseParam param = new GtApiProxyFactory.BaseParam(); 53 | // 解析方法注解 -> HTTP请求方式和uri 54 | handleAnnotation(method.getAnnotations(), param); 55 | // 获取泛型类型,用于反序列化使用 56 | Type[] types = ((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments(); 57 | // 设置返回值类型,用于反序列化 58 | param.setReturnType(new GtTypeHelper(method.getReturnType(), types).getType()); 59 | return param; 60 | } 61 | 62 | /** 63 | * 这个类主要目的: 构造泛型类型,方便反序列化(参考jackson) 64 | * 不一定是最好的方式,如果有更好的方式,可以替换 65 | */ 66 | class GtTypeHelper extends TypeReference { 67 | final Class aClass; 68 | final Type[] types; 69 | 70 | public GtTypeHelper(Class aClass, Type[] types) { 71 | this.aClass = aClass; 72 | this.types = types; 73 | } 74 | 75 | @Override 76 | public Type getType() { 77 | return ParameterizedTypeImpl.make(aClass, types, null); 78 | } 79 | } 80 | 81 | /** 82 | * 处理注解,解析uri和method 83 | * 84 | * @param annotations 85 | * @param apiParam notnull 86 | */ 87 | private GtApiProxyFactory.BaseParam handleAnnotation(Annotation[] annotations, GtApiProxyFactory.BaseParam apiParam) { 88 | if (apiParam == null) { 89 | throw new ApiException("apiParam cannot be null."); 90 | } 91 | for (Annotation annotation : annotations) { 92 | if (annotation instanceof GtGet) { 93 | apiParam.setMethod("GET"); 94 | apiParam.setUri(((GtGet) annotation).uri()); 95 | apiParam.setNeedToken(((GtGet) annotation).needToken()); 96 | } else if (annotation instanceof GtPost) { 97 | apiParam.setMethod("POST"); 98 | apiParam.setUri(((GtPost) annotation).uri()); 99 | apiParam.setNeedToken(((GtPost) annotation).needToken()); 100 | } else if (annotation instanceof GtPut) { 101 | apiParam.setMethod("PUT"); 102 | apiParam.setUri(((GtPut) annotation).uri()); 103 | apiParam.setNeedToken(((GtPut) annotation).needToken()); 104 | } else if (annotation instanceof GtDelete) { 105 | apiParam.setMethod("DELETE"); 106 | apiParam.setUri(((GtDelete) annotation).uri()); 107 | apiParam.setNeedToken(((GtDelete) annotation).needToken()); 108 | } else { 109 | throw new ApiException("请添加请求注解 GtGet/GtPost/GtPut/GtDelete"); 110 | } 111 | } 112 | if (Utils.isEmpty(apiParam.getMethod())) { 113 | throw new UnsupportedOperationException(); 114 | } 115 | return apiParam; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/registry/GtApiRegistry.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.registry; 2 | 3 | import com.getui.push.v2.sdk.core.factory.GtApiProxyFactory; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | /** 8 | * create by getui on 2020/6/8 9 | * 10 | * @author getui 11 | */ 12 | public interface GtApiRegistry { 13 | 14 | /** 15 | * 注册, 解析出HTTP请求方法、路径、返回值类型等并缓存 16 | * 17 | * @param method 18 | */ 19 | void register(Method method); 20 | 21 | /** 22 | * 获取缓存的方法信息,如果没有缓存则解析并缓存 23 | * 24 | * @param method 方法 25 | * @return 26 | */ 27 | GtApiProxyFactory.BaseParam get(Method method); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/status/ServiceState.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.status; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | import java.util.concurrent.atomic.AtomicLong; 5 | 6 | public class ServiceState { 7 | private AtomicInteger callTimes = new AtomicInteger(0); 8 | private AtomicInteger failedTimes = new AtomicInteger(0); 9 | private AtomicLong callAllTime = new AtomicLong(0); 10 | 11 | public void incrCallTimes() { 12 | this.callTimes.incrementAndGet(); 13 | } 14 | 15 | public void addCallTime(long millis) { 16 | this.callAllTime.addAndGet(millis); 17 | } 18 | 19 | public void incrFailedTimes() { 20 | this.failedTimes.incrementAndGet(); 21 | } 22 | 23 | public AtomicInteger getCallTimes() { 24 | return callTimes; 25 | } 26 | 27 | public void setCallTimes(AtomicInteger callTimes) { 28 | this.callTimes = callTimes; 29 | } 30 | 31 | public AtomicInteger getFailedTimes() { 32 | return failedTimes; 33 | } 34 | 35 | public void setFailedTimes(AtomicInteger failedTimes) { 36 | this.failedTimes = failedTimes; 37 | } 38 | 39 | public AtomicLong getCallAllTime() { 40 | return callAllTime; 41 | } 42 | 43 | public void setCallAllTime(AtomicLong callAllTime) { 44 | this.callAllTime = callAllTime; 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/core/status/StateWrapper.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.core.status; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | import java.util.concurrent.ConcurrentMap; 5 | 6 | public class StateWrapper { 7 | 8 | final ConcurrentMap uriToServiceState = new ConcurrentHashMap(); 9 | 10 | private String host; 11 | 12 | public StateWrapper(String host) { 13 | this.host = host; 14 | } 15 | 16 | public String getHost() { 17 | return host; 18 | } 19 | 20 | public void setHost(String host) { 21 | this.host = host; 22 | } 23 | 24 | public ConcurrentMap getUriToServiceState() { 25 | return uriToServiceState; 26 | } 27 | 28 | public ServiceState get(String uri) { 29 | ServiceState serviceState = uriToServiceState.get(uri); 30 | if (serviceState != null) { 31 | return serviceState; 32 | } 33 | synchronized (uriToServiceState) { 34 | serviceState = uriToServiceState.get(uri); 35 | if (serviceState != null) { 36 | return serviceState; 37 | } 38 | serviceState = new ServiceState(); 39 | uriToServiceState.put(uri, serviceState); 40 | return serviceState; 41 | } 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/BaseDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | 5 | /** 6 | * create by getui on 2020/6/2 7 | * 8 | * @author getui 9 | */ 10 | public interface BaseDTO { 11 | 12 | /** 13 | * 参数校验, 当参数有问题时,直接抛出异常{@link ApiException} 14 | * 15 | * @throws ApiException 16 | */ 17 | void check() throws ApiException; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/CommonEnum.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto; 2 | 3 | /** 4 | * create by getui on 2020/6/3 5 | * 6 | * @author getui 7 | */ 8 | public interface CommonEnum { 9 | 10 | enum ActivateFilterTypeEnum { 11 | ACTIVE(1, "活跃"), 12 | INACTIVE(-1, "非活跃"); 13 | 14 | public final int type; 15 | public final String msg; 16 | 17 | ActivateFilterTypeEnum(int type, String msg) { 18 | this.type = type; 19 | this.msg = msg; 20 | } 21 | } 22 | 23 | enum CidByTagOpTypeEnum { 24 | OR(0, "只要包含一个就推"), 25 | AND(1, "全包含才推送, 默认值"), 26 | NOT(2, "全不包含才推送"); 27 | 28 | public final int type; 29 | public final String msg; 30 | 31 | CidByTagOpTypeEnum(int type, String msg) { 32 | this.type = type; 33 | this.msg = msg; 34 | } 35 | } 36 | 37 | enum ClickTypeEnum { 38 | TYPE_INTENT("intent", "打开应用内特定页面"), 39 | TYPE_URL("url", "打开网页地址"), 40 | TYPE_PAYLOAD("payload", "自定义消息内容启动应用"), 41 | TYPE_PAYLOAD_CUSTOM("payload_custom", "自定义消息内容不启动应用"), 42 | TYPE_STARTAPP("startapp", "打开应用首页"), 43 | TYPE_NONE("none", "纯通知,无后续动作"), 44 | ; 45 | public final String type; 46 | public final String msg; 47 | 48 | ClickTypeEnum(String type, String msg) { 49 | this.type = type; 50 | this.msg = msg; 51 | } 52 | } 53 | 54 | enum HarmonyClickTypeEnum { 55 | TYPE_WANT("want", "打开应用内特定页面"), 56 | TYPE_STARTAPP("startapp", "打开应用首页"); 57 | public final String type; 58 | public final String msg; 59 | 60 | HarmonyClickTypeEnum(String type, String msg) { 61 | this.type = type; 62 | this.msg = msg; 63 | } 64 | } 65 | 66 | /** 67 | * 通知渠道重要性 68 | */ 69 | enum ChannelLevelEnum implements IEnum { 70 | LEVEL_ZERO(0, "<8.0, 无声音,无振动,不浮动; >8.0 无声音,无振动,不显示;"), 71 | LEVEL_ONE(1, "<8.0, 无声音,无振动,不浮动; >8.0 无声音,无振动,锁屏不显示,通知栏中被折叠显示,导航栏无logo;"), 72 | LEVEL_TWO(2, "<8.0, 无声音,无振动,不浮动; >8.0 无声音,无振动,锁屏和通知栏中都显示,通知不唤醒屏幕;"), 73 | LEVEL_THREE(3, "<8.0, 有声音,无振动,不浮动; >8.0 有声音,无振动,锁屏和通知栏中都显示,通知唤醒屏幕;"), 74 | LEVEL_FOUR(4, "<8.0, 有声音,有振动,有浮动; >8.0 有声音,有振动,亮屏下通知悬浮展示,锁屏通知以默认形式展示且唤醒屏幕;"), 75 | ; 76 | 77 | public final int level; 78 | public final String msg; 79 | 80 | @Override 81 | public boolean is(Integer integer) { 82 | return get().equals(integer); 83 | } 84 | 85 | @Override 86 | public Integer get() { 87 | return level; 88 | } 89 | 90 | ChannelLevelEnum(int level, String msg) { 91 | this.level = level; 92 | this.msg = msg; 93 | } 94 | } 95 | 96 | /** 97 | * 推送消息使用网络类型 98 | */ 99 | enum NetworkTypeEnum implements IEnum { 100 | TYPE_ALL(0, "推送时不限制联网方式"), 101 | TYPE_WIFI(1, "仅wifi推送"), 102 | ; 103 | public final int type; 104 | public final String msg; 105 | 106 | @Override 107 | public boolean is(Integer integer) { 108 | return get().equals(integer); 109 | } 110 | 111 | @Override 112 | public Integer get() { 113 | return type; 114 | } 115 | 116 | NetworkTypeEnum(int type, String msg) { 117 | this.type = type; 118 | this.msg = msg; 119 | } 120 | } 121 | 122 | enum MethodEnum { 123 | METHOD_GET("GET"), 124 | METHOD_POST("POST"), 125 | METHOD_PUT("PUT"), 126 | METHOD_DELETE("DELETE"), 127 | METHOD_PATCH("PATCH"), 128 | METHOD_TRACE("TRACE"), 129 | METHOD_HEAD("HEAD"), 130 | METHOD_OPTIONS("OPTIONS"), 131 | ; 132 | public final String method; 133 | 134 | MethodEnum(String method) { 135 | this.method = method; 136 | } 137 | 138 | public boolean is(String method) { 139 | return this.method.equalsIgnoreCase(method); 140 | } 141 | } 142 | 143 | /** 144 | * 条件关联方式 145 | */ 146 | enum OptTypeEnum implements IEnum { 147 | TYPE_AND("and"), 148 | TYPE_OR("or"), 149 | TYPE_NOT("not"), 150 | ; 151 | public final String type; 152 | 153 | @Override 154 | public boolean is(String s) { 155 | return get().equalsIgnoreCase(s); 156 | } 157 | 158 | @Override 159 | public String get() { 160 | return type; 161 | } 162 | 163 | OptTypeEnum(String type) { 164 | this.type = type; 165 | } 166 | } 167 | 168 | interface IEnum { 169 | /** 170 | * 判断当前值和枚举值是否相同 171 | * 172 | * @param t 173 | * @return 174 | */ 175 | boolean is(T t); 176 | 177 | /** 178 | * 获取枚举的值 179 | * 180 | * @return 181 | */ 182 | T get(); 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/Audience.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 接收人 8 | */ 9 | public class Audience { 10 | private List cid; 11 | private String aliasType; 12 | private List alias; 13 | private String fastCustomTag; 14 | private List tag; 15 | private String all; 16 | private List cidByTag; 17 | 18 | public void addCid(String cid) { 19 | if (this.cid == null) { 20 | this.cid = new ArrayList(); 21 | } 22 | this.cid.add(cid); 23 | } 24 | 25 | public void addCidByTag(CidByTagDTO cidByTag) { 26 | if (this.cidByTag == null) { 27 | this.cidByTag = new ArrayList<>(); 28 | } 29 | this.cidByTag.add(cidByTag); 30 | } 31 | 32 | public void addAlias(String alias) { 33 | if (this.alias == null) { 34 | this.alias = new ArrayList(); 35 | } 36 | this.alias.add(alias); 37 | } 38 | 39 | public void addCondition(Condition condition) { 40 | if (this.tag == null) { 41 | this.tag = new ArrayList(); 42 | } 43 | this.tag.add(condition); 44 | } 45 | 46 | public List getCid() { 47 | return cid; 48 | } 49 | 50 | public void setCid(List cid) { 51 | this.cid = cid; 52 | } 53 | 54 | public String getAliasType() { 55 | return aliasType; 56 | } 57 | 58 | public void setAliasType(String aliasType) { 59 | this.aliasType = aliasType; 60 | } 61 | 62 | public List getAlias() { 63 | return alias; 64 | } 65 | 66 | public void setAlias(List alias) { 67 | this.alias = alias; 68 | } 69 | 70 | public String getFastCustomTag() { 71 | return fastCustomTag; 72 | } 73 | 74 | public void setFastCustomTag(String fastCustomTag) { 75 | this.fastCustomTag = fastCustomTag; 76 | } 77 | 78 | public List getTag() { 79 | return tag; 80 | } 81 | 82 | public void setTag(List tag) { 83 | this.tag = tag; 84 | } 85 | 86 | public String getAll() { 87 | return all; 88 | } 89 | 90 | public void setAll(String all) { 91 | this.all = all; 92 | } 93 | 94 | public List getCidByTag() { 95 | return cidByTag; 96 | } 97 | 98 | public void setCidByTag(List cidByTag) { 99 | this.cidByTag = cidByTag; 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | return "Audience{" + 105 | "cid=" + cid + 106 | ", aliasType='" + aliasType + '\'' + 107 | ", alias=" + alias + 108 | ", fastCustomTag='" + fastCustomTag + '\'' + 109 | ", tag=" + tag + 110 | ", all='" + all + '\'' + 111 | ", cidByTag=" + cidByTag + 112 | '}'; 113 | } 114 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/AudienceDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | /** 4 | * create by getui on 2020/7/29 5 | * 6 | * @author getui 7 | */ 8 | public class AudienceDTO { 9 | 10 | /** 11 | * 推送目标用户 12 | */ 13 | private Audience audience; 14 | 15 | /** 16 | * 使用创建消息接口返回的taskId 17 | */ 18 | private String taskid; 19 | /** 20 | * 是否异步推送,异步推送不会返回data 21 | */ 22 | private boolean isAsync; 23 | 24 | /** 25 | * 是否返回别名详情,返回别名详情的前提:is_async=false 26 | */ 27 | private boolean needAliasDetail; 28 | 29 | public Audience getAudience() { 30 | return audience; 31 | } 32 | 33 | public void setAudience(Audience audience) { 34 | this.audience = audience; 35 | } 36 | 37 | public String getTaskid() { 38 | return taskid; 39 | } 40 | 41 | public void setTaskid(String taskid) { 42 | this.taskid = taskid; 43 | } 44 | 45 | public boolean isAsync() { 46 | return isAsync; 47 | } 48 | 49 | public void setAsync(boolean async) { 50 | isAsync = async; 51 | } 52 | 53 | public boolean isNeedAliasDetail() { 54 | return needAliasDetail; 55 | } 56 | 57 | public void setNeedAliasDetail(boolean needAliasDetail) { 58 | this.needAliasDetail = needAliasDetail; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return "AudienceDTO{" + 64 | "audience=" + audience + 65 | ", taskid='" + taskid + '\'' + 66 | ", isAsync=" + isAsync + 67 | ", needAliasDetail=" + needAliasDetail + 68 | '}'; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/AuthDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | 5 | import java.nio.charset.Charset; 6 | import java.security.MessageDigest; 7 | import java.security.NoSuchAlgorithmException; 8 | 9 | /** 10 | * create by getui on 2020/6/2 11 | * 12 | * @author getui 13 | */ 14 | public class AuthDTO implements BaseReqDTO { 15 | 16 | private String sign; 17 | private Long timestamp; 18 | private String appkey; 19 | 20 | /** 21 | * 生成签名 22 | * 23 | * @param appKey 24 | * @param masterSecret 25 | */ 26 | public static AuthDTO build(String appKey, String masterSecret) { 27 | AuthDTO authDTO = new AuthDTO(); 28 | authDTO.appkey = appKey; 29 | authDTO.timestamp = System.currentTimeMillis(); 30 | authDTO.sign = sha256(appKey + authDTO.timestamp + masterSecret); 31 | return authDTO; 32 | } 33 | 34 | private static String sha256(String s) { 35 | try { 36 | return hex(MessageDigest.getInstance("SHA-256").digest(s.getBytes(Charset.forName("UTF-8")))); 37 | } catch (NoSuchAlgorithmException var3) { 38 | throw new AssertionError(var3); 39 | } 40 | } 41 | 42 | private static final char[] HEX_DIGITS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 43 | 44 | public static String hex(byte[] data) { 45 | char[] result = new char[data.length * 2]; 46 | int c = 0; 47 | byte[] var3 = data; 48 | int var4 = var3.length; 49 | 50 | for (int var5 = 0; var5 < var4; ++var5) { 51 | byte b = var3[var5]; 52 | result[c++] = HEX_DIGITS[b >> 4 & 15]; 53 | result[c++] = HEX_DIGITS[b & 15]; 54 | } 55 | 56 | return new String(result); 57 | } 58 | 59 | 60 | @Override 61 | public void check() throws ApiException { 62 | } 63 | 64 | public String getSign() { 65 | return sign; 66 | } 67 | 68 | public void setSign(String sign) { 69 | this.sign = sign; 70 | } 71 | 72 | public Long getTimestamp() { 73 | return timestamp; 74 | } 75 | 76 | public void setTimestamp(Long timestamp) { 77 | this.timestamp = timestamp; 78 | } 79 | 80 | public String getAppkey() { 81 | return appkey; 82 | } 83 | 84 | public void setAppkey(String appkey) { 85 | this.appkey = appkey; 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | return "AuthDTO{" + 91 | "sign='" + sign + '\'' + 92 | ", timestamp=" + timestamp + 93 | ", appkey='" + appkey + '\'' + 94 | '}'; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/BadgeDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | 5 | /** 6 | * create by getui on 2020/6/4 7 | * 8 | * @author getui 9 | */ 10 | public class BadgeDTO implements BaseReqDTO { 11 | 12 | private String badge; 13 | 14 | @Override 15 | public void check() throws ApiException { 16 | } 17 | 18 | public String getBadge() { 19 | return badge; 20 | } 21 | 22 | public void setBadge(String badge) { 23 | this.badge = badge; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return "BadgeDTO{" + 29 | "badge='" + badge + '\'' + 30 | '}'; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/BaseReqDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.dto.BaseDTO; 4 | 5 | /** 6 | * create by getui on 2020/6/3 7 | * 8 | * @author getui 9 | */ 10 | public interface BaseReqDTO extends BaseDTO { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/CidAliasListDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | import com.getui.push.v2.sdk.dto.BaseDTO; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * create by getui on 2020/6/3 11 | * 12 | * @author getui 13 | */ 14 | public class CidAliasListDTO implements BaseReqDTO { 15 | 16 | private String aliasType; 17 | 18 | private List dataList; 19 | 20 | public CidAliasListDTO add(CidAlias cidAlias) { 21 | if (dataList == null) { 22 | dataList = new ArrayList(); 23 | } 24 | dataList.add(cidAlias); 25 | return this; 26 | } 27 | 28 | @Override 29 | public void check() throws ApiException { 30 | } 31 | 32 | public static class CidAlias implements BaseDTO { 33 | private String cid; 34 | private String alias; 35 | 36 | @Override 37 | public void check() throws ApiException { 38 | } 39 | 40 | public CidAlias(String cid, String alias) { 41 | this.cid = cid; 42 | this.alias = alias; 43 | } 44 | 45 | public CidAlias() { 46 | } 47 | 48 | public String getCid() { 49 | return cid; 50 | } 51 | 52 | public void setCid(String cid) { 53 | this.cid = cid; 54 | } 55 | 56 | public String getAlias() { 57 | return alias; 58 | } 59 | 60 | public void setAlias(String alias) { 61 | this.alias = alias; 62 | } 63 | } 64 | 65 | public String getAliasType() { 66 | return aliasType; 67 | } 68 | 69 | public void setAliasType(String aliasType) { 70 | this.aliasType = aliasType; 71 | } 72 | 73 | public List getDataList() { 74 | return dataList; 75 | } 76 | 77 | public void setDataList(List dataList) { 78 | this.dataList = dataList; 79 | } 80 | 81 | 82 | @Override 83 | public String toString() { 84 | return "CidAliasListDTO{" + 85 | "aliasType='" + aliasType + '\'' + 86 | ", dataList=" + dataList + 87 | '}'; 88 | } 89 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/CidByTagDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.dto.CommonEnum; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class CidByTagDTO { 9 | private String cid; 10 | /** 11 | * 标签列表 12 | */ 13 | private List tag; 14 | /** 15 | * @see CommonEnum.CidByTagOpTypeEnum 16 | * 标签条件过滤类型 17 | */ 18 | private Integer opType = CommonEnum.CidByTagOpTypeEnum.OR.type; 19 | 20 | public String getCid() { 21 | return cid; 22 | } 23 | 24 | public void setCid(String cid) { 25 | this.cid = cid; 26 | } 27 | 28 | public List getTag() { 29 | return tag; 30 | } 31 | 32 | public void setTag(List tag) { 33 | this.tag = tag; 34 | } 35 | 36 | public void addTag(String tag) { 37 | if (this.tag == null) { 38 | this.tag = new ArrayList<>(); 39 | } 40 | this.tag.add(tag); 41 | } 42 | 43 | public Integer getOpType() { 44 | return opType; 45 | } 46 | 47 | public void setOpType(CommonEnum.CidByTagOpTypeEnum opType) { 48 | this.opType = opType.type; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "CidByTagDTO{" + 54 | "cid='" + cid + '\'' + 55 | ", tag=" + tag + 56 | ", opType=" + opType + 57 | '}'; 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/Condition.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.dto.CommonEnum; 4 | 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | /** 9 | * 标签 10 | */ 11 | public class Condition { 12 | private String key; 13 | private Set values; 14 | /** 15 | * 条件关联方式 16 | * 17 | * @see CommonEnum.OptTypeEnum 18 | */ 19 | private String optType; 20 | 21 | public Condition addValue(String value) { 22 | if (this.values == null) { 23 | this.values = new HashSet(); 24 | } 25 | this.values.add(value); 26 | return this; 27 | } 28 | 29 | public String getKey() { 30 | return key; 31 | } 32 | 33 | public void setKey(String key) { 34 | this.key = key; 35 | } 36 | 37 | public Set getValues() { 38 | return values; 39 | } 40 | 41 | public void setValues(Set values) { 42 | this.values = values; 43 | } 44 | 45 | public String getOptType() { 46 | return optType; 47 | } 48 | 49 | public void setOptType(String optType) { 50 | this.optType = optType; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "Condition{" + 56 | "key='" + key + '\'' + 57 | ", values=" + values + 58 | ", optType='" + optType + '\'' + 59 | '}'; 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/ConditionListDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * create by getui on 2020/6/5 8 | * 9 | * @author getui 10 | */ 11 | public class ConditionListDTO { 12 | 13 | private List tag; 14 | 15 | public static ConditionListDTO build() { 16 | return new ConditionListDTO(); 17 | } 18 | 19 | public ConditionListDTO addCondition(Condition condition) { 20 | // 校验参数 21 | if (tag == null) { 22 | tag = new ArrayList(); 23 | } 24 | tag.add(condition); 25 | return this; 26 | } 27 | 28 | public List getTag() { 29 | return tag; 30 | } 31 | 32 | public void setTag(List tag) { 33 | this.tag = tag; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "ConditionListDTO{" + 39 | "tag=" + tag + 40 | '}'; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/QueryAliasDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | 5 | /** 6 | * create by getui on 2020/6/3 7 | * 8 | * @author getui 9 | */ 10 | public class QueryAliasDTO implements BaseReqDTO { 11 | 12 | /** 13 | * 路径参数cid 14 | */ 15 | private String cid; 16 | 17 | @Override 18 | public void check() throws ApiException { 19 | 20 | } 21 | 22 | public String getCid() { 23 | return cid; 24 | } 25 | 26 | public void setCid(String cid) { 27 | this.cid = cid; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "QueryAliasDTO{" + 33 | "cid='" + cid + '\'' + 34 | '}'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/Settings.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.dto.CommonEnum; 4 | 5 | /** 6 | * 推送条件 7 | */ 8 | public class Settings { 9 | /** 10 | * 消息离线时间设置,单位毫秒,-1表示不设离线, -1 ~ 3 * 24 * 3600 * 1000之间 11 | */ 12 | private Integer ttl; 13 | /** 14 | * 厂商通道策略 15 | */ 16 | private Strategy strategy; 17 | /** 18 | * 推送速度 19 | */ 20 | private Integer speed; 21 | /** 22 | * 定时推送时间,格式:毫秒时间戳 23 | */ 24 | private Long scheduleTime; 25 | /** 26 | * 自定义回执字段,SVIP功能 27 | */ 28 | private String customCallback; 29 | 30 | /** 31 | * 是否过滤关闭通知用户 32 | * false表示不过滤,true表示过滤 33 | */ 34 | private Boolean filterNotifyOff; 35 | 36 | /** 37 | * 厂商智能配额策略-用户连续活跃天数 38 | * 单位天,限制3 ~ 15天之间 39 | */ 40 | private Integer activeDays; 41 | 42 | /** 43 | * 厂商智能配额策略-是否需要兜底(离线消息到期时通过厂商通道下发),false表示不需要,true表示需要 44 | */ 45 | private Boolean needBackup; 46 | 47 | /** 48 | * 活跃行为的自定义天数,近${activate_filter_day}天活跃/非活跃用户 49 | */ 50 | private Integer activateFilterDay; 51 | /** 52 | * @see CommonEnum.ActivateFilterTypeEnum 53 | * 活跃行为的类型 54 | */ 55 | private Integer activateFilterType; 56 | 57 | public Integer getTtl() { 58 | return ttl; 59 | } 60 | 61 | public void setTtl(Integer ttl) { 62 | this.ttl = ttl; 63 | } 64 | 65 | public Strategy getStrategy() { 66 | return strategy; 67 | } 68 | 69 | public void setStrategy(Strategy strategy) { 70 | this.strategy = strategy; 71 | } 72 | 73 | public Integer getSpeed() { 74 | return speed; 75 | } 76 | 77 | public void setSpeed(Integer speed) { 78 | this.speed = speed; 79 | } 80 | 81 | public Long getScheduleTime() { 82 | return scheduleTime; 83 | } 84 | 85 | public void setScheduleTime(Long scheduleTime) { 86 | this.scheduleTime = scheduleTime; 87 | } 88 | 89 | public String getCustomCallback() { 90 | return customCallback; 91 | } 92 | 93 | public void setCustomCallback(String customCallback) { 94 | this.customCallback = customCallback; 95 | } 96 | 97 | public Boolean getFilterNotifyOff() { 98 | return filterNotifyOff; 99 | } 100 | 101 | public void setFilterNotifyOff(Boolean filterNotifyOff) { 102 | this.filterNotifyOff = filterNotifyOff; 103 | } 104 | 105 | public Integer getActiveDays() { 106 | return activeDays; 107 | } 108 | 109 | public void setActiveDays(Integer activeDays) { 110 | this.activeDays = activeDays; 111 | } 112 | 113 | public Boolean getNeedBackup() { 114 | return needBackup; 115 | } 116 | 117 | public void setNeedBackup(Boolean needBackup) { 118 | this.needBackup = needBackup; 119 | } 120 | 121 | public Integer getActivateFilterDay() { 122 | return activateFilterDay; 123 | } 124 | 125 | public void setActivateFilterDay(Integer activateFilterDay) { 126 | this.activateFilterDay = activateFilterDay; 127 | } 128 | 129 | public Integer getActivateFilterType() { 130 | return activateFilterType; 131 | } 132 | 133 | public void setActivateFilterType(CommonEnum.ActivateFilterTypeEnum activateFilterTypeEnum) { 134 | this.activateFilterType = activateFilterTypeEnum.type; 135 | } 136 | 137 | @Override 138 | public String toString() { 139 | return "Settings{" + 140 | "ttl=" + ttl + 141 | ", strategy=" + strategy + 142 | ", speed=" + speed + 143 | ", scheduleTime=" + scheduleTime + 144 | ", customCallback='" + customCallback + '\'' + 145 | ", filterNotifyOff=" + filterNotifyOff + 146 | ", activeDays=" + activeDays + 147 | ", needBackup=" + needBackup + 148 | ", activateFilterDay=" + activateFilterDay + 149 | ", activateFilterType=" + activateFilterType + 150 | '}'; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/Strategy.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Strategy extends HashMap { 6 | public final static String def = "default"; 7 | public final static String ios = "ios"; 8 | public final static String hw = "hw"; 9 | public final static String xm = "xm"; 10 | public final static String mz = "mz"; 11 | public final static String op = "op"; 12 | public final static String vv = "vv"; 13 | public final static String st = "st"; 14 | public final static String hx = "hx"; 15 | public final static String hwq = "hwq"; 16 | 17 | public Integer getDef() { 18 | return super.get(Strategy.def); 19 | } 20 | 21 | public void setDef(Integer def) { 22 | super.put(Strategy.def, def); 23 | } 24 | 25 | public Integer getIos() { 26 | return super.get(Strategy.ios); 27 | } 28 | 29 | public void setIos(Integer ios) { 30 | super.put(Strategy.ios, ios); 31 | } 32 | 33 | public Integer getHw() { 34 | return super.get(Strategy.hw); 35 | } 36 | 37 | public void setHw(Integer hw) { 38 | super.put(Strategy.hw, hw); 39 | } 40 | 41 | public Integer getXm() { 42 | return super.get(Strategy.xm); 43 | } 44 | 45 | public void setXm(Integer xm) { 46 | super.put(Strategy.xm, xm); 47 | } 48 | 49 | public Integer getMz() { 50 | return super.get(Strategy.mz); 51 | } 52 | 53 | public void setMz(Integer mz) { 54 | super.put(Strategy.mz, mz); 55 | } 56 | 57 | public Integer getOp() { 58 | return super.get(Strategy.op); 59 | } 60 | 61 | public void setOp(Integer op) { 62 | super.put(Strategy.op, op); 63 | } 64 | 65 | public Integer getVv() { 66 | return super.get(Strategy.vv); 67 | } 68 | 69 | public void setVv(Integer vv) { 70 | super.put(Strategy.vv, vv); 71 | } 72 | 73 | public Integer getSt() { 74 | return super.get(Strategy.st); 75 | } 76 | 77 | public void setSt(Integer st) { 78 | super.put(Strategy.st, st); 79 | } 80 | 81 | public Integer getHx() { 82 | return (Integer) super.get(Strategy.hx); 83 | } 84 | 85 | public void setHx(Integer hx) { 86 | super.put(Strategy.hx, hx); 87 | } 88 | 89 | public Integer getHwq() { 90 | return (Integer) super.get(Strategy.hwq); 91 | } 92 | 93 | public void setHwq(Integer hwq) { 94 | super.put(Strategy.hwq, hwq); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/TagDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | import com.getui.push.v2.sdk.common.util.Utils; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | /** 10 | * create by getui on 2020/6/4 11 | * 12 | * @author getui 13 | */ 14 | public class TagDTO implements BaseReqDTO { 15 | 16 | private Set customTag; 17 | 18 | public static TagDTO build() { 19 | return new TagDTO(); 20 | } 21 | 22 | public TagDTO addTag(String tag) { 23 | if (Utils.isEmpty(tag)) { 24 | return this; 25 | } 26 | if (customTag == null) { 27 | customTag = new HashSet(); 28 | } 29 | customTag.add(tag); 30 | return this; 31 | } 32 | 33 | @Override 34 | public void check() throws ApiException { 35 | } 36 | 37 | public Set getCustomTag() { 38 | return customTag; 39 | } 40 | 41 | public void setCustomTag(Set customTag) { 42 | this.customTag = customTag; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "TagDTO{" + 48 | "customTag=" + customTag + 49 | '}'; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/UserDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | import com.getui.push.v2.sdk.common.util.Utils; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | /** 10 | * create by getui on 2020/6/4 11 | * 12 | * @author getui 13 | */ 14 | public class UserDTO implements BaseReqDTO { 15 | 16 | private Set cid; 17 | 18 | public static UserDTO build() { 19 | return new UserDTO(); 20 | } 21 | 22 | /** 23 | * 添加cid 24 | * 25 | * @param cid 26 | * @return 27 | */ 28 | public UserDTO addCid(String cid) { 29 | if (Utils.isEmpty(cid)) { 30 | return this; 31 | } 32 | if (this.cid == null) { 33 | this.cid = new HashSet(); 34 | } 35 | this.cid.add(cid); 36 | return this; 37 | } 38 | 39 | @Override 40 | public void check() throws ApiException { 41 | } 42 | 43 | public Set getCid() { 44 | return cid; 45 | } 46 | 47 | public void setCid(Set cid) { 48 | this.cid = cid; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "UserDTO{" + 54 | "cid=" + cid + 55 | '}'; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/CustomBean.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message; 2 | 3 | public class CustomBean { 4 | /** 5 | * 消息类型 6 | * subscribe:授权订阅消息(仅支持toSingle推送API) 7 | * form_update:卡片刷新消息(仅支持toSingle推送API) 8 | * live_view:实况窗消息 9 | * voip_call:VoIP呼叫消息 10 | */ 11 | private String type; 12 | /** 13 | * 相应消息类型指定请求体的JSON字符串 14 | */ 15 | private String payload; 16 | 17 | public String getType() { 18 | return type; 19 | } 20 | 21 | public void setType(String type) { 22 | this.type = type; 23 | } 24 | 25 | public String getPayload() { 26 | return payload; 27 | } 28 | 29 | public void setPayload(String payload) { 30 | this.payload = payload; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return "CustomBean{" + 36 | "type='" + type + '\'' + 37 | ", payload='" + payload + '\'' + 38 | '}'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/PushBatchDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message; 2 | 3 | import com.getui.push.v2.sdk.dto.req.Audience; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * create by getui on 2020/8/7 10 | * 11 | * @author getui 12 | */ 13 | public class PushBatchDTO { 14 | 15 | private Boolean isAsync; 16 | 17 | private List> msgList; 18 | 19 | public PushBatchDTO addPushDTO(PushDTO pushDTO) { 20 | if (msgList == null) { 21 | msgList = new ArrayList>(); 22 | } 23 | msgList.add(pushDTO); 24 | return this; 25 | } 26 | 27 | public Boolean getAsync() { 28 | return isAsync; 29 | } 30 | 31 | public void setAsync(Boolean async) { 32 | isAsync = async; 33 | } 34 | 35 | public List> getMsgList() { 36 | return msgList; 37 | } 38 | 39 | public void setMsgList(List> msgList) { 40 | this.msgList = msgList; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "PushBatchDTO{" + 46 | "isAsync=" + isAsync + 47 | ", msgList=" + msgList + 48 | '}'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/PushChannel.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | import com.getui.push.v2.sdk.dto.BaseDTO; 5 | import com.getui.push.v2.sdk.dto.req.message.android.AndroidDTO; 6 | import com.getui.push.v2.sdk.dto.req.message.harmony.HarmonyDTO; 7 | import com.getui.push.v2.sdk.dto.req.message.ios.IosDTO; 8 | 9 | /** 10 | * create by getui on 2020/6/3 11 | * 12 | * @author getui 13 | */ 14 | public class PushChannel implements BaseDTO { 15 | 16 | /** 17 | * ios通道推送消息内容 18 | */ 19 | private IosDTO ios; 20 | /** 21 | * android通道推送消息内容 22 | */ 23 | private AndroidDTO android; 24 | /** 25 | * harmony通道推送消息内容 26 | */ 27 | private HarmonyDTO harmony; 28 | 29 | @Override 30 | public void check() throws ApiException { 31 | } 32 | 33 | public static class AndroidMessage { 34 | 35 | } 36 | 37 | public IosDTO getIos() { 38 | return ios; 39 | } 40 | 41 | public void setIos(IosDTO ios) { 42 | this.ios = ios; 43 | } 44 | 45 | public AndroidDTO getAndroid() { 46 | return android; 47 | } 48 | 49 | public void setAndroid(AndroidDTO android) { 50 | this.android = android; 51 | } 52 | 53 | public HarmonyDTO getHarmony() { 54 | return harmony; 55 | } 56 | 57 | public void setHarmony(HarmonyDTO harmony) { 58 | this.harmony = harmony; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return "PushChannel{" + 64 | "ios=" + ios + 65 | ", android=" + android + 66 | ", harmony=" + harmony + 67 | '}'; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/PushDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | import com.getui.push.v2.sdk.dto.req.Audience; 5 | import com.getui.push.v2.sdk.dto.req.BaseReqDTO; 6 | import com.getui.push.v2.sdk.dto.req.Settings; 7 | 8 | /** 9 | * create by getui on 2020/6/3 10 | * 11 | * @param 接收人的泛型 {@link Audience} 12 | * @author getui 13 | */ 14 | public class PushDTO implements BaseReqDTO { 15 | 16 | /** 17 | * 请求唯一标识号(10-32位之间) 18 | */ 19 | private String requestId; 20 | 21 | private String taskName; 22 | private String groupName; 23 | 24 | private Settings settings; 25 | 26 | private T audience; 27 | 28 | private PushMessage pushMessage; 29 | private PushChannel pushChannel; 30 | 31 | @Override 32 | public void check() throws ApiException { 33 | } 34 | 35 | public String getRequestId() { 36 | return requestId; 37 | } 38 | 39 | public void setRequestId(String requestId) { 40 | this.requestId = requestId; 41 | } 42 | 43 | public String getTaskName() { 44 | return taskName; 45 | } 46 | 47 | public void setTaskName(String taskName) { 48 | this.taskName = taskName; 49 | } 50 | 51 | public String getGroupName() { 52 | return groupName; 53 | } 54 | 55 | public void setGroupName(String groupName) { 56 | this.groupName = groupName; 57 | } 58 | 59 | public Settings getSettings() { 60 | return settings; 61 | } 62 | 63 | public void setSettings(Settings settings) { 64 | this.settings = settings; 65 | } 66 | 67 | public T getAudience() { 68 | return audience; 69 | } 70 | 71 | public void setAudience(T audience) { 72 | this.audience = audience; 73 | } 74 | 75 | public PushMessage getPushMessage() { 76 | return pushMessage; 77 | } 78 | 79 | public void setPushMessage(PushMessage pushMessage) { 80 | this.pushMessage = pushMessage; 81 | } 82 | 83 | public PushChannel getPushChannel() { 84 | return pushChannel; 85 | } 86 | 87 | public void setPushChannel(PushChannel pushChannel) { 88 | this.pushChannel = pushChannel; 89 | } 90 | 91 | @Override 92 | public String toString() { 93 | return "PushDTO{" + 94 | "requestId='" + requestId + '\'' + 95 | ", taskName='" + taskName + '\'' + 96 | ", groupName='" + groupName + '\'' + 97 | ", settings=" + settings + 98 | ", audience=" + audience + 99 | ", pushMessage=" + pushMessage + 100 | ", pushChannel=" + pushChannel + 101 | '}'; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/PushMessage.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message; 2 | 3 | import com.getui.push.v2.sdk.common.ApiException; 4 | import com.getui.push.v2.sdk.dto.BaseDTO; 5 | import com.getui.push.v2.sdk.dto.CommonEnum; 6 | import com.getui.push.v2.sdk.dto.req.message.android.GTNotification; 7 | 8 | /** 9 | * 个推推送消息参数 10 | * create by getui on 2020/6/3 11 | * 12 | * @author getui 13 | */ 14 | public class PushMessage implements BaseDTO { 15 | 16 | /** 17 | * 推送消息使用网络类型,0:不限制,1:仅wifi 18 | * 19 | * @see CommonEnum.NetworkTypeEnum 20 | */ 21 | private Integer networkType; 22 | 23 | /** 24 | * 通知展示时间段,格式为毫秒时间戳段,两个时间的时间差必须大于10分钟,例如:"1590547347000-1590633747000" 25 | */ 26 | private String duration; 27 | 28 | /** 29 | * 个推通知消息内容,与{@link #transmission}、{@link #revoke} 三选一 30 | */ 31 | private GTNotification notification; 32 | 33 | /** 34 | * 透传消息内容,与{@link #notification}、{@link #revoke} 三选一 35 | */ 36 | private String transmission; 37 | 38 | /** 39 | * 撤回消息,撤回消息不能与{@link #notification}和{@link #transmission}并存 40 | */ 41 | private RevokeBean revoke; 42 | 43 | @Override 44 | public void check() throws ApiException { 45 | } 46 | 47 | public Integer getNetworkType() { 48 | return networkType; 49 | } 50 | 51 | public void setNetworkType(Integer networkType) { 52 | this.networkType = networkType; 53 | } 54 | 55 | public String getDuration() { 56 | return duration; 57 | } 58 | 59 | public void setDuration(String duration) { 60 | this.duration = duration; 61 | } 62 | 63 | public GTNotification getNotification() { 64 | return notification; 65 | } 66 | 67 | public void setNotification(GTNotification notification) { 68 | this.notification = notification; 69 | } 70 | 71 | public String getTransmission() { 72 | return transmission; 73 | } 74 | 75 | public void setTransmission(String transmission) { 76 | this.transmission = transmission; 77 | } 78 | 79 | public RevokeBean getRevoke() { 80 | return revoke; 81 | } 82 | 83 | public void setRevoke(RevokeBean revoke) { 84 | this.revoke = revoke; 85 | } 86 | 87 | @Override 88 | public String toString() { 89 | return "PushMessage{" + 90 | "networkType=" + networkType + 91 | ", duration='" + duration + '\'' + 92 | ", notification=" + notification + 93 | ", transmission='" + transmission + '\'' + 94 | ", revoke=" + revoke + 95 | '}'; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/RevokeBean.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message; 2 | 3 | /** 4 | * create by getui on 2020/9/23 5 | * 6 | * @author getui 7 | */ 8 | public class RevokeBean { 9 | /** 10 | * 在没有找到对应的taskid,是否把对应appid下所有的通知都撤回 11 | */ 12 | private Boolean force = false; 13 | /** 14 | * 根据oldTaskId进行撤回 15 | */ 16 | private String oldTaskId; 17 | 18 | public Boolean getForce() { 19 | return force == null ? Boolean.FALSE : force; 20 | } 21 | 22 | public void setForce(Boolean force) { 23 | this.force = force; 24 | } 25 | 26 | public String getOldTaskId() { 27 | return oldTaskId; 28 | } 29 | 30 | public void setOldTaskId(String oldTaskId) { 31 | this.oldTaskId = oldTaskId; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "RevokeBean{" + 37 | "force=" + force + 38 | ", oldTaskId='" + oldTaskId + '\'' + 39 | '}'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/android/AndroidDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.android; 2 | 3 | public class AndroidDTO { 4 | /** 5 | * android厂商通道推送消息内容 6 | */ 7 | private Ups ups; 8 | 9 | public Ups getUps() { 10 | return ups; 11 | } 12 | 13 | public AndroidDTO setUps(Ups ups) { 14 | this.ups = ups; 15 | return this; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "AndroidDTO{" + 21 | "ups=" + ups + 22 | '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/android/GTNotification.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.android; 2 | 3 | import com.getui.push.v2.sdk.dto.CommonEnum; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | /** 7 | * @author getui 8 | */ 9 | public class GTNotification { 10 | /** 11 | * 第三方厂商通知标题,长度 ≤ 50 12 | */ 13 | private String title; 14 | /** 15 | * 第三方厂商通知内容,长度 ≤ 256 16 | */ 17 | private String body; 18 | @SerializedName("big_text") 19 | private String bigText; 20 | @SerializedName("big_image") 21 | private String bigImage; 22 | private String logo; 23 | @SerializedName("logo_url") 24 | private String logoUrl; 25 | @SerializedName("channel_id") 26 | private String channelId; 27 | 28 | @SerializedName("channel_name") 29 | private String channelName; 30 | 31 | @SerializedName("channel_level") 32 | private String channelLevel; 33 | 34 | /** 35 | * 鸿蒙通知渠道类型 36 | */ 37 | @SerializedName("slot_type") 38 | private String slotType; 39 | /** 40 | * @see CommonEnum.ClickTypeEnum 41 | * 点击通知后续动作, 42 | * 目前支持5种后续动作, 43 | * intent:打开应用内特定页面, 44 | * url:打开网页地址, 45 | * payload:启动应用加自定义消息内容, 46 | * startapp:打开应用首页, 47 | * none:纯通知,无后续动作 48 | */ 49 | @SerializedName("click_type") 50 | private String clickType; 51 | 52 | /** 53 | * 点击通知打开应用特定页面,长度 ≤ 4096; 54 | * 示例:intent:#Intent;component=你的包名/你要打开的 activity 全路径;S.parm1=value1;S.parm2=value2;end 55 | */ 56 | private String intent; 57 | 58 | /** 59 | * 鸿蒙平台点击动作

60 | * 示例:{"deviceId":"","bundleName":"com.getui.push","abilityName":"TestAbility","uri":"https://www.test.com:8080/push/test","action":"com.test.action","parameters":{"name":"Getui","age":12}} 61 | */ 62 | private String want; 63 | 64 | /** 65 | * 点击通知打开链接,长度 ≤ 1024 66 | */ 67 | private String url; 68 | /** 69 | * 点击通知加自定义消息,长度 ≤ 3072 70 | */ 71 | private String payload; 72 | /** 73 | * 消息覆盖使用,两条消息的notify_id相同,新的消息会覆盖老的消息 74 | */ 75 | @SerializedName("notify_id") 76 | private String notifyId; 77 | 78 | /** 79 | * 自定义铃声,请填写文件名,不包含后缀名(需要在客户端开发时嵌入),个推通道下发有效 80 | * 客户端SDK最低要求 2.14.0.0 81 | */ 82 | @SerializedName("ring_name") 83 | private String ringName; 84 | /** 85 | * 角标, 必须大于0, 个推通道下发有效 86 | * 此属性目前仅针对华为 EMUI 4.1 及以上设备有效 87 | * 角标数字数据会和之前角标数字进行叠加; 88 | * 举例:角标数字配置1,应用之前角标数为2,发送此角标消息后,应用角标数显示为3。 89 | * 客户端SDK最低要求 2.14.0.0 90 | */ 91 | @SerializedName("badge_add_num") 92 | private String badgeAddNum; 93 | 94 | /** 95 | * 消息折叠分组,设置成相同thread_id的消息会被折叠(仅支持个推渠道下发的安卓消息)。 96 | * 目前与iOS的thread_id设置无关,安卓和iOS需要分别设置。 97 | */ 98 | @SerializedName("thread_id") 99 | private String threadId; 100 | 101 | /** 102 | * 消息重弹次数,0代表不重弹,若要设置消息重弹则必须大于1,上限3次。 103 | */ 104 | @SerializedName("redisplay_freq") 105 | private Integer redisplayFreq; 106 | 107 | /** 108 | * 消息重弹间隔(单位小时),仅当重弹次数大于0时才生效,代表每次消息重弹之间的最小间隔。 109 | * 由于重弹依赖SDK登录动作,因此实际的重弹间隔可能会大于设置的最小间隔。 110 | * 0代表登录即弹,大于0即忽略在最小间隔内的登录重弹动作,上限为24小时 111 | */ 112 | @SerializedName("redisplay_duration") 113 | private Integer redisplayDuration; 114 | 115 | /** 116 | * 消息分类 117 | */ 118 | private String category; 119 | 120 | public String getTitle() { 121 | return title; 122 | } 123 | 124 | public void setTitle(String title) { 125 | this.title = title; 126 | } 127 | 128 | public String getBody() { 129 | return body; 130 | } 131 | 132 | public void setBody(String body) { 133 | this.body = body; 134 | } 135 | 136 | public String getBigText() { 137 | return bigText; 138 | } 139 | 140 | public void setBigText(String bigText) { 141 | this.bigText = bigText; 142 | } 143 | 144 | public String getBigImage() { 145 | return bigImage; 146 | } 147 | 148 | public void setBigImage(String bigImage) { 149 | this.bigImage = bigImage; 150 | } 151 | 152 | public String getLogo() { 153 | return logo; 154 | } 155 | 156 | public void setLogo(String logo) { 157 | this.logo = logo; 158 | } 159 | 160 | public String getLogoUrl() { 161 | return logoUrl; 162 | } 163 | 164 | public void setLogoUrl(String logoUrl) { 165 | this.logoUrl = logoUrl; 166 | } 167 | 168 | public String getChannelId() { 169 | return channelId; 170 | } 171 | 172 | public void setChannelId(String channelId) { 173 | this.channelId = channelId; 174 | } 175 | 176 | public String getChannelName() { 177 | return channelName; 178 | } 179 | 180 | public void setChannelName(String channelName) { 181 | this.channelName = channelName; 182 | } 183 | 184 | public String getChannelLevel() { 185 | return channelLevel; 186 | } 187 | 188 | public void setChannelLevel(String channelLevel) { 189 | this.channelLevel = channelLevel; 190 | } 191 | 192 | public String getSlotType() { 193 | return slotType; 194 | } 195 | 196 | public void setSlotType(String slotType) { 197 | this.slotType = slotType; 198 | } 199 | 200 | public String getClickType() { 201 | return clickType; 202 | } 203 | 204 | public void setClickType(String clickType) { 205 | this.clickType = clickType; 206 | } 207 | 208 | public String getIntent() { 209 | return intent; 210 | } 211 | 212 | public void setIntent(String intent) { 213 | this.intent = intent; 214 | } 215 | 216 | public String getWant() { 217 | return want; 218 | } 219 | 220 | public void setWant(String want) { 221 | this.want = want; 222 | } 223 | 224 | public String getUrl() { 225 | return url; 226 | } 227 | 228 | public void setUrl(String url) { 229 | this.url = url; 230 | } 231 | 232 | public String getPayload() { 233 | return payload; 234 | } 235 | 236 | public void setPayload(String payload) { 237 | this.payload = payload; 238 | } 239 | 240 | public String getNotifyId() { 241 | return notifyId; 242 | } 243 | 244 | public void setNotifyId(String notifyId) { 245 | this.notifyId = notifyId; 246 | } 247 | 248 | public String getRingName() { 249 | return ringName; 250 | } 251 | 252 | public void setRingName(String ringName) { 253 | this.ringName = ringName; 254 | } 255 | 256 | public String getBadgeAddNum() { 257 | return badgeAddNum; 258 | } 259 | 260 | public void setBadgeAddNum(String badgeAddNum) { 261 | this.badgeAddNum = badgeAddNum; 262 | } 263 | 264 | public String getThreadId() { 265 | return threadId; 266 | } 267 | 268 | public void setThreadId(String threadId) { 269 | this.threadId = threadId; 270 | } 271 | 272 | public Integer getRedisplayFreq() { 273 | return redisplayFreq; 274 | } 275 | 276 | public void setRedisplayFreq(Integer redisplayFreq) { 277 | this.redisplayFreq = redisplayFreq; 278 | } 279 | 280 | public Integer getRedisplayDuration() { 281 | return redisplayDuration; 282 | } 283 | 284 | public void setRedisplayDuration(Integer redisplayDuration) { 285 | this.redisplayDuration = redisplayDuration; 286 | } 287 | 288 | public String getCategory() { 289 | return category; 290 | } 291 | 292 | public void setCategory(String category) { 293 | this.category = category; 294 | } 295 | 296 | @Override 297 | public String toString() { 298 | return "GTNotification{" + 299 | "title='" + title + '\'' + 300 | ", body='" + body + '\'' + 301 | ", bigText='" + bigText + '\'' + 302 | ", bigImage='" + bigImage + '\'' + 303 | ", logo='" + logo + '\'' + 304 | ", logoUrl='" + logoUrl + '\'' + 305 | ", channelId='" + channelId + '\'' + 306 | ", channelName='" + channelName + '\'' + 307 | ", channelLevel='" + channelLevel + '\'' + 308 | ", slotType='" + slotType + '\'' + 309 | ", clickType='" + clickType + '\'' + 310 | ", intent='" + intent + '\'' + 311 | ", want='" + want + '\'' + 312 | ", url='" + url + '\'' + 313 | ", payload='" + payload + '\'' + 314 | ", notifyId='" + notifyId + '\'' + 315 | ", ringName='" + ringName + '\'' + 316 | ", badgeAddNum='" + badgeAddNum + '\'' + 317 | ", threadId='" + threadId + '\'' + 318 | ", redisplayFreq=" + redisplayFreq + 319 | ", redisplayDuration=" + redisplayDuration + 320 | ", category='" + category + '\'' + 321 | '}'; 322 | } 323 | } 324 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/android/ThirdNotification.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.android; 2 | 3 | import com.getui.push.v2.sdk.dto.CommonEnum; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | public class ThirdNotification { 7 | /** 8 | * 第三方厂商通知标题,长度 ≤ 50 9 | */ 10 | private String title; 11 | /** 12 | * 第三方厂商通知内容,长度 ≤ 256 13 | */ 14 | private String body; 15 | /** 16 | * @see CommonEnum.ClickTypeEnum 17 | * 点击通知后续动作, 18 | * 目前支持5种后续动作, 19 | * intent:打开应用内特定页面, 20 | * url:打开网页地址, 21 | * payload:启动应用加自定义消息内容, 22 | * startapp:打开应用首页, 23 | * none:纯通知,无后续动作 24 | */ 25 | @SerializedName("click_type") 26 | private String clickType; 27 | 28 | /** 29 | * 点击通知打开应用特定页面,长度 ≤ 4096,不同厂商限制不同,具体限制参考各厂商文档; 30 | * hw:没有限制 31 | * vv:1024字符 32 | * mz:1000字节 33 | * op: ≤2000字节 34 | * 示例:intent:#Intent;component=你的包名/你要打开的 activity 全路径;S.parm1=value1;S.parm2=value2;end 35 | */ 36 | private String intent; 37 | /** 38 | * 点击通知打开链接,长度 ≤ 1024 39 | */ 40 | private String url; 41 | /** 42 | * 点击通知加自定义消息,长度 ≤ 3072 43 | */ 44 | private String payload; 45 | /** 46 | * 消息覆盖使用,两条消息的notify_id相同,新的消息会覆盖老的消息 47 | */ 48 | @SerializedName("notify_id") 49 | private String notifyId; 50 | 51 | public String getTitle() { 52 | return title; 53 | } 54 | 55 | public void setTitle(String title) { 56 | this.title = title; 57 | } 58 | 59 | public String getBody() { 60 | return body; 61 | } 62 | 63 | public void setBody(String body) { 64 | this.body = body; 65 | } 66 | 67 | public String getClickType() { 68 | return clickType; 69 | } 70 | 71 | public void setClickType(String clickType) { 72 | this.clickType = clickType; 73 | } 74 | 75 | public String getIntent() { 76 | return intent; 77 | } 78 | 79 | public void setIntent(String intent) { 80 | this.intent = intent; 81 | } 82 | 83 | public String getUrl() { 84 | return url; 85 | } 86 | 87 | public void setUrl(String url) { 88 | this.url = url; 89 | } 90 | 91 | public String getPayload() { 92 | return payload; 93 | } 94 | 95 | public void setPayload(String payload) { 96 | this.payload = payload; 97 | } 98 | 99 | public String getNotifyId() { 100 | return notifyId; 101 | } 102 | 103 | public void setNotifyId(String notifyId) { 104 | this.notifyId = notifyId; 105 | } 106 | 107 | @Override 108 | public String toString() { 109 | return "ThirdNotification{" + 110 | "title='" + title + '\'' + 111 | ", body='" + body + '\'' + 112 | ", clickType='" + clickType + '\'' + 113 | ", intent='" + intent + '\'' + 114 | ", url='" + url + '\'' + 115 | ", payload='" + payload + '\'' + 116 | ", notifyId='" + notifyId + '\'' + 117 | '}'; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/android/ThirdRevokeBean.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.android; 2 | 3 | public class ThirdRevokeBean { 4 | /** 5 | * 需要撤回的taskId 6 | */ 7 | private String oldTaskId; 8 | 9 | public String getOldTaskId() { 10 | return oldTaskId; 11 | } 12 | 13 | public void setOldTaskId(String oldTaskId) { 14 | this.oldTaskId = oldTaskId; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return "ThirdRevokeBean{" + 20 | "oldTaskId='" + oldTaskId + '\'' + 21 | '}'; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/android/Ups.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.android; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * Android厂商消息 8 | */ 9 | public class Ups { 10 | /** 11 | * 通知消息内容,与transmission 二选一,两个都填写时报错 12 | */ 13 | private ThirdNotification notification; 14 | /** 15 | * 透传消息内容,与notification 二选一,两个都填写时报错,长度 ≤ 3072 16 | */ 17 | private String transmission; 18 | 19 | /** 20 | * 第三方厂商扩展内容 21 | */ 22 | private Map> options; 23 | 24 | /** 25 | * 撤回消息时使用 26 | */ 27 | private ThirdRevokeBean revoke; 28 | 29 | public ThirdNotification getNotification() { 30 | return notification; 31 | } 32 | 33 | public void setNotification(ThirdNotification notification) { 34 | this.notification = notification; 35 | } 36 | 37 | public String getTransmission() { 38 | return transmission; 39 | } 40 | 41 | public void setTransmission(String transmission) { 42 | this.transmission = transmission; 43 | } 44 | 45 | public Map> getOptions() { 46 | return options; 47 | } 48 | 49 | public void setOptions(Map> options) { 50 | this.options = options; 51 | } 52 | 53 | public void addOptionAll(String key, Object value) { 54 | addOption("ALL", key, value); 55 | } 56 | 57 | public void addOption(String constraint, String key, Object value) { 58 | if (constraint == null || "".equals(constraint)) { 59 | constraint = "ALL"; 60 | } 61 | if (options == null) { 62 | options = new HashMap>(); 63 | } 64 | if (!options.containsKey(constraint)) { 65 | options.put(constraint, new HashMap()); 66 | } 67 | Map map = options.get(constraint); 68 | map.put(key, value); 69 | } 70 | 71 | public ThirdRevokeBean getRevoke() { 72 | return revoke; 73 | } 74 | 75 | public void setRevoke(ThirdRevokeBean revoke) { 76 | this.revoke = revoke; 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return "Ups{" + 82 | "notification=" + notification + 83 | ", transmission='" + transmission + '\'' + 84 | ", options=" + options + 85 | ", revoke=" + revoke + 86 | '}'; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/harmony/HarmonyDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.harmony; 2 | 3 | import com.getui.push.v2.sdk.dto.req.message.CustomBean; 4 | import com.getui.push.v2.sdk.dto.req.message.android.ThirdRevokeBean; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class HarmonyDTO { 10 | 11 | /** 12 | * 通知消息内容,与transmission、custom、revoke四选一,都填写时报错。 13 | * 若希望客户端离线时,直接在系统通知栏中展示通知栏消息,推荐使用此参数。 14 | */ 15 | private HarmonyNotification notification; 16 | /** 17 | * 透传消息内容,与notification、custom、revoke四选一,都填写时报错,长度 ≤ 3072字 18 | */ 19 | private String transmission; 20 | /** 21 | * 自定义消息内容,与notification、custom、revoke四选一,都填写时报错。 22 | */ 23 | private Map custom; 24 | /** 25 | * 撤回消息时使用 26 | */ 27 | private ThirdRevokeBean revoke; 28 | /** 29 | * 第三方厂商扩展内容 30 | */ 31 | private Map> options; 32 | 33 | public HarmonyNotification getNotification() { 34 | return notification; 35 | } 36 | 37 | public void setNotification(HarmonyNotification notification) { 38 | this.notification = notification; 39 | } 40 | 41 | public String getTransmission() { 42 | return transmission; 43 | } 44 | 45 | public void setTransmission(String transmission) { 46 | this.transmission = transmission; 47 | } 48 | 49 | public Map getCustom() { 50 | return custom; 51 | } 52 | 53 | public void setCustom(Map custom) { 54 | this.custom = custom; 55 | } 56 | 57 | public ThirdRevokeBean getRevoke() { 58 | return revoke; 59 | } 60 | 61 | public void setRevoke(ThirdRevokeBean revoke) { 62 | this.revoke = revoke; 63 | } 64 | 65 | public Map> getOptions() { 66 | return options; 67 | } 68 | 69 | public void setOptions(Map> options) { 70 | this.options = options; 71 | } 72 | 73 | public void addOptionAll(String key, Object value) { 74 | addOption("ALL", key, value); 75 | } 76 | 77 | public void addOption(String constraint, String key, Object value) { 78 | if (constraint == null || "".equals(constraint)) { 79 | constraint = "ALL"; 80 | } 81 | if (options == null) { 82 | options = new HashMap>(); 83 | } 84 | if (!options.containsKey(constraint)) { 85 | options.put(constraint, new HashMap()); 86 | } 87 | Map map = options.get(constraint); 88 | map.put(key, value); 89 | } 90 | 91 | @Override 92 | public String toString() { 93 | return "HarmonyDTO{" + 94 | "notification=" + notification + 95 | ", transmission='" + transmission + '\'' + 96 | ", custom=" + custom + 97 | ", revoke=" + revoke + 98 | ", options=" + options + 99 | '}'; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/harmony/HarmonyNotification.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.harmony; 2 | 3 | import com.getui.push.v2.sdk.dto.CommonEnum; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | public class HarmonyNotification { 7 | /** 8 | * 第三方厂商通知标题,长度 ≤ 50 9 | */ 10 | private String title; 11 | /** 12 | * 第三方厂商通知内容,长度 ≤ 256 13 | */ 14 | private String body; 15 | /** 16 | * 鸿蒙华为通知消息类别,长度 ≤ 50 17 | */ 18 | private String category; 19 | /** 20 | * @see CommonEnum.HarmonyClickTypeEnum 21 | * 点击通知后续动作, 22 | * 目前支持3种后续动作, 23 | * want:打开应用内特定页面, 24 | * startapp:打开应用首页 25 | * payload:通知扩展消息 26 | */ 27 | @SerializedName("click_type") 28 | private String clickType; 29 | /** 30 | * 鸿蒙平台点击动作

31 | * 示例:{"deviceId":"","bundleName":"com.getui.push","abilityName":"TestAbility","uri":"https://www.test.com:8080/push/test","action":"com.test.action","parameters":{"name":"Getui","age":12}} 32 | */ 33 | private String want; 34 | /** 35 | * 鸿蒙平台通知扩展消息的额外数据,传递给应用的数据,应用根据数据自行处理相关逻辑 36 | */ 37 | private String payload; 38 | 39 | /** 40 | * 消息覆盖使用,两条消息的notify_id相同,新的消息会覆盖老的消息 41 | * 范围:[0, 2147483647](如果要使用鸿蒙华为的消息撤回功能,此参数必填) 42 | */ 43 | @SerializedName("notify_id") 44 | private String notifyId; 45 | 46 | public String getTitle() { 47 | return title; 48 | } 49 | 50 | public void setTitle(String title) { 51 | this.title = title; 52 | } 53 | 54 | public String getBody() { 55 | return body; 56 | } 57 | 58 | public void setBody(String body) { 59 | this.body = body; 60 | } 61 | 62 | public String getCategory() { 63 | return category; 64 | } 65 | 66 | public void setCategory(String category) { 67 | this.category = category; 68 | } 69 | 70 | public String getClickType() { 71 | return clickType; 72 | } 73 | 74 | public void setClickType(String clickType) { 75 | this.clickType = clickType; 76 | } 77 | 78 | public String getWant() { 79 | return want; 80 | } 81 | 82 | public void setWant(String want) { 83 | this.want = want; 84 | } 85 | 86 | public String getPayload() { 87 | return payload; 88 | } 89 | 90 | public void setPayload(String payload) { 91 | this.payload = payload; 92 | } 93 | 94 | public String getNotifyId() { 95 | return notifyId; 96 | } 97 | 98 | public void setNotifyId(String notifyId) { 99 | this.notifyId = notifyId; 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | return "HarmonyNotification{" + 105 | "title='" + title + '\'' + 106 | ", body='" + body + '\'' + 107 | ", category='" + category + '\'' + 108 | ", clickType='" + clickType + '\'' + 109 | ", want='" + want + '\'' + 110 | ", payload='" + payload + '\'' + 111 | ", notifyId='" + notifyId + '\'' + 112 | '}'; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/ios/Alert.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.ios; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | 6 | /** 7 | * create by getui on 2020/7/20 8 | * 9 | * @author getui 10 | */ 11 | public class Alert extends HashMap { 12 | /** 13 | * 通知消息标题 14 | */ 15 | private final String title = "title"; 16 | /** 17 | * 通知消息内容 18 | */ 19 | private final String body = "body"; 20 | /** 21 | * (用于多语言支持)指定执行按钮所使用的Localizable.strings 22 | */ 23 | private final String actionLocKey = "action-loc-key"; 24 | /** 25 | * (用于多语言支持)指定Localizable.strings文件中相应的key 26 | */ 27 | private final String locKey = "loc-key"; 28 | /** 29 | * 如果loc-key中使用了占位符,则在loc-args中指定各参数 30 | */ 31 | private final String locArgs = "loc-args"; 32 | /** 33 | * 指定启动界面图片名 34 | */ 35 | private final String launchImage = "launch-image"; 36 | /** 37 | * (用于多语言支持)对于标题指定执行按钮所使用的Localizable.strings,仅支持iOS8.2以上版本 38 | */ 39 | private final String titleLocKey = "title-loc-key"; 40 | /** 41 | * 对于标题,如果loc-key中使用的占位符,则在loc-args中指定各参数,仅支持iOS8.2以上版本 42 | */ 43 | private final String titleLocArgs = "title-loc-args"; 44 | /** 45 | * 通知子标题,仅支持iOS8.2以上版本 46 | */ 47 | private final String subtitle = "subtitle"; 48 | /** 49 | * 当前本地化文件中的子标题字符串的关键字,仅支持iOS8.2以上版本 50 | */ 51 | private final String subtitleLocKey = "subtitle-loc-key"; 52 | /** 53 | * 当前本地化子标题内容中需要置换的变量参数 ,仅支持iOS8.2以上版本 54 | */ 55 | private final String subtitleLocArgs = "subtitle-loc-args"; 56 | 57 | public String getTitle() { 58 | return (String) super.get(this.title); 59 | } 60 | 61 | public void setTitle(String title) { 62 | super.put(this.title, title); 63 | } 64 | 65 | public String getBody() { 66 | return (String) super.get(this.body); 67 | } 68 | 69 | public void setBody(String body) { 70 | super.put(this.body, body); 71 | } 72 | 73 | public String getActionLocKey() { 74 | return (String) super.get(this.actionLocKey); 75 | } 76 | 77 | public void setActionLocKey(String actionLocKey) { 78 | super.put(this.actionLocKey, actionLocKey); 79 | } 80 | 81 | public String getLocKey() { 82 | return (String) super.get(this.locKey); 83 | } 84 | 85 | public void setLocKey(String locKey) { 86 | super.put(this.locKey, locKey); 87 | } 88 | 89 | public List getLocArgs() { 90 | return (List) super.get(this.locArgs); 91 | } 92 | 93 | public void setLocArgs(List locArgs) { 94 | super.put(this.locArgs, locArgs); 95 | } 96 | 97 | public String getLaunchImage() { 98 | return (String) super.get(this.launchImage); 99 | } 100 | 101 | public void setLaunchImage(String launchImage) { 102 | super.put(this.launchImage, launchImage); 103 | } 104 | 105 | public String getTitleLocKey() { 106 | return (String) super.get(this.titleLocKey); 107 | } 108 | 109 | public void setTitleLocKey(String titleLocKey) { 110 | super.put(this.titleLocKey, titleLocKey); 111 | } 112 | 113 | public List getTitleLocArgs() { 114 | return (List) super.get(this.titleLocArgs); 115 | } 116 | 117 | public void setTitleLocArgs(List titleLocArgs) { 118 | super.put(this.titleLocArgs, titleLocArgs); 119 | } 120 | 121 | public String getSubtitle() { 122 | return (String) super.get(this.subtitle); 123 | } 124 | 125 | public void setSubtitle(String subtitle) { 126 | super.put(this.subtitle, subtitle); 127 | } 128 | 129 | public String getSubtitleLocKey() { 130 | return (String) super.get(this.subtitleLocKey); 131 | } 132 | 133 | public void setSubtitleLocKey(String subtitleLocKey) { 134 | super.put(this.subtitleLocKey, subtitleLocKey); 135 | } 136 | 137 | public List getSubtitleLocArgs() { 138 | return (List) super.get(this.subtitleLocArgs); 139 | } 140 | 141 | public void setSubtitleLocArgs(List subtitleLocArgs) { 142 | super.put(this.subtitleLocArgs, subtitleLocArgs); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/ios/Aps.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.ios; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * create by getui on 2020/7/20 8 | * 9 | * @author getui 10 | */ 11 | public class Aps extends HashMap { 12 | /** 13 | * 通知消息 14 | */ 15 | private final String alert = "alert"; 16 | /** 17 | * 推送直接带有透传数据,content-available=1表示静默推送,静默推送时不需要填写其他参数,详细参数填写见示例,苹果建议1小时最多推送3条静默消息 18 | */ 19 | private final String contentAvailable = "content-available"; 20 | /** 21 | * 通知铃声文件名,无声设置为“com.gexin.ios.silence” 22 | */ 23 | private final String sound = "sound"; 24 | /** 25 | * 在客户端通知栏触发特定的action和button显示 26 | */ 27 | private final String category = "category"; 28 | 29 | /** 30 | * ios的远程通知通过该属性对通知进行分组,仅支持iOS 12.0以上版本 31 | */ 32 | private final String threadId = "thread-id"; 33 | 34 | /** 35 | * type为liveactivity时必填,当前时间,秒级10位时间戳 36 | */ 37 | private final String timestamp = "timestamp"; 38 | 39 | /** 40 | * 灵动岛推送事件,update:更新灵动岛,end:关闭灵动岛 41 | */ 42 | private final String event = "event"; 43 | 44 | /** 45 | * 实时活动消失时间,秒级10位时间戳,event为end,且需要按时关闭实时活动时填写 46 | */ 47 | private final String dismissalDate = "dismissal-date"; 48 | 49 | /** 50 | * 灵动岛推送透传参数,Json内的kv由业务方自定义,客户APP拿到值后自行解析 51 | */ 52 | private final String contentState = "content-state"; 53 | 54 | public Alert getAlert() { 55 | return (Alert) super.get(this.alert); 56 | } 57 | 58 | public void setAlert(Alert alert) { 59 | super.put(this.alert, alert); 60 | } 61 | 62 | public Integer getContentAvailable() { 63 | return (Integer) super.get(this.contentAvailable); 64 | } 65 | 66 | public void setContentAvailable(Integer contentAvailable) { 67 | super.put(this.contentAvailable, contentAvailable); 68 | } 69 | 70 | public String getSound() { 71 | return (String) super.get(this.sound); 72 | } 73 | 74 | public void setSound(String sound) { 75 | super.put(this.sound, sound); 76 | } 77 | 78 | public String getCategory() { 79 | return (String) super.get(this.category); 80 | } 81 | 82 | public void setCategory(String category) { 83 | super.put(this.category, category); 84 | } 85 | 86 | public String getThreadId() { 87 | return (String) super.get(this.threadId); 88 | } 89 | 90 | public void setThreadId(String threadId) { 91 | super.put(this.threadId, threadId); 92 | } 93 | 94 | public Integer getTimestamp() { 95 | return (Integer) super.get(this.timestamp); 96 | } 97 | 98 | public void setTimestamp(Integer timestamp) { 99 | super.put(this.timestamp, timestamp); 100 | } 101 | 102 | public String getEvent() { 103 | return (String) super.get(this.event); 104 | } 105 | 106 | public void setEvent(String event) { 107 | super.put(this.event, event); 108 | } 109 | 110 | public Integer getDismissalDate() { 111 | return (Integer) super.get(this.dismissalDate); 112 | } 113 | 114 | public void setDismissalDate(Integer dismissalDate) { 115 | super.put(this.dismissalDate, dismissalDate); 116 | } 117 | 118 | public Map getContentState() { 119 | return (Map) super.get(this.contentState); 120 | } 121 | 122 | public void setContentState(Map contentState) { 123 | super.put(this.contentState, contentState); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/ios/IosDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.ios; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | 7 | /** 8 | * create by getui on 2020/7/20 9 | * 10 | * @author getui 11 | */ 12 | public class IosDTO extends HashMap { 13 | /** 14 | * voip:voip语音推送,notify:apns通知消息 15 | */ 16 | private final String type = "type"; 17 | 18 | /** 19 | * 推送通知消息内容 20 | */ 21 | private final String aps = "aps"; 22 | /** 23 | * 用于计算icon上显示的数字,还可以实现显示数字的自动增减,如“+1”、 “-1”、 “1” 等,计算结果将覆盖badge 24 | */ 25 | private final String autoBadge = "auto_badge"; 26 | /** 27 | * 增加自定义的数据 28 | */ 29 | private final String payload = "payload"; 30 | /** 31 | * 多媒体设置 32 | */ 33 | private final String multimedia = "multimedia"; 34 | 35 | /** 36 | * 使用相同的apns-collapse-id可以覆盖之前的消息 37 | */ 38 | private final String apnsCollapseId = "apns-collapse-id"; 39 | /** 40 | * type选择liveactivity时,通过传入该参数选择指定推送的灵动岛 41 | */ 42 | private final String laId = "laId"; 43 | 44 | public IosDTO addMultimedia(Multimedia multimedia) { 45 | List multimediaList = getMultimedia(); 46 | if (multimedia == null) { 47 | return this; 48 | } 49 | if (multimediaList == null) { 50 | multimediaList = new ArrayList(); 51 | setMultimedia(multimediaList); 52 | } 53 | multimediaList.add(multimedia); 54 | return this; 55 | } 56 | 57 | public String getType() { 58 | return (String) super.get(this.type); 59 | } 60 | 61 | public void setType(String type) { 62 | super.put(this.type, type); 63 | } 64 | 65 | public Aps getAps() { 66 | return (Aps) super.get(this.aps); 67 | } 68 | 69 | public void setAps(Aps aps) { 70 | super.put(this.aps, aps); 71 | } 72 | 73 | public String getAutoBadge() { 74 | return (String) super.get(this.autoBadge); 75 | } 76 | 77 | public void setAutoBadge(String autoBadge) { 78 | super.put(this.autoBadge, autoBadge); 79 | } 80 | 81 | public String getPayload() { 82 | return (String) super.get(this.payload); 83 | } 84 | 85 | public void setPayload(String payload) { 86 | super.put(this.payload, payload); 87 | } 88 | 89 | public List getMultimedia() { 90 | return (List) super.get(this.multimedia); 91 | } 92 | 93 | public void setMultimedia(List multimedia) { 94 | super.put(this.multimedia, multimedia); 95 | } 96 | 97 | public String getApnsCollapseId() { 98 | return (String) super.get(this.apnsCollapseId); 99 | } 100 | 101 | public void setApnsCollapseId(String apnsCollapseId) { 102 | super.put(this.apnsCollapseId, apnsCollapseId); 103 | } 104 | 105 | public String getLaId() { 106 | return (String) super.get(this.laId); 107 | } 108 | 109 | public void setLaId(String laId) { 110 | super.put(this.laId, laId); 111 | } 112 | 113 | @Override 114 | public Object put(String key, Object value) { 115 | return super.put(key, value); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/req/message/ios/Multimedia.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.req.message.ios; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * create by getui on 2020/7/20 7 | * 8 | * @author getui 9 | */ 10 | public class Multimedia extends HashMap { 11 | /** 12 | * 多媒体资源地址 13 | */ 14 | private final String url = "url"; 15 | /** 16 | * 资源类型(1.图片,2.音频,3.视频) 17 | */ 18 | private final String type = "type"; 19 | /** 20 | * 是否只在wifi环境下加载,如果设置成true,但未使用wifi时,会展示成普通通知 21 | */ 22 | private final String onlyWifi = "only_wifi"; 23 | 24 | public String getUrl() { 25 | return (String) super.get(this.url); 26 | } 27 | 28 | public void setUrl(String url) { 29 | super.put(this.url, url); 30 | } 31 | 32 | public Integer getType() { 33 | return (Integer) super.get(this.type); 34 | } 35 | 36 | public void setType(Integer type) { 37 | super.put(this.type, type); 38 | } 39 | 40 | public boolean isOnlyWifi() { 41 | final Boolean isOnlyWifi = (Boolean) super.get(this.onlyWifi); 42 | return isOnlyWifi != null && isOnlyWifi; 43 | } 44 | 45 | public void setOnlyWifi(boolean onlyWifi) { 46 | super.put(this.onlyWifi, onlyWifi); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/AliasResDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res; 2 | 3 | /** 4 | * create by getui on 2020/6/3 5 | * 6 | * @author getui 7 | */ 8 | public class AliasResDTO { 9 | private String alias; 10 | 11 | public String getAlias() { 12 | return alias; 13 | } 14 | 15 | public void setAlias(String alias) { 16 | this.alias = alias; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "AliasResDTO{" + 22 | "alias='" + alias + '\'' + 23 | '}'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/CidStatusDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res; 2 | 3 | /** 4 | * create by getui on 2020/7/29 5 | * 6 | * @author getui 7 | */ 8 | public class CidStatusDTO { 9 | 10 | private String lastLoginTime; 11 | private String status; 12 | 13 | public String getLastLoginTime() { 14 | return lastLoginTime; 15 | } 16 | 17 | public void setLastLoginTime(String lastLoginTime) { 18 | this.lastLoginTime = lastLoginTime; 19 | } 20 | 21 | public String getStatus() { 22 | return status; 23 | } 24 | 25 | public void setStatus(String status) { 26 | this.status = status; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "CidStatusDTO{" + 32 | "lastLoginTime='" + lastLoginTime + '\'' + 33 | ", status='" + status + '\'' + 34 | '}'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/PushCountDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | * @author getui 7 | */ 8 | public class PushCountDTO { 9 | 10 | /** 11 | * 单日可推送总量 12 | */ 13 | @SerializedName("total_num") 14 | private Integer totalNum; 15 | 16 | /** 17 | * 单日可推送剩余量 18 | */ 19 | @SerializedName("remain_num") 20 | private Integer remainNum; 21 | 22 | /** 23 | * 单日可推送请求量 24 | * 仅vv返回该字段 25 | */ 26 | @SerializedName("push_num") 27 | private Integer pushNum; 28 | 29 | /** 30 | * 是否被限量 31 | * 当日可推送总量使用完时,该字段更新true 32 | */ 33 | @SerializedName("limit") 34 | private Boolean limit; 35 | 36 | 37 | public Integer getTotalNum() { 38 | return totalNum; 39 | } 40 | 41 | public void setTotalNum(Integer totalNum) { 42 | this.totalNum = totalNum; 43 | } 44 | 45 | public Integer getRemainNum() { 46 | return remainNum; 47 | } 48 | 49 | public void setRemainNum(Integer remainNum) { 50 | this.remainNum = remainNum; 51 | } 52 | 53 | public Integer getPushNum() { 54 | return pushNum; 55 | } 56 | 57 | public void setPushNum(Integer pushNum) { 58 | this.pushNum = pushNum; 59 | } 60 | 61 | public Boolean getLimit() { 62 | return limit; 63 | } 64 | 65 | public void setLimit(Boolean limit) { 66 | this.limit = limit; 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return "PushCountDTO{" + 72 | "totalNum=" + totalNum + 73 | ", remainNum=" + remainNum + 74 | ", pushNum=" + pushNum + 75 | ", limit=" + limit + 76 | '}'; 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/QueryCidResDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * create by getui on 2020/6/4 7 | * 8 | * @author getui 9 | */ 10 | public class QueryCidResDTO { 11 | private List cid; 12 | 13 | public List getCid() { 14 | return cid; 15 | } 16 | 17 | public void setCid(List cid) { 18 | this.cid = cid; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "QueryCidResDTO{" + 24 | "cid=" + cid + 25 | '}'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/ScheduleTaskDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res; 2 | 3 | /** 4 | * create by getui on 2020/8/8 5 | * 6 | * @author getui 7 | */ 8 | public class ScheduleTaskDTO { 9 | /** 10 | * 定时任务创建时间,毫秒时间戳 11 | */ 12 | private String createTime; 13 | /** 14 | * 定时任务状态:success/failed 15 | */ 16 | private String status; 17 | /** 18 | * 透传内容 19 | */ 20 | private String transmissionContent; 21 | /** 22 | * 定时任务推送时间,毫秒时间戳 23 | */ 24 | private String pushTime; 25 | 26 | public String getCreateTime() { 27 | return createTime; 28 | } 29 | 30 | public void setCreateTime(String createTime) { 31 | this.createTime = createTime; 32 | } 33 | 34 | public String getStatus() { 35 | return status; 36 | } 37 | 38 | public void setStatus(String status) { 39 | this.status = status; 40 | } 41 | 42 | public String getTransmissionContent() { 43 | return transmissionContent; 44 | } 45 | 46 | public void setTransmissionContent(String transmissionContent) { 47 | this.transmissionContent = transmissionContent; 48 | } 49 | 50 | public String getPushTime() { 51 | return pushTime; 52 | } 53 | 54 | public void setPushTime(String pushTime) { 55 | this.pushTime = pushTime; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "ScheduleTaskDTO{" + 61 | "createTime='" + createTime + '\'' + 62 | ", status='" + status + '\'' + 63 | ", transmissionContent='" + transmissionContent + '\'' + 64 | ", pushTime='" + pushTime + '\'' + 65 | '}'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/TaskIdDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | * create by getui on 2020/7/29 7 | * 8 | * @author getui 9 | */ 10 | public class TaskIdDTO { 11 | @SerializedName("taskid") 12 | private String taskId; 13 | 14 | public String getTaskId() { 15 | return taskId; 16 | } 17 | 18 | public void setTaskId(String taskId) { 19 | this.taskId = taskId; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return "TaskIdDTO{" + 25 | "taskId='" + taskId + '\'' + 26 | '}'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/TokenDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res; 2 | 3 | /** 4 | * create by getui on 2020/6/2 5 | * 6 | * @author getui 7 | */ 8 | public class TokenDTO { 9 | /** 10 | * token有效期 11 | */ 12 | public final static int EXPIRE_INTERVAL = 60 * 60 * 1000; 13 | 14 | private String token; 15 | private Long expireTime; 16 | 17 | /** 18 | * 校验token是否过期 19 | * 20 | * @return true表示过期 21 | */ 22 | public boolean expired() { 23 | if (expireTime == null) { 24 | return true; 25 | } 26 | if (expireTime - System.currentTimeMillis() < EXPIRE_INTERVAL) { 27 | return true; 28 | } 29 | return false; 30 | } 31 | 32 | /** 33 | * @return 34 | */ 35 | public boolean isNew() { 36 | if (expireTime == null) { 37 | return false; 38 | } 39 | return true; 40 | } 41 | 42 | public String getToken() { 43 | return token; 44 | } 45 | 46 | public void setToken(String token) { 47 | this.token = token; 48 | } 49 | 50 | public Long getExpireTime() { 51 | return expireTime; 52 | } 53 | 54 | public void setExpireTime(Long expireTime) { 55 | this.expireTime = expireTime; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "TokenDTO{" + 61 | "token='" + token + '\'' + 62 | ", expireTime=" + expireTime + 63 | '}'; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/statistic/StatisticDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res.statistic; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * @author getui 7 | */ 8 | public class StatisticDTO extends HashMap { 9 | 10 | /** 11 | * 可下发数 12 | */ 13 | public Integer getMsgNum() { 14 | return (Integer) this.get("msg_num"); 15 | } 16 | 17 | public void setMsgNum(Integer msgNum) { 18 | this.put("msg_num", msgNum); 19 | } 20 | 21 | /** 22 | * 下发数 23 | */ 24 | public Integer getTargetNum() { 25 | return (Integer) this.get("target_num"); 26 | } 27 | 28 | public void setTargetNum(Integer targetNum) { 29 | this.put("target_num", targetNum); 30 | } 31 | 32 | /** 33 | * 到达数 34 | */ 35 | public Integer getReceiveNum() { 36 | return (Integer) this.get("receive_num"); 37 | } 38 | 39 | public void setReceiveNum(Integer receiveNum) { 40 | this.put("receive_num", receiveNum); 41 | } 42 | 43 | /** 44 | * 展示数 45 | */ 46 | public Integer getDisplayNum() { 47 | return (Integer) this.get("display_num"); 48 | } 49 | 50 | public void setDisplayNum(Integer displayNum) { 51 | this.put("display_num", displayNum); 52 | } 53 | 54 | /** 55 | * 点击数 56 | */ 57 | public Integer getClickNum() { 58 | return (Integer) this.get("click_num"); 59 | } 60 | 61 | public void setClickNum(Integer clickNum) { 62 | this.put("click_num", clickNum); 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return "StatisticDTO" + super.toString(); 68 | } 69 | } -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/dto/res/statistic/UserStatisticDTO.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.dto.res.statistic; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | * @author getui 7 | */ 8 | public class UserStatisticDTO { 9 | @SerializedName("accumulative_num") 10 | private Integer accumulativeNum; 11 | @SerializedName("register_num") 12 | private Integer registerNum; 13 | @SerializedName("active_num") 14 | private Integer activeNum; 15 | @SerializedName("online_num") 16 | private Integer onlineNum; 17 | 18 | public Integer getAccumulativeNum() { 19 | return accumulativeNum; 20 | } 21 | 22 | public void setAccumulativeNum(Integer accumulativeNum) { 23 | this.accumulativeNum = accumulativeNum; 24 | } 25 | 26 | public Integer getRegisterNum() { 27 | return registerNum; 28 | } 29 | 30 | public void setRegisterNum(Integer registerNum) { 31 | this.registerNum = registerNum; 32 | } 33 | 34 | public Integer getActiveNum() { 35 | return activeNum; 36 | } 37 | 38 | public void setActiveNum(Integer activeNum) { 39 | this.activeNum = activeNum; 40 | } 41 | 42 | public Integer getOnlineNum() { 43 | return onlineNum; 44 | } 45 | 46 | public void setOnlineNum(Integer onlineNum) { 47 | this.onlineNum = onlineNum; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return "UserStatisticDTO{" + 53 | "accumulativeNum=" + accumulativeNum + 54 | ", registerNum=" + registerNum + 55 | ", activeNum=" + activeNum + 56 | ", onlineNum=" + onlineNum + 57 | '}'; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/getui/push/v2/sdk/spring/GtBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.spring; 2 | 3 | import com.getui.push.v2.sdk.ApiHelper; 4 | import com.getui.push.v2.sdk.GtApiConfiguration; 5 | import com.getui.push.v2.sdk.common.ApiException; 6 | import org.springframework.beans.factory.FactoryBean; 7 | import org.springframework.beans.factory.InitializingBean; 8 | 9 | /** 10 | * create by getui on 2020/6/4 11 | * 12 | * @author getui 13 | */ 14 | public class GtBeanFactory implements FactoryBean, InitializingBean { 15 | 16 | /** 17 | * 创建代理类的工厂类 18 | */ 19 | private ApiHelper apiHelper; 20 | 21 | private Class apiClass; 22 | 23 | private T api; 24 | 25 | /** 26 | * 标记是否调用方法 {@link #afterPropertiesSet()} 27 | */ 28 | volatile boolean calledMethodAfterPropertiesSet = false; 29 | 30 | public GtBeanFactory(GtApiConfiguration configuration) { 31 | if (configuration == null) { 32 | throw new ApiException("configuration cannot be null.", true); 33 | } 34 | apiHelper = ApiHelper.build(configuration); 35 | } 36 | 37 | @Override 38 | public T getObject() { 39 | if (api != null) { 40 | return api; 41 | } 42 | if (!calledMethodAfterPropertiesSet) { 43 | throw new ApiException("please call method afterPropertiesSet first."); 44 | } else { 45 | // 理论上是不会出现这种可能性的 46 | throw new ApiException("api is null, please check."); 47 | } 48 | } 49 | 50 | @Override 51 | public Class getObjectType() { 52 | return apiClass; 53 | } 54 | 55 | @Override 56 | public boolean isSingleton() { 57 | return true; 58 | } 59 | 60 | @Override 61 | public void afterPropertiesSet() { 62 | if (apiHelper == null) { 63 | throw new ApiException("gtApiProxyFactory cannot be null.", true); 64 | } 65 | if (apiClass == null) { 66 | throw new ApiException("apiClass cannot be null.", true); 67 | } 68 | api = apiHelper.creatApi(apiClass); 69 | this.calledMethodAfterPropertiesSet = true; 70 | } 71 | 72 | public void setApiClass(Class apiClass) { 73 | this.apiClass = apiClass; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/test/java/com/getui/push/v2/sdk/api/Jsons.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api; 2 | 3 | import com.getui.push.v2.sdk.IJson; 4 | import com.getui.push.v2.sdk.core.DefaultJson; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.io.IOException; 9 | import java.lang.reflect.Type; 10 | 11 | public final class Jsons { 12 | 13 | static IJson json = new DefaultJson(); 14 | 15 | private static final Logger logger = LoggerFactory.getLogger(Jsons.class); 16 | 17 | public static void main(String[] args) throws IOException { 18 | } 19 | 20 | public static T fromJson(String jsonString, Type type) { 21 | if (jsonString == null || jsonString.trim().length() == 0) { 22 | return null; 23 | } else { 24 | try { 25 | return json.fromJson(jsonString, type); 26 | } catch (Exception var3) { 27 | logger.error("parse json string to object error, input=" + jsonString, var3); 28 | return null; 29 | } 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/getui/push/v2/sdk/api/StatisticApiTest.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api; 2 | 3 | import com.getui.push.v2.sdk.ApiHelper; 4 | import com.getui.push.v2.sdk.GtApiConfiguration; 5 | import com.getui.push.v2.sdk.api.env.ApiContext; 6 | import com.getui.push.v2.sdk.api.util.Utils; 7 | import com.getui.push.v2.sdk.common.ApiResult; 8 | import com.getui.push.v2.sdk.dto.res.PushCountDTO; 9 | import com.getui.push.v2.sdk.dto.res.statistic.StatisticDTO; 10 | import com.getui.push.v2.sdk.dto.res.statistic.UserStatisticDTO; 11 | import org.junit.Before; 12 | import org.junit.Test; 13 | 14 | import java.util.Map; 15 | 16 | /** 17 | * create by getui on 2020/10/28 18 | * 19 | * @author getui 20 | */ 21 | public class StatisticApiTest { 22 | 23 | StatisticApi pushApi; 24 | 25 | @Before 26 | public void before() { 27 | final ApiContext apiContext = ApiContext.build(); 28 | GtApiConfiguration apiConfiguration = apiContext.configuration; 29 | // apiConfiguration.setOpenAnalyseStableDomainSwitch(false); 30 | 31 | ApiHelper apiHelper = ApiHelper.build(apiConfiguration); 32 | pushApi = apiHelper.creatApi(StatisticApi.class); 33 | } 34 | 35 | @Test 36 | public void queryPushResultByTaskIds() { 37 | final ApiResult>> result = pushApi.queryPushResultByTaskIds( 38 | Utils.newHashSet("taskId")); 39 | System.out.println(result); 40 | } 41 | 42 | @Test 43 | public void queryPushResultByTaskIdsAndActionIds() { 44 | final ApiResult>> result = pushApi.queryPushResultByTaskIdsAndActionIds(Utils.newHashSet("taskId1", 45 | "taskId2", "taskId3"), Utils.newHashSet("actionId1", "actionId2")); 46 | System.out.println(result); 47 | } 48 | 49 | @Test 50 | public void queryPushResultByGroupName() { 51 | final ApiResult>> result = pushApi.queryPushResultByGroupName("group1"); 52 | System.out.println(result); 53 | } 54 | 55 | @Test 56 | public void queryPushResultByDate() { 57 | final ApiResult>> result = pushApi.queryPushResultByDate("2021-01-01"); 58 | System.out.println(result); 59 | } 60 | 61 | @Test 62 | public void queryUserDataByDate() { 63 | final ApiResult>> result = pushApi.queryUserDataByDate("2021-01-01"); 64 | System.out.println(result); 65 | } 66 | 67 | @Test 68 | public void queryOnlineUserData() { 69 | final ApiResult>> result = pushApi.queryOnlineUserData(); 70 | System.out.println(result); 71 | } 72 | 73 | @Test 74 | public void queryPushCountData() { 75 | final ApiResult>> result = pushApi.queryPushCountData(); 76 | System.out.println(result); 77 | } 78 | 79 | @Test 80 | public void queryPushTaskDetailData() { 81 | final ApiResult>> result = pushApi.queryPushTaskDetailData( 82 | Utils.newHashSet("taskId1", "taskId2") 83 | ); 84 | System.out.println(result); 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /src/test/java/com/getui/push/v2/sdk/api/UserApiTest.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api; 2 | 3 | import com.getui.push.v2.sdk.ApiHelper; 4 | import com.getui.push.v2.sdk.GtApiConfiguration; 5 | import com.getui.push.v2.sdk.api.env.ApiContext; 6 | import com.getui.push.v2.sdk.api.util.Utils; 7 | import com.getui.push.v2.sdk.common.ApiResult; 8 | import com.getui.push.v2.sdk.dto.CommonEnum; 9 | import com.getui.push.v2.sdk.dto.req.*; 10 | import com.getui.push.v2.sdk.dto.res.AliasResDTO; 11 | import com.getui.push.v2.sdk.dto.res.QueryCidResDTO; 12 | import org.junit.Before; 13 | import org.junit.Test; 14 | 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | /** 19 | * create by getui on 2020/6/4 20 | * 21 | * @author getui 22 | */ 23 | public class UserApiTest { 24 | String cid = ""; 25 | UserApi userApi; 26 | ApiContext apiContext = ApiContext.build(); 27 | 28 | @Before 29 | public void setUp() { 30 | GtApiConfiguration apiConfiguration = apiContext.configuration; 31 | apiConfiguration.setMaxHttpTryTime(0); 32 | apiConfiguration.setOpenCheckHealthDataSwitch(true); 33 | apiConfiguration.setOpenAnalyseStableDomainSwitch(true); 34 | apiConfiguration.setSoTimeout(5000); 35 | apiConfiguration.setConnectTimeout(5000); 36 | // apiConfiguration.setProxyConfig(new GtHttpProxyConfig("proxy_ip", 80, "proxy_username", "proxy_password")); 37 | 38 | cid = apiContext.cid; 39 | 40 | ApiHelper apiHelper = ApiHelper.build(apiConfiguration); 41 | userApi = apiHelper.creatApi(UserApi.class); 42 | } 43 | 44 | @Test 45 | public void addBlackUser() { 46 | System.out.println(userApi.addBlackUser(Utils.newHashSet(cid))); 47 | } 48 | 49 | @Test 50 | public void removeBlackUser() { 51 | System.out.println(userApi.removeBlackUser(Utils.newHashSet(cid))); 52 | } 53 | 54 | @Test 55 | public void queryUserStatus() { 56 | System.out.println(userApi.queryUserStatus(Utils.newHashSet(cid))); 57 | } 58 | 59 | @Test 60 | public void setBadge() { 61 | BadgeDTO badgeDTO = new BadgeDTO(); 62 | badgeDTO.setBadge("+1"); 63 | System.out.println(userApi.setBadge(Utils.newHashSet(cid), badgeDTO)); 64 | } 65 | 66 | @Test 67 | public void queryUser() { 68 | final Condition condition = new Condition(); 69 | condition.setKey("region"); 70 | condition.addValue(""); 71 | condition.setOptType(CommonEnum.OptTypeEnum.TYPE_AND.type); 72 | System.out.println(userApi.queryUser(ConditionListDTO.build().addCondition(condition))); 73 | ; 74 | } 75 | 76 | @Test 77 | public void bindAlias() throws InterruptedException { 78 | while (true) { 79 | System.out.println("==============================================="); 80 | CidAliasListDTO cidAliasListDTO = new CidAliasListDTO(); 81 | cidAliasListDTO.add(new CidAliasListDTO.CidAlias(cid, "2221")); 82 | ApiResult apiResult = userApi.bindAlias(cidAliasListDTO); 83 | System.out.println(apiResult); 84 | Thread.sleep(1000); 85 | return; 86 | } 87 | } 88 | 89 | @Test 90 | public void queryAliasByCid() { 91 | QueryAliasDTO queryAliasDTO = new QueryAliasDTO(); 92 | queryAliasDTO.setCid(cid); 93 | ApiResult apiResult = userApi.queryAliasByCid(queryAliasDTO.getCid()); 94 | System.out.println(apiResult); 95 | } 96 | 97 | @Test 98 | public void queryAliasByCidAndType() { 99 | QueryAliasDTO queryAliasDTO = new QueryAliasDTO(); 100 | queryAliasDTO.setCid(cid); 101 | ApiResult apiResult = userApi.queryAliasByCid(queryAliasDTO.getCid(),"t-2"); 102 | System.out.println(apiResult); 103 | } 104 | 105 | @Test 106 | public void queryCidByAlias() { 107 | ApiResult apiResult = userApi.queryCidByAlias("alias"); 108 | System.out.println(apiResult); 109 | } 110 | 111 | @Test 112 | public void queryCidByAliasAndType() { 113 | ApiResult apiResult = userApi.queryCidByAlias("2221","t-1"); 114 | System.out.println(apiResult); 115 | } 116 | 117 | @Test 118 | public void batchUnboundAlias() { 119 | CidAliasListDTO cidAliasListDTO = new CidAliasListDTO(); 120 | cidAliasListDTO.add(new CidAliasListDTO.CidAlias(cid, "alias")); 121 | ApiResult apiResult = userApi.batchUnbindAlias(cidAliasListDTO); 122 | System.out.println(apiResult); 123 | } 124 | 125 | @Test 126 | public void unboundAllAlias() { 127 | ApiResult apiResult = userApi.unbindAllAlias("alias"); 128 | System.out.println(apiResult); 129 | } 130 | 131 | @Test 132 | public void unboundAllAliasWithType() { 133 | ApiResult apiResult = userApi.unbindAllAlias("2221","t-1"); 134 | System.out.println(apiResult); 135 | } 136 | 137 | @Test 138 | public void userBindTags() { 139 | ApiResult apiResult = userApi.userBindTags(cid, TagDTO.build().addTag("tag1").addTag("tag2").addTag("tag3")); 140 | System.out.println(apiResult); 141 | } 142 | 143 | @Test 144 | public void usersBindTag() { 145 | ApiResult> apiResult = userApi.usersBindTag("tag", UserDTO.build().addCid(cid).addCid(cid)); 146 | System.out.println(apiResult); 147 | } 148 | 149 | @Test 150 | public void deleteUsersTag() { 151 | ApiResult> apiResult = userApi.deleteUsersTag("tag", UserDTO.build().addCid(cid)); 152 | System.out.println(apiResult); 153 | } 154 | 155 | @Test 156 | public void queryUserTags() { 157 | System.out.println(userApi.toString()); 158 | ApiResult>> apiResult = userApi.queryUserTags(cid); 159 | System.out.println(apiResult); 160 | } 161 | } -------------------------------------------------------------------------------- /src/test/java/com/getui/push/v2/sdk/api/env/ApiContext.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api.env; 2 | 3 | import com.getui.push.v2.sdk.GtApiConfiguration; 4 | 5 | public class ApiContext { 6 | 7 | public GtApiConfiguration configuration; 8 | public String cid; 9 | 10 | public static ApiContext build() { 11 | ApiContext context = new ApiContext(); 12 | GtApiConfiguration apiConfiguration = new GtApiConfiguration(); 13 | context.configuration = apiConfiguration; 14 | 15 | apiConfiguration.setAppId("appId"); 16 | apiConfiguration.setAppKey("appKey"); 17 | apiConfiguration.setMasterSecret("masterSecret"); 18 | // 接口调用前缀,请查看文档: 接口调用规范 -> 接口前缀, 可不填写appId 19 | apiConfiguration.setDomain("https://restapi.getui.com/v2/"); 20 | context.cid = "CID"; 21 | 22 | return context; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/getui/push/v2/sdk/api/util/Utils.java: -------------------------------------------------------------------------------- 1 | package com.getui.push.v2.sdk.api.util; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * create by 远见 on 2022/5/12 8 | * 9 | * @author liuyj@getui.com 10 | */ 11 | public class Utils { 12 | public static Set newHashSet(T... arr) { 13 | Set set = new HashSet(arr.length); 14 | for (T t : arr) { 15 | set.add(t); 16 | } 17 | return set; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/resource/Spring-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | --------------------------------------------------------------------------------