初始化

This commit is contained in:
谢洪龙
2017-08-23 12:20:15 +08:00
commit 491d430741
471 changed files with 16355 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v7.0"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
+42
View File
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>quartzPro</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry kind="src" path="target/m2e-wtp/web-resources"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>
@@ -0,0 +1,3 @@
eclipse.preferences.version=1
encoding//src/main/resources/jPpush.properties=UTF-8
encoding/<project>=UTF-8
+13
View File
@@ -0,0 +1,13 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
+4
View File
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="quartzPro">
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<property name="context-root" value="quartzPro"/>
<property name="java-output-path" value="/quartzPro/target/classes"/>
</wb-module>
</project-modules>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="java" version="1.7"/>
<installed facet="jst.web" version="3.0"/>
</faceted-project>
@@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
@@ -0,0 +1 @@
Window
@@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1
+1
View File
@@ -0,0 +1 @@
12
+1
View File
@@ -0,0 +1 @@
12
@@ -0,0 +1,232 @@
package com.ifish.jpush.device;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.reflect.TypeToken;
import com.ifish.jpush.common.ClientConfig;
import com.ifish.jpush.common.ServiceHelper;
import com.ifish.jpush.common.connection.HttpProxy;
import com.ifish.jpush.common.connection.IHttpClient;
import com.ifish.jpush.common.connection.NativeHttpClient;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.common.resp.BaseResult;
import com.ifish.jpush.common.resp.BooleanResult;
import com.ifish.jpush.common.resp.DefaultResult;
import com.ifish.jpush.common.resp.ResponseWrapper;
import com.ifish.jpush.utils.Preconditions;
public class DeviceClient {
private final NativeHttpClient _httpClient;
private String hostName;
private String devicesPath;
private String tagsPath;
private String aliasesPath;
public DeviceClient(String masterSecret, String appKey) {
this(masterSecret, appKey, IHttpClient.DEFAULT_MAX_RETRY_TIMES);
}
public DeviceClient(String masterSecret, String appKey, int maxRetryTimes) {
this(masterSecret, appKey, maxRetryTimes, null);
}
public DeviceClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy) {
this(masterSecret, appKey, maxRetryTimes, proxy, ClientConfig.getInstance());
}
/**
*
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
* @param maxRetryTimes Max retry times
* @param proxy The proxy, if there is no proxy, should be null.
* @param conf The client configuration. Can use ClientConfig.getInstance() as default.
*/
public DeviceClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy, ClientConfig conf) {
ServiceHelper.checkBasic(appKey, masterSecret);
hostName = (String) conf.get(ClientConfig.DEVICE_HOST_NAME);
devicesPath = (String) conf.get(ClientConfig.DEVICES_PATH);
tagsPath = (String) conf.get(ClientConfig.TAGS_PATH);
aliasesPath = (String) conf.get(ClientConfig.ALIASES_PATH);
String authCode = ServiceHelper.getBasicAuthorization(appKey, masterSecret);
_httpClient = new NativeHttpClient(authCode, maxRetryTimes, proxy);
}
// -------------- device
public TagAliasResult getDeviceTagAlias(String registrationId) throws APIConnectionException, APIRequestException {
String url = hostName + devicesPath + "/" + registrationId;
ResponseWrapper response = _httpClient.sendGet(url);
return BaseResult.fromResponse(response, TagAliasResult.class);
}
public DefaultResult updateDeviceTagAlias(String registrationId, boolean clearAlias, boolean clearTag) throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(clearAlias || clearTag, "It is not meaningful to do nothing.");
String url = hostName + devicesPath + "/" + registrationId;
JsonObject top = new JsonObject();
if (clearAlias) {
top.addProperty("alias", "");
}
if (clearTag) {
top.addProperty("tags", "");
}
ResponseWrapper response = _httpClient.sendPost(url, top.toString());
return DefaultResult.fromResponse(response);
}
public DefaultResult updateDeviceTagAlias(String registrationId, String alias,
Set<String> tagsToAdd, Set<String> tagsToRemove) throws APIConnectionException, APIRequestException {
String url = hostName + devicesPath + "/" + registrationId;
JsonObject top = new JsonObject();
if (null != alias) {
top.addProperty("alias", alias);
}
JsonObject tagObject = new JsonObject();
JsonArray tagsAdd = ServiceHelper.fromSet(tagsToAdd);
if (tagsAdd.size() > 0) {
tagObject.add("add", tagsAdd);
}
JsonArray tagsRemove = ServiceHelper.fromSet(tagsToRemove);
if (tagsRemove.size() > 0) {
tagObject.add("remove", tagsRemove);
}
if (tagObject.entrySet().size() > 0) {
top.add("tags", tagObject);
}
ResponseWrapper response = _httpClient.sendPost(url, top.toString());
return DefaultResult.fromResponse(response);
}
// ------------- tags
public TagListResult getTagList() throws APIConnectionException, APIRequestException {
String url = hostName + tagsPath + "/";
ResponseWrapper response = _httpClient.sendGet(url);
return TagListResult.fromResponse(response, TagListResult.class);
}
public BooleanResult isDeviceInTag(String theTag, String registrationID) throws APIConnectionException, APIRequestException {
String url = hostName + tagsPath + "/" + theTag + "/registration_ids/" + registrationID;
ResponseWrapper response = _httpClient.sendGet(url);
return BaseResult.fromResponse(response, BooleanResult.class);
}
public DefaultResult addRemoveDevicesFromTag(String theTag, Set<String> toAddUsers, Set<String> toRemoveUsers) throws APIConnectionException, APIRequestException {
String url = hostName + tagsPath + "/" + theTag;
JsonObject top = new JsonObject();
JsonObject registrationIds = new JsonObject();
if (null != toAddUsers && toAddUsers.size() > 0) {
JsonArray array = new JsonArray();
for (String user : toAddUsers) {
array.add(new JsonPrimitive(user));
}
registrationIds.add("add", array);
}
if (null != toRemoveUsers && toRemoveUsers.size() > 0) {
JsonArray array = new JsonArray();
for (String user : toRemoveUsers) {
array.add(new JsonPrimitive(user));
}
registrationIds.add("remove", array);
}
top.add("registration_ids", registrationIds);
ResponseWrapper response = _httpClient.sendPost(url, top.toString());
return DefaultResult.fromResponse(response);
}
public DefaultResult deleteTag(String theTag, String platform) throws APIConnectionException, APIRequestException {
String url = hostName + tagsPath + "/" + theTag;
if (null != platform) {
url += "?platform=" + platform;
}
ResponseWrapper response = _httpClient.sendDelete(url);
return DefaultResult.fromResponse(response);
}
// ------------- alias
public AliasDeviceListResult getAliasDeviceList(String alias, String platform) throws APIConnectionException, APIRequestException {
String url = hostName + aliasesPath + "/" + alias;
if (null != platform) {
url += "?platform=" + platform;
}
ResponseWrapper response = _httpClient.sendGet(url);
return BaseResult.fromResponse(response, AliasDeviceListResult.class);
}
public DefaultResult deleteAlias(String alias, String platform) throws APIConnectionException, APIRequestException {
String url = hostName + aliasesPath + "/" + alias;
if (null != platform) {
url += "?platform=" + platform;
}
ResponseWrapper response = _httpClient.sendDelete(url);
return DefaultResult.fromResponse(response);
}
// -------------- devices status
public Map<String, OnlineStatus> getUserOnlineStatus(String... registrationIds)
throws APIConnectionException, APIRequestException
{
Preconditions.checkArgument((null != registrationIds ),
"The registration id list should not be null.");
Preconditions.checkArgument(registrationIds!=null && registrationIds.length > 0 && registrationIds.length <= 1000,
"The length of registration id list should between 1 and 1000.");
String url = hostName + devicesPath + "/status";
JsonObject json = new JsonObject();
JsonArray array = new JsonArray();
if(registrationIds!=null){
for(int i = 0; i < registrationIds.length; i++) {
array.add(new JsonPrimitive(registrationIds[i]));
}
}
json.add("registration_ids", array);
Type type = new TypeToken<Map<String, OnlineStatus>>(){}.getType();
ResponseWrapper response = _httpClient.sendPost(url, json.toString());
Map<String, OnlineStatus> map = new Gson().fromJson(response.responseContent, type);
return map;
}
}
@@ -0,0 +1,8 @@
package com.ifish.jpush.schedule.model;
import com.google.gson.JsonElement;
public interface IModel {
public JsonElement toJSON();
}
@@ -0,0 +1,807 @@
package com.ifish.jpush;
import java.util.Map;
import java.util.Set;
import com.google.gson.JsonObject;
import com.ifish.jpush.common.ClientConfig;
import com.ifish.jpush.common.TimeUnit;
import com.ifish.jpush.common.Week;
import com.ifish.jpush.common.connection.HttpProxy;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.common.resp.BooleanResult;
import com.ifish.jpush.common.resp.DefaultResult;
import com.ifish.jpush.device.AliasDeviceListResult;
import com.ifish.jpush.device.DeviceClient;
import com.ifish.jpush.device.OnlineStatus;
import com.ifish.jpush.device.TagAliasResult;
import com.ifish.jpush.device.TagListResult;
import com.ifish.jpush.push.PushClient;
import com.ifish.jpush.push.PushResult;
import com.ifish.jpush.push.model.Message;
import com.ifish.jpush.push.model.Platform;
import com.ifish.jpush.push.model.PushPayload;
import com.ifish.jpush.push.model.audience.Audience;
import com.ifish.jpush.push.model.notification.IosAlert;
import com.ifish.jpush.push.model.notification.Notification;
import com.ifish.jpush.report.MessagesResult;
import com.ifish.jpush.report.ReceivedsResult;
import com.ifish.jpush.report.ReportClient;
import com.ifish.jpush.report.UsersResult;
import com.ifish.jpush.schedule.ScheduleClient;
import com.ifish.jpush.schedule.ScheduleListResult;
import com.ifish.jpush.schedule.ScheduleResult;
import com.ifish.jpush.schedule.model.SchedulePayload;
import com.ifish.jpush.schedule.model.TriggerPayload;
import com.ifish.jpush.utils.Preconditions;
/**
* The global entrance of JPush API library.
*/
public class JPushClient {
private final PushClient _pushClient;
private final ReportClient _reportClient;
private final DeviceClient _deviceClient;
private final ScheduleClient _scheduleClient;
/**
* Create a JPush Client.
*
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
*/
public JPushClient(String masterSecret, String appKey) {
_pushClient = new PushClient(masterSecret, appKey);
_reportClient = new ReportClient(masterSecret, appKey);
_deviceClient = new DeviceClient(masterSecret, appKey);
_scheduleClient = new ScheduleClient(masterSecret, appKey);
}
public JPushClient(String masterSecret, String appKey, int maxRetryTimes) {
_pushClient = new PushClient(masterSecret, appKey, maxRetryTimes);
_reportClient = new ReportClient(masterSecret, appKey, maxRetryTimes);
_deviceClient = new DeviceClient(masterSecret, appKey, maxRetryTimes);
_scheduleClient = new ScheduleClient(masterSecret, appKey, maxRetryTimes);
}
public JPushClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy) {
_pushClient = new PushClient(masterSecret, appKey, maxRetryTimes, proxy);
_reportClient = new ReportClient(masterSecret, appKey, maxRetryTimes, proxy);
_deviceClient = new DeviceClient(masterSecret, appKey, maxRetryTimes, proxy);
_scheduleClient = new ScheduleClient(masterSecret, appKey, maxRetryTimes, proxy);
}
/**
* Create a JPush Client by custom Client configuration.
*
* If you are using JPush privacy cloud, maybe this constructor is what you needed.
*
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
* @param maxRetryTimes Client request retry times.
* @param proxy The proxy, if there is no proxy, should be null.
* @param conf The client configuration. Can use ClientConfig.getInstance() as default.
*/
public JPushClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy, ClientConfig conf) {
_pushClient = new PushClient(masterSecret, appKey, maxRetryTimes, proxy, conf);
_reportClient = new ReportClient(masterSecret, appKey, maxRetryTimes, proxy, conf);
_deviceClient = new DeviceClient(masterSecret, appKey, maxRetryTimes, proxy, conf);
_scheduleClient = new ScheduleClient(masterSecret, appKey, maxRetryTimes, proxy, conf);
}
/**
* Create a JPush Client by custom Client configuration with global settings.
*
* If you are using JPush privacy cloud, and you want different settings from default globally,
* maybe this constructor is what you needed.
*
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
* @param maxRetryTimes Client request retry times.
* @param proxy The proxy, if there is no proxy, should be null.
* @param conf The client configuration. Can use ClientConfig.getInstance() as default.
* @param apnsProduction Global APNs environment setting. It will override PushPayload Options.
* @param timeToLive Global time_to_live setting. It will override PushPayload Options.
*/
public JPushClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy, ClientConfig conf,
boolean apnsProduction, long timeToLive) {
_pushClient = new PushClient(masterSecret, appKey, maxRetryTimes, proxy, conf);
_reportClient = new ReportClient(masterSecret, appKey, maxRetryTimes, proxy, conf);
_deviceClient = new DeviceClient(masterSecret, appKey, maxRetryTimes, proxy, conf);
_scheduleClient = new ScheduleClient(masterSecret, appKey, maxRetryTimes, proxy, conf);
_pushClient.setDefaults(apnsProduction, timeToLive);
}
/**
* Create a JPush Client with global settings.
*
* If you want different settings from default globally, this constructor is what you needed.
*
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
* @param apnsProduction Global APNs environment setting. It will override PushPayload Options.
* @param timeToLive Global time_to_live setting. It will override PushPayload Options.
*/
public JPushClient(String masterSecret, String appKey, boolean apnsProduction, long timeToLive) {
_pushClient = new PushClient(masterSecret, appKey, apnsProduction, timeToLive);
_reportClient = new ReportClient(masterSecret, appKey);
_deviceClient = new DeviceClient(masterSecret, appKey);
_scheduleClient = new ScheduleClient(masterSecret, appKey);
}
// ----------------------------- Push API
/**
* Send a push with PushPayload object.
*
* @param pushPayload payload object of a push.
* @return PushResult The result object of a Push. Can be printed to a JSON.
* @throws APIConnectionException
* @throws APIRequestException
*/
public PushResult sendPush(PushPayload pushPayload) throws APIConnectionException, APIRequestException {
return _pushClient.sendPush(pushPayload);
}
/**
* Send a push with JSON string.
*
* You can send a push JSON string directly with this method.
*
* Attention: globally settings cannot be affect this type of Push.
*
* @param payloadString payload of a push.
* @return PushResult. Can be printed to a JSON.
* @throws APIConnectionException
* @throws APIRequestException
*/
public PushResult sendPush(String payloadString) throws APIConnectionException, APIRequestException {
return _pushClient.sendPush(payloadString);
}
/**
* Validate a push action, but do NOT send it actually.
*
* @param paylaod
* @return
* @throws APIConnectionException
* @throws APIRequestException
*/
public PushResult sendPushValidate(PushPayload paylaod) throws APIConnectionException, APIRequestException {
return _pushClient.sendPushValidate(paylaod);
}
public PushResult sendPushValidate(String payloadString) throws APIConnectionException, APIRequestException {
return _pushClient.sendPushValidate(payloadString);
}
// ------------------------------- Report API
/**
* Get received report.
*
* @param msgIds 100 msgids to batch getting is supported.
* @return ReceivedResult. Can be printed to JSON.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ReceivedsResult getReportReceiveds(String msgIds) throws APIConnectionException, APIRequestException {
return _reportClient.getReceiveds(msgIds);
}
public UsersResult getReportUsers(TimeUnit timeUnit, String start, int duration) throws APIConnectionException, APIRequestException {
return _reportClient.getUsers(timeUnit, start, duration);
}
public MessagesResult getReportMessages(String msgIds) throws APIConnectionException, APIRequestException {
return _reportClient.getMessages(msgIds);
}
// ------------------------------ Shortcuts - notification
/**
* Shortcut
*/
public PushResult sendNotificationAll(String alert) throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.alertAll(alert);
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendAndroidNotificationWithAlias(String title, String alert,
Map<String, String> extras, String... alias)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.android())
.setAudience(Audience.alias(alias))
.setNotification(Notification.android(alert, title, extras))
.build();
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendAndroidNotificationWithRegistrationID(String title, String alert,
Map<String, String> extras, String... registrationID)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.android())
.setAudience(Audience.registrationId(registrationID))
.setNotification(Notification.android(alert, title, extras))
.build();
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendIosNotificationWithAlias(String alert, Map<String, String> extras, String... alias)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.alias(alias))
.setNotification(Notification.ios(alert, extras))
.build();
return _pushClient.sendPush(payload);
}
/**
* Send an iOS notification with alias.
* If you want to send alert as a Json object, maybe this method is what you needed.
*
* @param alert The wrapper of APNs alert.
* @param extras The extra params.
* @param alias The alias list.
* @return
* @throws APIConnectionException
* @throws APIRequestException
*/
public PushResult sendIosNotificationWithAlias(IosAlert alert, Map<String, String> extras, String... alias)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.alias(alias))
.setNotification(Notification.ios(alert, extras))
.build();
return _pushClient.sendPush(payload);
}
/**
* Send an iOS notification with alias.
* If you want to send alert as a Json object, maybe this method is what you needed.
*
* @param alert The wrapper of APNs alert.
* @param extras The extra params.
* @param alias The alias list.
* @return
* @throws APIConnectionException
* @throws APIRequestException
*/
public PushResult sendIosNotificationWithAlias(JsonObject alert, Map<String, String> extras, String... alias)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.alias(alias))
.setNotification(Notification.ios(alert, extras))
.build();
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendIosNotificationWithRegistrationID(String alert,
Map<String, String> extras, String... registrationID)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.registrationId(registrationID))
.setNotification(Notification.ios(alert, extras))
.build();
return _pushClient.sendPush(payload);
}
/**
* Send an iOS notification with registrationIds.
* If you want to send alert as a Json object, maybe this method is what you needed.
*
* @param alert The wrapper of APNs alert.
* @param extras The extra params.
* @param registrationID The registration ids.
* @return
* @throws APIConnectionException
* @throws APIRequestException
*/
public PushResult sendIosNotificationWithRegistrationID(IosAlert alert,
Map<String, String> extras, String... registrationID)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.registrationId(registrationID))
.setNotification(Notification.ios(alert, extras))
.build();
return _pushClient.sendPush(payload);
}
/**
* Send an iOS notification with registrationIds.
* If you want to send alert as a Json object, maybe this method is what you needed.
*
* @param alert The wrapper of APNs alert.
* @param extras The extra params.
* @param registrationID The registration ids.
* @return
* @throws APIConnectionException
* @throws APIRequestException
*/
public PushResult sendIosNotificationWithRegistrationID(JsonObject alert,
Map<String, String> extras, String... registrationID)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.registrationId(registrationID))
.setNotification(Notification.ios(alert, extras))
.build();
return _pushClient.sendPush(payload);
}
// ---------------------- shortcuts - message
/**
* Shortcut
*/
public PushResult sendMessageAll(String msgContent) throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.messageAll(msgContent);
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendAndroidMessageWithAlias(String title, String msgContent, String... alias)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.android())
.setAudience(Audience.alias(alias))
.setMessage(Message.newBuilder()
.setTitle(title)
.setMsgContent(msgContent)
.build())
.build();
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendAndroidMessageWithRegistrationID(String title, String msgContent, String... registrationID)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.android())
.setAudience(Audience.registrationId(registrationID))
.setMessage(Message.newBuilder()
.setTitle(title)
.setMsgContent(msgContent)
.build())
.build();
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendIosMessageWithAlias(String title, String msgContent, String... alias)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.alias(alias))
.setMessage(Message.newBuilder()
.setTitle(title)
.setMsgContent(msgContent)
.build())
.build();
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendIosMessageWithRegistrationID(String title, String msgContent, String... registrationID)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.registrationId(registrationID))
.setMessage(Message.newBuilder()
.setTitle(title)
.setMsgContent(msgContent)
.build())
.build();
return _pushClient.sendPush(payload);
}
/**
* Shortcut
*/
public PushResult sendMessageWithRegistrationID(String title, String msgContent, String... registrationID)
throws APIConnectionException, APIRequestException {
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.all())
.setAudience(Audience.registrationId(registrationID))
.setMessage(Message.newBuilder()
.setTitle(title)
.setMsgContent(msgContent)
.build())
.build();
return _pushClient.sendPush(payload);
}
// ----------------------- Device
public TagAliasResult getDeviceTagAlias(String registrationId)
throws APIConnectionException, APIRequestException {
return _deviceClient.getDeviceTagAlias(registrationId);
}
public DefaultResult updateDeviceTagAlias(String registrationId, boolean clearAlias, boolean clearTag)
throws APIConnectionException, APIRequestException {
return _deviceClient.updateDeviceTagAlias(registrationId, clearAlias, clearTag);
}
public DefaultResult updateDeviceTagAlias(String registrationId, String alias,
Set<String> tagsToAdd, Set<String> tagsToRemove)
throws APIConnectionException, APIRequestException {
return _deviceClient.updateDeviceTagAlias(registrationId, alias, tagsToAdd, tagsToRemove);
}
public TagListResult getTagList()
throws APIConnectionException, APIRequestException {
return _deviceClient.getTagList();
}
public BooleanResult isDeviceInTag(String theTag, String registrationID)
throws APIConnectionException, APIRequestException {
return _deviceClient.isDeviceInTag(theTag, registrationID);
}
public DefaultResult addRemoveDevicesFromTag(String theTag,
Set<String> toAddUsers, Set<String> toRemoveUsers)
throws APIConnectionException, APIRequestException {
return _deviceClient.addRemoveDevicesFromTag(theTag, toAddUsers,
toRemoveUsers);
}
public DefaultResult deleteTag(String theTag, String platform)
throws APIConnectionException, APIRequestException {
return _deviceClient.deleteTag(theTag, platform);
}
public AliasDeviceListResult getAliasDeviceList(String alias,
String platform) throws APIConnectionException, APIRequestException {
return _deviceClient.getAliasDeviceList(alias, platform);
}
public DefaultResult deleteAlias(String alias, String platform)
throws APIConnectionException, APIRequestException {
return _deviceClient.deleteAlias(alias, platform);
}
public Map<String, OnlineStatus> getUserOnlineStatus(String... registrationIds)
throws APIConnectionException, APIRequestException
{
return _deviceClient.getUserOnlineStatus(registrationIds);
}
// ----------------------- Schedule
/**
* Create a single schedule.
* @param name The schedule name.
* @param time The push time, format is 'yyyy-MM-dd HH:mm:ss'
* @param push The push payload.
* @return The created scheduleResult instance.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult createSingleSchedule(String name, String time, PushPayload push)
throws APIConnectionException, APIRequestException {
TriggerPayload trigger = TriggerPayload.newBuilder()
.setSingleTime(time)
.buildSingle();
SchedulePayload payload = SchedulePayload.newBuilder()
.setName(name)
.setEnabled(true)
.setTrigger(trigger)
.setPush(push)
.build();
return _scheduleClient.createSchedule(payload);
}
/**
* Create a daily schedule push everyday.
* @param name The schedule name.
* @param start The schedule comes into effect date, format 'yyyy-MM-dd HH:mm:ss'.
* @param end The schedule expiration date, format 'yyyy-MM-dd HH:mm:ss'.
* @param time The push time, format 'HH:mm:ss'
* @param push The push payload.
* @return The created scheduleResult instance.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult createDailySchedule(String name, String start, String end, String time, PushPayload push)
throws APIConnectionException, APIRequestException {
return createPeriodicalSchedule(name, start, end, time, TimeUnit.DAY, 1, null, push);
}
/**
* Create a daily schedule push with a custom frequency.
* @param name The schedule name.
* @param start The schedule comes into effect date, format 'yyyy-MM-dd HH:mm:ss'.
* @param end The schedule expiration date, format 'yyyy-MM-dd HH:mm:ss'.
* @param time The push time, format 'HH:mm:ss'
* @param frequency The custom frequency.
* @param push The push payload.
* @return The created scheduleResult instance.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult createDailySchedule(String name, String start, String end, String time, int frequency, PushPayload push)
throws APIConnectionException, APIRequestException {
return createPeriodicalSchedule(name, start, end, time, TimeUnit.DAY, frequency, null, push);
}
/**
* Create a weekly schedule push every week at the appointed days.
* @param name The schedule name.
* @param start The schedule comes into effect date, format 'yyyy-MM-dd HH:mm:ss'.
* @param end The schedule expiration date, format 'yyyy-MM-dd HH:mm:ss'.
* @param time The push time, format 'HH:mm:ss'
* @param days The appointed days.
* @param push The push payload.
* @return The created scheduleResult instance.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult createWeeklySchedule(String name, String start, String end, String time, Week[] days, PushPayload push)
throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(null != days && days.length > 0, "The days must not be empty.");
String[] points = new String[days.length];
for(int i = 0 ; i < days.length; i++) {
points[i] = days[i].name();
}
return createPeriodicalSchedule(name, start, end, time, TimeUnit.WEEK, 1, points, push);
}
/**
* Create a weekly schedule push with a custom frequency at the appointed days.
* @param name The schedule name.
* @param start The schedule comes into effect date, format 'yyyy-MM-dd HH:mm:ss'.
* @param end The schedule expiration date, format 'yyyy-MM-dd HH:mm:ss'.
* @param time The push time, format 'HH:mm:ss'.
* @param frequency The custom frequency.
* @param days The appointed days.
* @param push The push payload.
* @return The created scheduleResult instance.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult createWeeklySchedule(String name, String start, String end, String time, int frequency, Week[] days, PushPayload push)
throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(null != days && days.length > 0, "The days must not be empty.");
String[] points = new String[days.length];
for(int i = 0 ; i < days.length; i++) {
points[i] = days[i].name();
}
return createPeriodicalSchedule(name, start, end, time, TimeUnit.WEEK, frequency, points, push);
}
/**
* Create a monthly schedule push every month at the appointed days.
* @param name The schedule name.
* @param start The schedule comes into effect date, format 'yyyy-MM-dd HH:mm:ss'.
* @param end The schedule expiration date, format 'yyyy-MM-dd HH:mm:ss'.
* @param time The push time, format 'HH:mm:ss'.
* @param points The appointed days.
* @param push The push payload.
* @return The created scheduleResult instance.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult createMonthlySchedule(String name, String start, String end, String time, String[] points, PushPayload push)
throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(null != points && points.length > 0, "The points must not be empty.");
return createPeriodicalSchedule(name, start, end, time, TimeUnit.MONTH, 1, points, push);
}
/**
* Create a monthly schedule push with a custom frequency at the appointed days.
* @param name The schedule name.
* @param start The schedule comes into effect date, format 'yyyy-MM-dd HH:mm:ss'.
* @param end The schedule expiration date, format 'yyyy-MM-dd HH:mm:ss'.
* @param time The push time, format 'HH:mm:ss'.
* @param frequency The custom frequency.
* @param points The appointed days.
* @param push The push payload.
* @return The created scheduleResult instance.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult createMonthlySchedule(String name, String start, String end, String time, int frequency, String[] points, PushPayload push)
throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(null != points && points.length > 0, "The points must not be empty.");
return createPeriodicalSchedule(name, start, end, time, TimeUnit.MONTH, frequency, points, push);
}
/**
* Get the schedule information by the schedule id.
* @param scheduleId The schedule id.
* @return The schedule information.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult getSchedule(String scheduleId)
throws APIConnectionException, APIRequestException {
return _scheduleClient.getSchedule(scheduleId);
}
/**
* Get the schedule list size and the first page.
* @return The schedule list size and the first page.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleListResult getScheduleList()
throws APIConnectionException, APIRequestException {
return _scheduleClient.getScheduleList(1);
}
/**
* Get the schedule list by the page.
* @param page The page to search.
* @return The schedule list of the appointed page.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleListResult getScheduleList(int page)
throws APIConnectionException, APIRequestException {
return _scheduleClient.getScheduleList(page);
}
/**
* Update the schedule name
* @param scheduleId The schedule id.
* @param name The new name.
* @return The schedule information after updated.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult updateScheduleName(String scheduleId, String name)
throws APIConnectionException, APIRequestException {
SchedulePayload payload = SchedulePayload.newBuilder()
.setName(name)
.build();
return updateSchedule(scheduleId, payload);
}
/**
* Enable the schedule.
* @param scheduleId The schedule id.
* @return The schedule information after updated.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult enableSchedule(String scheduleId)
throws APIConnectionException, APIRequestException {
SchedulePayload payload = SchedulePayload.newBuilder()
.setEnabled(true)
.build();
return updateSchedule(scheduleId, payload);
}
/**
* Disable the schedule.
* @param scheduleId The schedule id.
* @return The schedule information after updated.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult disableSchedule(String scheduleId)
throws APIConnectionException, APIRequestException {
SchedulePayload payload = SchedulePayload.newBuilder()
.setEnabled(false)
.build();
return updateSchedule(scheduleId, payload);
}
/**
* Update the trigger of the schedule.
* @param scheduleId The schedule id.
* @param trigger The new trigger.
* @return The schedule information after updated.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult updateScheduleTrigger(String scheduleId, TriggerPayload trigger)
throws APIConnectionException, APIRequestException {
SchedulePayload payload = SchedulePayload.newBuilder()
.setTrigger(trigger)
.build();
return updateSchedule(scheduleId, payload);
}
/**
* Update the push content of the schedule.
* @param scheduleId The schedule id.
* @param push The new push payload.
* @return The schedule information after updated.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult updateSchedulePush(String scheduleId, PushPayload push)
throws APIConnectionException, APIRequestException {
SchedulePayload payload = SchedulePayload.newBuilder()
.setPush(push)
.build();
return updateSchedule(scheduleId, payload);
}
/**
* Update a schedule by the id.
* @param scheduleId The schedule id to update.
* @param payload The new schedule payload.
* @return The new schedule information.
* @throws APIConnectionException
* @throws APIRequestException
*/
public ScheduleResult updateSchedule(String scheduleId, SchedulePayload payload)
throws APIConnectionException, APIRequestException {
return _scheduleClient.updateSchedule(scheduleId, payload);
}
/**
* Delete a schedule by id.
* @param scheduleId The schedule id.
* @throws APIConnectionException
* @throws APIRequestException
*/
public void deleteSchedule(String scheduleId)
throws APIConnectionException, APIRequestException {
_scheduleClient.deleteSchedule(scheduleId);
}
private ScheduleResult createPeriodicalSchedule(String name, String start, String end, String time,
TimeUnit timeUnit, int frequency, String[] point, PushPayload push)
throws APIConnectionException, APIRequestException {
TriggerPayload trigger = TriggerPayload.newBuilder()
.setPeriodTime(start, end, time)
.setTimeFrequency(timeUnit, frequency, point )
.buildPeriodical();
SchedulePayload payload = SchedulePayload.newBuilder()
.setName(name)
.setEnabled(true)
.setTrigger(trigger)
.setPush(push)
.build();
return _scheduleClient.createSchedule(payload);
}
}
@@ -0,0 +1,14 @@
package com.ifish.jpush.device;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.ifish.jpush.common.resp.BaseResult;
public class TagListResult extends BaseResult {
@Expose public List<String> tags = new ArrayList<String>();
}
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>quartzPro</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,16 @@
package com.ifish.jpush.utils;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Copied from javax.annotation.Nullable
*/
@Documented
//@TypeQualifierNickname
//@Nonnull(when = When.UNKNOWN)
@Retention(RetentionPolicy.RUNTIME)
public @interface Nullable {
}
@@ -0,0 +1,31 @@
package com.ifish.jpush.device;
public class OnlineStatus {
Boolean online;
String last_online_time;
public Boolean getOnline() {
return online;
}
public void setOnline(Boolean online) {
this.online = online;
}
public String getLast_online_time() {
return last_online_time;
}
public void setLast_online_time(String last_online_time) {
this.last_online_time = last_online_time;
}
@Override
public String toString() {
if(null == last_online_time) {
return "status: " + online;
}
return "status: " + online + " , last_online_time: " + last_online_time;
}
}
@@ -0,0 +1,19 @@
package com.ifish.jpush.push.model.audience;
public enum AudienceType {
TAG("tag"),
TAG_AND("tag_and"),
ALIAS("alias"),
SEGMENT("segment"),
REGISTRATION_ID("registration_id");
private final String value;
private AudienceType(final String value) {
this.value = value;
}
public String value() {
return this.value;
}
}
@@ -0,0 +1,40 @@
package com.ifish.jpush.common.resp;
/**
* Should retry for encountering this exception basically.
* Normally it is due to:
* 1. Connect timed out.
* 2. Read timed out.
* 3. Cannot parse domain.
*
* For Push action, if the exception is "Read timed out" you may not want to retry it.
*/
public class APIConnectionException extends Exception {
private static final long serialVersionUID = -2615370590441195647L;
private boolean readTimedout = false;
private int doneRetriedTimes = 0;
public APIConnectionException(String message, Throwable e) {
super(message, e);
}
public APIConnectionException(String message, Throwable e, int doneRetriedTimes) {
super(message, e);
this.doneRetriedTimes = doneRetriedTimes;
}
public APIConnectionException(String message, Throwable e, boolean readTimedout) {
super(message, e);
this.readTimedout = readTimedout;
}
public boolean isReadTimedout() {
return readTimedout;
}
public int getDoneRetriedTimes() {
return this.doneRetriedTimes;
}
}
@@ -0,0 +1,175 @@
package com.ifish.jpush.schedule.model;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.common.TimeUnit;
import com.ifish.jpush.utils.Preconditions;
import com.ifish.jpush.utils.StringUtils;
import com.ifish.jpush.utils.TimeUtils;
public class TriggerPayload implements IModel {
private static Gson gson = new Gson();
private Type type;
private String start;
private String end;
private String time;
private TimeUnit time_unit;
private int frequency;
private String[] point;
private TriggerPayload(String time) {
this.type = Type.single;
this.time = time;
}
private TriggerPayload(String start, String end, String time, TimeUnit time_unit, int frequency, String[] point) {
this.type = Type.periodical;
this.start = start;
this.end = end;
this.time = time;
this.time_unit = time_unit;
this.frequency = frequency;
this.point = point;
}
public static Builder newBuilder() {
return new Builder();
}
@Override
public String toString() {
return gson.toJson(toJSON());
}
@Override
public JsonElement toJSON() {
JsonObject json = new JsonObject();
switch (type) {
case single:
JsonObject s = new JsonObject();
s.addProperty("time", time);
json.add(Type.single.name(), s);
break;
case periodical:
JsonObject p = new JsonObject();
p.addProperty("start", start);
p.addProperty("end", end);
p.addProperty("time", time);
p.addProperty("time_unit", time_unit.name().toLowerCase());
p.addProperty("frequency", frequency);
if( !TimeUnit.DAY.equals(time_unit) ) {
JsonArray array = new JsonArray();
for (String aPoint : point) {
array.add(new JsonPrimitive(aPoint));
}
p.add("point", array);
}
json.add(Type.periodical.name(), p);
break;
default:
// nothing
}
return json;
}
public static enum Type {
single, periodical
}
public static class Builder{
private String start;
private String end;
private String time;
private TimeUnit time_unit;
private int frequency;
private String[] point;
/**
* Setup time for single trigger.
* @param time The execute time, format yyyy-MM-dd HH:mm:ss
* @return this Builder
*/
public Builder setSingleTime(String time) {
this.time = time;
return this;
}
/**
* Setup period for periodical trigger.
* @param start The start time, format yyyy-MM-dd HH:mm:ss
* @param end The end time, format yyyy-MM-dd HH:mm:ss
* @param time The execute time, format HH:mm:ss
* @return this Builder
*/
public Builder setPeriodTime(String start, String end, String time) {
this.start = start;
this.end = end;
this.time = time;
return this;
}
/**
* Setup frequency for periodical trigger.
* @param time_unit The time unit, can be day, week or month.
* @param frequency The frequency cooperate with time unit, must between 1 and 100.
* @param point The time point cooperate with time unit.
* If time unit is day, the point should be null.
* If time unit is week, should be the abbreviation of the days. eg. {"MON", "TUE"}
* If time unit is month, should be the date of the days. eg. {"01", "03"}
* @return this Builder
*/
public Builder setTimeFrequency(TimeUnit time_unit, int frequency, String[] point) {
this.time_unit = time_unit;
this.frequency = frequency;
this.point = point;
return this;
}
public TriggerPayload buildSingle() {
Preconditions.checkArgument(StringUtils.isNotEmpty(time), "The time must not be empty.");
Preconditions.checkArgument(TimeUtils.isDateFormat(time), "The time format is incorrect.");
return new TriggerPayload(time);
}
public TriggerPayload buildPeriodical() {
Preconditions.checkArgument(StringUtils.isNotEmpty(start), "The start must not be empty.");
Preconditions.checkArgument(StringUtils.isNotEmpty(end), "The end must not be empty.");
Preconditions.checkArgument(StringUtils.isNotEmpty(time), "The time must not be empty.");
Preconditions.checkArgument(TimeUtils.isDateFormat(start), "The start format is incorrect.");
Preconditions.checkArgument(TimeUtils.isDateFormat(end), "The end format is incorrect.");
Preconditions.checkArgument(TimeUtils.isTimeFormat(time), "The time format is incorrect.");
Preconditions.checkNotNull(time_unit, "The time_unit must not be null.");
Preconditions.checkArgument(isTimeUnitOk(time_unit), "The time unit must be DAY, WEEK or MONTH.");
Preconditions.checkArgument(frequency > 0 && frequency < 101, "The frequency must be a int between 1 and 100.");
return new TriggerPayload(start, end, time, time_unit, frequency, point);
}
private boolean isTimeUnitOk(TimeUnit timeUnit) {
switch (timeUnit) {
case HOUR:
return false;
case DAY:
case WEEK:
case MONTH:
return true;
default:
return false;
}
}
}
}
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"
default-lazy-init="true">
<!-- 启动触发器的配置开始 -->
<bean name="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="myJobTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
</props>
</property>
</bean>
<!-- 启动触发器的配置结束 -->
<!-- quartz-2.x的配置 -->
<bean id="myJobTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="myJobDetail" />
</property>
<property name="cronExpression">
<!--每天10点开始推送 -->
<value>0 0 10 * * ?</value>
</property>
</bean>
<!-- 调度的配置结束 -->
<!-- job的配置开始 -->
<bean id="myJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="myJob" />
</property>
<property name="targetMethod">
<value>pushRemind</value>
</property>
</bean>
<!-- job的配置结束 -->
<!-- 工作的bean -->
<bean id="myJob" class=" com.ifish.job.job" />
<!-- 注册识别注解 -->
<context:annotation-config />
<!-- 导入外部的properties文件-->
<context:property-placeholder location="classpath*:jPpush.properties" ignore-unresolvable="true"/>
<!-- 极光推送 -->
<bean id="jPushNotification2" class="com.ifish.jpush.JPushNotification">
<constructor-arg index="0">
<!-- appKey -->
<value>${jpush.ios.appKey}</value>
</constructor-arg>
<constructor-arg index="1">
<!-- secret -->
<value>${jpush.ios.secret}</value>
</constructor-arg>
<constructor-arg index="2">
<!-- production -->
<value>${jpush.ios.productionMode}</value>
</constructor-arg>
</bean>
<!-- 云信 -->
<bean id="neteaseIM" class="com.ifish.netease.NeteaseIM">
<constructor-arg index="0">
<!-- appKey -->
<value>${netease.appKey}</value>
</constructor-arg>
<constructor-arg index="1">
<!-- appSecret -->
<value>${netease.appSecret}</value>
</constructor-arg>
</bean>
</beans>
@@ -0,0 +1,168 @@
package com.ifish.jpush.push;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.ifish.jpush.common.ClientConfig;
import com.ifish.jpush.common.ServiceHelper;
import com.ifish.jpush.common.connection.HttpProxy;
import com.ifish.jpush.common.connection.IHttpClient;
import com.ifish.jpush.common.connection.NativeHttpClient;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.common.resp.BaseResult;
import com.ifish.jpush.common.resp.ResponseWrapper;
import com.ifish.jpush.push.model.PushPayload;
import com.ifish.jpush.utils.Preconditions;
import com.ifish.jpush.utils.StringUtils;
/**
* Entrance for sending Push.
*
* For the following parameters, you can set them by instance creation.
* This action will override setting in PushPayload Optional.
* * apnsProduction If not present, the default is true.
* * timeToLive If not present, the default is 86400(s) (one day).
*
* Can be used directly.
*/
public class PushClient {
private final NativeHttpClient _httpClient;
private String _baseUrl;
private String _pushPath;
private String _pushValidatePath;
private JsonParser _jsonParser = new JsonParser();
// If not present, true by default.
private boolean _apnsProduction = true;
// If not present, the default value is 86400(s) (one day)
private long _timeToLive = 60 * 60 * 24;
private boolean _globalSettingEnabled = false;
/**
* Create a Push Client.
*
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
*/
public PushClient(String masterSecret, String appKey) {
this(masterSecret, appKey, IHttpClient.DEFAULT_MAX_RETRY_TIMES);
}
public PushClient(String masterSecret, String appKey, int maxRetryTimes) {
this(masterSecret, appKey, maxRetryTimes, null);
}
/**
* Create a Push Client with max retry times.
*
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
* @param maxRetryTimes max retry times
*/
public PushClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy) {
this(masterSecret, appKey, maxRetryTimes, proxy, ClientConfig.getInstance());
}
public PushClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy, ClientConfig conf) {
ServiceHelper.checkBasic(appKey, masterSecret);
this._baseUrl = (String) conf.get(ClientConfig.PUSH_HOST_NAME);
this._pushPath = (String) conf.get(ClientConfig.PUSH_PATH);
this._pushValidatePath = (String) conf.get(ClientConfig.PUSH_VALIDATE_PATH);
String authCode = ServiceHelper.getBasicAuthorization(appKey, masterSecret);
this._httpClient = new NativeHttpClient(authCode, maxRetryTimes, proxy);
}
/**
* Create a Push Client with global settings.
*
* If you want different settings from default globally, this constructor is what you needed.
*
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
* @param apnsProduction Global APNs environment setting. It will override PushPayload Options.
* @param timeToLive Global time_to_live setting. It will override PushPayload Options.
*/
public PushClient(String masterSecret, String appKey, boolean apnsProduction, long timeToLive) {
this(masterSecret, appKey);
this._apnsProduction = apnsProduction;
this._timeToLive = timeToLive;
this._globalSettingEnabled = true;
}
public void setDefaults(boolean apnsProduction, long timeToLive) {
this._apnsProduction = apnsProduction;
this._timeToLive = timeToLive;
this._globalSettingEnabled = true;
}
public void setBaseUrl(String baseUrl) {
this._baseUrl = baseUrl;
}
public PushResult sendPush(PushPayload pushPayload) throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(! (null == pushPayload), "pushPayload should not be null");
if (_globalSettingEnabled) {
pushPayload.resetOptionsTimeToLive(_timeToLive);
pushPayload.resetOptionsApnsProduction(_apnsProduction);
}
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushPath, pushPayload.toString());
return BaseResult.fromResponse(response, PushResult.class);
}
public PushResult sendPushValidate(PushPayload pushPayload) throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(! (null == pushPayload), "pushPayload should not be null");
if (_globalSettingEnabled) {
pushPayload.resetOptionsTimeToLive(_timeToLive);
pushPayload.resetOptionsApnsProduction(_apnsProduction);
}
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushValidatePath, pushPayload.toString());
return BaseResult.fromResponse(response, PushResult.class);
}
public PushResult sendPush(String payloadString) throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(StringUtils.isNotEmpty(payloadString), "pushPayload should not be empty");
try {
_jsonParser.parse(payloadString);
} catch (JsonParseException e) {
Preconditions.checkArgument(false, "payloadString should be a valid JSON string.");
}
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushPath, payloadString);
return BaseResult.fromResponse(response, PushResult.class);
}
public PushResult sendPushValidate(String payloadString) throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(StringUtils.isNotEmpty(payloadString), "pushPayload should not be empty");
try {
_jsonParser.parse(payloadString);
} catch (JsonParseException e) {
Preconditions.checkArgument(false, "payloadString should be a valid JSON string.");
}
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushValidatePath, payloadString);
return BaseResult.fromResponse(response, PushResult.class);
}
}
@@ -0,0 +1,191 @@
package com.ifish.jpush.examples;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ifish.jpush.JPushClient;
import com.ifish.jpush.common.TimeUnit;
import com.ifish.jpush.common.Week;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.push.model.PushPayload;
import com.ifish.jpush.schedule.ScheduleListResult;
import com.ifish.jpush.schedule.ScheduleResult;
import com.ifish.jpush.schedule.model.SchedulePayload;
import com.ifish.jpush.schedule.model.TriggerPayload;
public class ScheduleExample {
protected static final Logger LOG = LoggerFactory.getLogger(ScheduleExample.class);
private static final String appKey ="e5c0d34f58732cf09b2d4d74";
private static final String masterSecret = "4cdda6d3c8b029941dbc5cb3";
public static void main(String[] args) {
// testDeleteSchedule();
testGetScheduleList();
// testUpdateSchedule();
testGetSchedule();
}
public static void testCreateSingleSchedule() {
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
String name = "test_schedule_example";
String time = "2016-07-30 12:30:25";
PushPayload push = PushPayload.alertAll("test schedule example.");
try {
ScheduleResult result = jpushClient.createSingleSchedule(name, time, push);
LOG.info("schedule result is " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testCreateDailySchedule() {
JPushClient jPushClient = new JPushClient(masterSecret, appKey);
String name = "test_daily_schedule";
String start = "2015-08-06 12:16:13";
String end = "2115-08-06 12:16:13";
String time = "14:00:00";
PushPayload push = PushPayload.alertAll("test daily example.");
try {
ScheduleResult result = jPushClient.createDailySchedule(name, start, end, time, push);
LOG.info("schedule result is " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testCreateWeeklySchedule() {
JPushClient jPushClient = new JPushClient(masterSecret, appKey);
String name = "test_weekly_schedule";
String start = "2015-08-06 12:16:13";
String end = "2115-08-06 12:16:13";
String time = "14:00:00";
Week[] days = {Week.MON, Week.FRI};
PushPayload push = PushPayload.alertAll("test weekly example.");
try {
ScheduleResult result = jPushClient.createWeeklySchedule(name, start, end, time, days, push);
LOG.info("schedule result is " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testCreateMonthlySchedule() {
JPushClient jPushClient = new JPushClient(masterSecret, appKey);
String name = "test_monthly_schedule";
String start = "2015-08-06 12:16:13";
String end = "2115-08-06 12:16:13";
String time = "14:00:00";
String[] points = {"01", "02"};
PushPayload push = PushPayload.alertAll("test monthly example.");
try {
ScheduleResult result = jPushClient.createMonthlySchedule(name, start, end, time, points, push);
LOG.info("schedule result is " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later.", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testDeleteSchedule() {
String scheduleId = "95bbd066-3a88-11e5-8e62-0021f652c102";
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
try {
jpushClient.deleteSchedule(scheduleId);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testGetScheduleList() {
int page = 1;
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
try {
ScheduleListResult list = jpushClient.getScheduleList(page);
LOG.info("total " + list.getTotal_count());
for(ScheduleResult s : list.getSchedules()) {
LOG.info(s.toString());
}
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testUpdateSchedule() {
String scheduleId = "95bbd066-3a88-11e5-8e62-0021f652c102";
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
String[] points = {Week.MON.name(), Week.FRI.name()};
TriggerPayload trigger = TriggerPayload.newBuilder()
.setPeriodTime("2015-08-01 12:10:00", "2015-08-30 12:12:12", "15:00:00")
.setTimeFrequency(TimeUnit.WEEK, 2, points)
.buildPeriodical();
SchedulePayload payload = SchedulePayload.newBuilder()
.setName("test_update_schedule")
.setEnabled(false)
.setTrigger(trigger)
.build();
try {
jpushClient.updateSchedule(scheduleId, payload);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testGetSchedule() {
String scheduleId = "95bbd066-3a88-11e5-8e62-0021f652c102";
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
try {
ScheduleResult result = jpushClient.getSchedule(scheduleId);
LOG.info("schedule " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
}
@@ -0,0 +1,12 @@
#appKey
jpush.android.appKey=d970d5e193cb2a0bbe41653c
#secret
jpush.android.secret=60162c8cf195ce9f4dc76629
#production
jpush.android.productionMode=true
#appKey
jpush.ios.appKey=d147124018074eb970474e48
#secret
jpush.ios.secret=a7d41825e75082b13675c326
#production
jpush.ios.productionMode=true
@@ -0,0 +1,97 @@
package com.ifish.jpush.schedule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ifish.jpush.common.ClientConfig;
import com.ifish.jpush.common.ServiceHelper;
import com.ifish.jpush.common.connection.HttpProxy;
import com.ifish.jpush.common.connection.IHttpClient;
import com.ifish.jpush.common.connection.NativeHttpClient;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.common.resp.ResponseWrapper;
import com.ifish.jpush.schedule.model.SchedulePayload;
import com.ifish.jpush.utils.Preconditions;
import com.ifish.jpush.utils.StringUtils;
public class ScheduleClient {
private static final Logger LOG = LoggerFactory.getLogger(ScheduleClient.class);
private final NativeHttpClient _httpClient;
private String hostName;
private String schedulePath;
public ScheduleClient(String masterSecret, String appkey) {
this(masterSecret, appkey, IHttpClient.DEFAULT_MAX_RETRY_TIMES, null, ClientConfig.getInstance());
}
public ScheduleClient(String masterSecret, String appKey, int maxRetryTimes) {
this(masterSecret, appKey, maxRetryTimes, null, ClientConfig.getInstance());
}
public ScheduleClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy) {
this(masterSecret, appKey, maxRetryTimes, proxy, ClientConfig.getInstance());
}
/**
* Create a Schedule Client with custom configuration.
* @param masterSecret API access secret of the appKey.
* @param appKey The KEY of one application on JPush.
* @param maxRetryTimes Max retry times
* @param proxy The proxy, if there is no proxy, should be null.
* @param conf The client configuration. Can use ClientConfig.getInstance() as default.
*/
public ScheduleClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy, ClientConfig conf) {
ServiceHelper.checkBasic(appKey, masterSecret);
hostName = (String) conf.get(ClientConfig.SCHEDULE_HOST_NAME);
schedulePath = (String) conf.get(ClientConfig.SCHEDULE_PATH);
String authCode = ServiceHelper.getBasicAuthorization(appKey, masterSecret);
this._httpClient = new NativeHttpClient(authCode, maxRetryTimes, proxy);
}
public ScheduleResult createSchedule(SchedulePayload payload) throws APIConnectionException, APIRequestException {
Preconditions.checkArgument(null != payload, "payload should not be null");
ResponseWrapper response = _httpClient.sendPost(hostName + schedulePath, payload.toString());
return ScheduleResult.fromResponse(response, ScheduleResult.class);
}
public ScheduleListResult getScheduleList(int page) throws APIConnectionException, APIRequestException{
Preconditions.checkArgument(page > 0, "page should more than 0.");
ResponseWrapper response = _httpClient.sendGet(hostName + schedulePath + "?page=" + page);
return ScheduleListResult.fromResponse(response, ScheduleListResult.class);
}
public ScheduleResult getSchedule(String scheduleId) throws APIConnectionException, APIRequestException{
Preconditions.checkArgument(StringUtils.isNotEmpty(scheduleId), "scheduleId should not be empty");
ResponseWrapper response = _httpClient.sendGet(hostName + schedulePath + "/" + scheduleId);
return ScheduleResult.fromResponse(response, ScheduleResult.class);
}
public ScheduleResult updateSchedule(String scheduleId, SchedulePayload payload) throws APIConnectionException, APIRequestException{
Preconditions.checkArgument(StringUtils.isNotEmpty(scheduleId), "scheduleId should not be empty");
Preconditions.checkArgument(null != payload, "payload should not be null");
ResponseWrapper response = _httpClient.sendPut(hostName + schedulePath + "/" + scheduleId,
payload.toString());
return ScheduleResult.fromResponse(response, ScheduleResult.class);
}
public void deleteSchedule(String scheduleId) throws APIConnectionException, APIRequestException{
Preconditions.checkArgument(StringUtils.isNotEmpty(scheduleId), "scheduleId should not be empty");
_httpClient.sendDelete(hostName + schedulePath + "/" + scheduleId);
}
}
@@ -0,0 +1 @@
Window
@@ -0,0 +1,131 @@
package com.ifish.jpush.push.model.notification;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.push.model.PushModel;
import com.ifish.jpush.utils.StringUtils;
public class IosAlert implements PushModel {
private final String title;
private final String body;
private final String title_loc_key;
private final String[] title_loc_args;
private final String action_loc_key;
private final String loc_key;
private final String[] loc_args;
private final String launch_image;
private IosAlert(String title, String body, String title_loc_key, String[] title_loc_args,
String action_loc_key, String loc_key, String[] loc_args, String launch_image) {
this.title = title;
this.body = body;
this.title_loc_key = title_loc_key;
this.title_loc_args = title_loc_args;
this.action_loc_key = action_loc_key;
this.loc_key = loc_key;
this.loc_args = loc_args;
this.launch_image = launch_image;
}
public static Builder newBuilder() {
return new Builder();
}
@Override
public JsonElement toJSON() {
JsonObject json = new JsonObject();
if( StringUtils.isNotEmpty(title) ) {
json.addProperty("title", title);
}
if( StringUtils.isNotEmpty(body) ) {
json.addProperty("body", body);
}
if( StringUtils.isNotEmpty(title_loc_key) ) {
json.addProperty("title-loc-key", title_loc_key);
if( null != title_loc_args && title_loc_args.length > 0 ) {
JsonArray args = new JsonArray();
for(int i = 0; i < title_loc_args.length; i++) {
args.add(new JsonPrimitive(title_loc_args[i]));
}
json.add("title-loc-args", args);
}
}
if( StringUtils.isNotEmpty(action_loc_key) ) {
json.addProperty("action-loc-key", action_loc_key);
}
if( StringUtils.isNotEmpty(loc_key) ) {
json.addProperty("loc-key", loc_key);
if( null != loc_args && loc_args.length > 0 ) {
JsonArray args = new JsonArray();
for(int i = 0; i < loc_args.length; i++) {
args.add(new JsonPrimitive(loc_args[i]));
}
json.add("loc-args", args);
}
}
if( StringUtils.isNotEmpty(launch_image) ) {
json.addProperty("launch-image", launch_image);
}
return json;
}
@Override
public String toString() {
return gson.toJson(toJSON());
}
public static class Builder {
private String title;
private String body;
private String title_loc_key;
private String[] title_loc_args;
private String action_loc_key;
private String loc_key;
private String[] loc_args;
private String launch_image;
public Builder setTitleAndBody(String title, String body){
this.title = title;
this.body = body;
return this;
}
public Builder setTitleLoc(String title_loc_key, String... title_loc_args) {
this.title_loc_key = title_loc_key;
this.title_loc_args = title_loc_args;
return this;
}
public Builder setActionLocKey(String action_loc_key) {
this.action_loc_key = action_loc_key;
return this;
}
public Builder setLoc(String loc_key, String... loc_args) {
this.loc_key = loc_key;
this.loc_args = loc_args;
return this;
}
public Builder setLaunchImage(String launch_image) {
this.launch_image = launch_image;
return this;
}
public IosAlert build() {
return new IosAlert(title, body, title_loc_key, title_loc_args, action_loc_key,
loc_key, loc_args, launch_image);
}
}
}
@@ -0,0 +1,120 @@
package com.ifish.jpush.utils;
import java.io.CharArrayWriter;
import java.io.IOException;
public class Base64 {
static final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();
public static char[] encode(byte[] content) {
CharArrayWriter cw = new CharArrayWriter(4 * content.length / 3);
int idx = 0;
int x = 0;
for (int i = 0; i < content.length; ++i) {
if (idx == 0)
x = (content[i] & 0xFF) << 16;
else if (idx == 1)
x |= (content[i] & 0xFF) << 8;
else {
x |= content[i] & 0xFF;
}
if (++idx == 3) {
cw.write(alphabet[(x >> 18)]);
cw.write(alphabet[(x >> 12 & 0x3F)]);
cw.write(alphabet[(x >> 6 & 0x3F)]);
cw.write(alphabet[(x & 0x3F)]);
idx = 0;
}
}
if (idx == 1) {
cw.write(alphabet[(x >> 18)]);
cw.write(alphabet[(x >> 12 & 0x3F)]);
cw.write(61);
cw.write(61);
}
if (idx == 2) {
cw.write(alphabet[(x >> 18)]);
cw.write(alphabet[(x >> 12 & 0x3F)]);
cw.write(alphabet[(x >> 6 & 0x3F)]);
cw.write(61);
}
return cw.toCharArray();
}
public static byte[] decode(char[] message) throws IOException {
byte[] buff = new byte[4];
byte[] dest = new byte[message.length];
int bpos = 0;
int destpos = 0;
for (int i = 0; i < message.length; ++i) {
int c = message[i];
if ((c != 10) && (c != 13) && (c != 32)) {
if (c == 9)
continue;
if ((c >= 65) && (c <= 90)) {
buff[(bpos++)] = (byte) (c - 65);
} else if ((c >= 97) && (c <= 122)) {
buff[(bpos++)] = (byte) (c - 97 + 26);
} else if ((c >= 48) && (c <= 57)) {
buff[(bpos++)] = (byte) (c - 48 + 52);
} else if (c == 43) {
buff[(bpos++)] = 62;
} else if (c == 47) {
buff[(bpos++)] = 63;
} else if (c == 61) {
buff[(bpos++)] = 64;
} else {
throw new IOException("Illegal char in base64 code.");
}
if (bpos == 4) {
bpos = 0;
if (buff[0] == 64)
break;
if (buff[1] == 64)
throw new IOException("Unexpected '=' in base64 code.");
int v;
if (buff[2] == 64) {
v = (buff[0] & 0x3F) << 6 | buff[1] & 0x3F;
dest[(destpos++)] = (byte) (v >> 4);
break;
}
if (buff[3] == 64) {
v = (buff[0] & 0x3F) << 12 | (buff[1] & 0x3F) << 6
| buff[2] & 0x3F;
dest[(destpos++)] = (byte) (v >> 10);
dest[(destpos++)] = (byte) (v >> 2);
break;
}
v = (buff[0] & 0x3F) << 18 | (buff[1] & 0x3F) << 12
| (buff[2] & 0x3F) << 6 | buff[3] & 0x3F;
dest[(destpos++)] = (byte) (v >> 16);
dest[(destpos++)] = (byte) (v >> 8);
dest[(destpos++)] = (byte) v;
}
}
}
byte[] res = new byte[destpos];
System.arraycopy(dest, 0, res, 0, destpos);
return res;
}
}
@@ -0,0 +1,14 @@
package com.ifish.jpush.device;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.ifish.jpush.common.resp.BaseResult;
public class AliasDeviceListResult extends BaseResult {
@Expose public List<String> registration_ids = new ArrayList<String>();
}
@@ -0,0 +1,199 @@
package com.ifish.jpush.push.model.notification;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.push.model.PushModel;
import com.ifish.jpush.utils.Preconditions;
public abstract class PlatformNotification implements PushModel {
public static final String ALERT = "alert";
private static final String EXTRAS = "extras";
protected static final Logger LOG = LoggerFactory.getLogger(PlatformNotification.class);
private Object alert;
private final Map<String, String> extras;
private final Map<String, Number> numberExtras;
private final Map<String, Boolean> booleanExtras;
private final Map<String, JsonObject> jsonExtras;
public PlatformNotification(Object alert, Map<String, String> extras,
Map<String, Number> numberExtras,
Map<String, Boolean> booleanExtras,
Map<String, JsonObject> jsonExtras) {
this.alert = alert;
this.extras = extras;
this.numberExtras = numberExtras;
this.booleanExtras = booleanExtras;
this.jsonExtras = jsonExtras;
}
@Override
public JsonElement toJSON() {
JsonObject json = new JsonObject();
if (null != alert) {
if ( alert instanceof JsonObject) {
json.add(ALERT, (JsonObject) alert);
} else if (alert instanceof IosAlert) {
json.add(ALERT, ((IosAlert) alert).toJSON());
} else {
json.add(ALERT, new JsonPrimitive(alert.toString()));
}
}
JsonObject extrasObject = null;
if (null != extras || null != numberExtras || null != booleanExtras || null != jsonExtras) {
extrasObject = new JsonObject();
}
if (null != extras) {
String value = null;
for (String key : extras.keySet()) {
value = extras.get(key);
if (null != value) {
extrasObject.add(key, new JsonPrimitive(value));
}
}
}
if (null != numberExtras) {
Number value = null;
for (String key : numberExtras.keySet()) {
value = numberExtras.get(key);
if (null != value) {
extrasObject.add(key, new JsonPrimitive(value));
}
}
}
if (null != booleanExtras) {
Boolean value = null;
for (String key : booleanExtras.keySet()) {
value = booleanExtras.get(key);
if (null != value) {
extrasObject.add(key, new JsonPrimitive(value));
}
}
}
if (null != jsonExtras) {
JsonObject value = null;
for (String key : jsonExtras.keySet()) {
value = jsonExtras.get(key);
if (null != value) {
extrasObject.add(key, value);
}
}
}
if (null != extras || null != numberExtras || null != booleanExtras || null != jsonExtras) {
json.add(EXTRAS, extrasObject);
}
return json;
}
protected Object getAlert() {
return this.alert;
}
protected void setAlert(Object alert) {
this.alert = alert;
}
protected abstract String getPlatform();
protected abstract static class Builder<T extends PlatformNotification, B extends Builder<T, B>> {
private B theBuilder;
protected Object alert;
protected Map<String, String> extrasBuilder;
protected Map<String, Number> numberExtrasBuilder;
protected Map<String, Boolean> booleanExtrasBuilder;
protected Map<String, JsonObject> jsonExtrasBuilder;
public Builder () {
theBuilder = getThis();
}
protected abstract B getThis();
public abstract B setAlert(Object alert);
public B addExtra(String key, String value) {
Preconditions.checkArgument(! (null == key), "Key should not be null.");
if (null == value) {
LOG.debug("Extra value is null, throw away it.");
return theBuilder;
}
if (null == extrasBuilder) {
extrasBuilder = new HashMap<String, String>();
}
extrasBuilder.put(key, value);
return theBuilder;
}
public B addExtras(Map<String, String> extras) {
if (null == extras) {
LOG.warn("Null extras param. Throw away it.");
return theBuilder;
}
if (null == extrasBuilder) {
extrasBuilder = new HashMap<String, String>();
}
for (String key : extras.keySet()) {
extrasBuilder.put(key, extras.get(key));
}
return theBuilder;
}
public B addExtra(String key, Number value) {
Preconditions.checkArgument(! (null == key), "Key should not be null.");
if (null == value) {
LOG.debug("Extra value is null, throw away it.");
return theBuilder;
}
if (null == numberExtrasBuilder) {
numberExtrasBuilder = new HashMap<String, Number>();
}
numberExtrasBuilder.put(key, value);
return theBuilder;
}
public B addExtra(String key, Boolean value) {
Preconditions.checkArgument(! (null == key), "Key should not be null.");
if (null == value) {
LOG.debug("Extra value is null, throw away it.");
return theBuilder;
}
if (null == booleanExtrasBuilder) {
booleanExtrasBuilder = new HashMap<String, Boolean>();
}
booleanExtrasBuilder.put(key, value);
return theBuilder;
}
public B addExtra(String key, JsonObject value) {
Preconditions.checkArgument(! (null == key), "Key should not be null.");
if (null == value) {
LOG.debug("Extra value is null, throw away it.");
return theBuilder;
}
if (null == jsonExtrasBuilder) {
jsonExtrasBuilder = new HashMap<String, JsonObject>();
}
jsonExtrasBuilder.put(key, value);
return theBuilder;
}
public abstract T build();
}
}
@@ -0,0 +1,12 @@
package com.ifish.jpush.push;
import com.google.gson.annotations.Expose;
import com.ifish.jpush.common.resp.BaseResult;
public class PushResult extends BaseResult {
@Expose public long msg_id;
@Expose public int sendno;
}
@@ -0,0 +1,184 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>quartzPro</groupId>
<artifactId>quartzPro</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>quartzPro</name>
<url>http://mvnrepository.com</url>
<dependencies>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-annotations</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
<finalName>quartzPro</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.5.4</version>
<extensions>true</extensions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.hbm.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
<properties>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
</properties>
</project>
@@ -0,0 +1,11 @@
<%@ page language="java" pageEncoding="utf-8"%>
<html>
<head>
<title>首页</title>
<meta http-equiv="cache-control" content="max-age=10">
</head>
<body style="text-align: center">
<h4>访问正常</h4>
</body>
</html>
@@ -0,0 +1,172 @@
package com.ifish.job;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import com.ifish.enums.PhoneTypeEnum;
import com.ifish.jpush.JPushNotification;
import com.ifish.netease.NeteaseIM;
import com.ifish.util.IfishUtil;
public class job{
@Autowired
private NeteaseIM neteaseIM;
@Autowired
private JPushNotification jPushNotification;
@Autowired
private JPushNotification jPushNotification2;
private Connection connection = null;
private Statement stmt = null;
private PreparedStatement prest = null;
/**
* 查询需要推送的用户并且推送完修改为下一次提醒日期
*/
public void pushRemind(){
System.out.println(new Date()+"开始任务");
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myfishdb?characterEncoding=UTF-8", "ifish", "ifish7pwd");
stmt = connection.createStatement();
prest = connection.prepareStatement("update tbl_tmp_push_remind set is_push=? where user_id=? and device_id=?");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//结果集
ResultSet result = null;
try {
//推送提醒数
int rowCount = 0;
//按分页来获取数据
int pageNo = 0;
//云信限制每次最多500条
int pageSize = 500;
//查询总共需要推送的用户数
String countSql = "select count(1) as countRow from tbl_tmp_push_remind where is_push='0'";
result = stmt.executeQuery(countSql);
if(result.next()){
rowCount=result.getInt("countRow");
pageNo = (rowCount+pageSize-1)/pageSize;
}
System.out.println(pageNo);
for (int i = 0; i < pageNo; i++) {
result = stmt.executeQuery("select device_id,user_id,show_name,login_type from tbl_tmp_push_remind where is_push='0' limit 0,"+pageSize);
//推送的用户
List<String> androidUser = new ArrayList<String>();
List<String> iosUser = new ArrayList<String>();
List<String> ids = new ArrayList<String>();
//更新提醒过的用户
while(result.next()){
Integer deviceId= result.getInt("device_id");
Integer userId = result.getInt("user_id");
String loginType = result.getString("login_type");
prest.setString(1, "1");
prest.setInt(2, userId);
prest.setInt(3, deviceId);
prest.addBatch();
//云信
ids.add(userId.toString());
//极光
if(loginType.toLowerCase().equals(PhoneTypeEnum.android.getKey())){
androidUser.add(userId.toString());
}
else if(loginType.toLowerCase().equals(PhoneTypeEnum.ios.getKey())){
iosUser.add(userId.toString());
}
}
//发送云信消息
if(ids.size()>0){
neteaseIM.sendBatchMsg("ifish", JSONArray.fromObject(ids).toString(), "【换水提醒】您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置");
}
//极光推送
Integer iosSize = iosUser.size();
Integer androidSize = androidUser.size();
if(iosSize>0){
push(PhoneTypeEnum.ios,iosUser.toArray(new String[iosSize]));
}
if(androidSize>0){
push(PhoneTypeEnum.android,androidUser.toArray(new String[androidSize]));
}
//批量提交
prest.executeBatch();
//云信一分钟访问不超过120次
Thread.sleep(600);
}
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(result!=null){
try {
result.close();
result = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
stmt = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(prest!=null){
try {
prest.close();
prest = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
connection = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* 推送提醒
* @param type
* @param ids
*/
public void push(PhoneTypeEnum type,String[] ids){
try {
Map<String,String> map = new HashMap<String, String>();
map.put("timestamp", IfishUtil.format2(new Date()));
//推送android
if(type.equals(PhoneTypeEnum.android)){
System.out.println(new Date()+"android推送"+ids.length+"个");
jPushNotification.sendAndroidNotification(ids, "换水提醒", "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置", map);
}
//推送IOS
else if(type.equals(PhoneTypeEnum.ios)){
System.out.println(new Date()+"ios推送"+ids.length+"个");
jPushNotification2.sendIosNotification(ids, "换水提醒", "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置", map);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,87 @@
package com.ifish.jpush.push.model.notification;
import java.util.Map;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
public class AndroidNotification extends PlatformNotification {
public static final String NOTIFICATION_ANDROID = "android";
private static final String TITLE = "title";
private static final String BUILDER_ID = "builder_id";
private final String title;
private final int builderId;
private AndroidNotification(Object alert, String title, int builderId,
Map<String, String> extras,
Map<String, Number> numberExtras,
Map<String, Boolean> booleanExtras,
Map<String, JsonObject> jsonExtras) {
super(alert, extras, numberExtras, booleanExtras, jsonExtras);
this.title = title;
this.builderId = builderId;
}
public static Builder newBuilder() {
return new Builder();
}
public static AndroidNotification alert(String alert) {
return newBuilder().setAlert(alert).build();
}
@Override
public String getPlatform() {
return NOTIFICATION_ANDROID;
}
@Override
public JsonElement toJSON() {
JsonObject json = super.toJSON().getAsJsonObject();
if (builderId > 0) {
json.add(BUILDER_ID, new JsonPrimitive(this.builderId));
}
if (null != title) {
json.add(TITLE, new JsonPrimitive(title));
}
return json;
}
public static class Builder extends PlatformNotification.Builder<AndroidNotification, Builder> {
private String title;
private int builderId;
protected Builder getThis() {
return this;
}
public Builder setTitle(String title) {
this.title = title;
return this;
}
public Builder setBuilderId(int builderId) {
this.builderId = builderId;
return this;
}
public Builder setAlert(Object alert) {
this.alert = alert;
return this;
}
public AndroidNotification build() {
return new AndroidNotification(alert, title, builderId,
extrasBuilder, numberExtrasBuilder, booleanExtrasBuilder, jsonExtrasBuilder);
}
}
}
@@ -0,0 +1,182 @@
package com.ifish.job;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import com.ifish.enums.PhoneTypeEnum;
import com.ifish.jpush.JPushNotification;
import com.ifish.netease.NeteaseIM;
import com.ifish.util.IfishUtil;
public class job{
@Autowired
private NeteaseIM neteaseIM;
@Autowired
private JPushNotification jPushNotification;
@Autowired
private JPushNotification jPushNotification2;
private Connection connection = null;
private Statement stmt = null;
private PreparedStatement prest = null;
/**
* 查询需要推送的用户并且推送完修改为下一次提醒日期
*/
public void pushRemind(){
System.out.println(new Date()+"开始任务");
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myfishdb?characterEncoding=UTF-8", "ifish", "ifish7pwd");
stmt = connection.createStatement();
prest = connection.prepareStatement("update tbl_tmp_push_remind set is_push=? where user_id=? and device_id=?");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//结果集
ResultSet result = null;
try {
//推送提醒数
int rowCount = 0;
//按分页来获取数据
int pageNo = 0;
//云信限制每次最多500条
int pageSize = 500;
//查询总共需要推送的用户数
String countSql = "select count(1) as countRow from tbl_tmp_push_remind where is_push='0'";
result = stmt.executeQuery(countSql);
if(result.next()){
rowCount=result.getInt("countRow");
pageNo = (rowCount+pageSize-1)/pageSize;
}
System.out.println(pageNo);
for (int i = 0; i < pageNo; i++) {
result = stmt.executeQuery("select device_id,user_id,show_name,login_type from tbl_tmp_push_remind where is_push='0' limit 0,"+pageSize);
//推送的用户
List<String> androidUser = new ArrayList<String>();
List<String> iosUser = new ArrayList<String>();
List<String> ids = new ArrayList<String>();
//是否云信
boolean bln = true;
//更新提醒过的用户
while(result.next()){
Integer deviceId= result.getInt("device_id");
Integer userId = result.getInt("user_id");
String loginType = result.getString("login_type");
prest.setString(1, "1");
prest.setInt(2, userId);
prest.setInt(3, deviceId);
prest.addBatch();
//云信
if(bln){
ids.add(userId.toString());
}
else{
//极光推送
if(loginType.toLowerCase().equals(PhoneTypeEnum.android.getKey())){
androidUser.add(userId.toString());
}
else if(loginType.toLowerCase().equals(PhoneTypeEnum.ios.getKey())){
iosUser.add(userId.toString());
}
}
}
//云信
if(bln){
if(ids.size()>0){
neteaseIM.sendBatchMsg("ifish", JSONArray.fromObject(ids).toString(), "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置");
}
}
else{
//极光推送
Integer iosSize = iosUser.size();
Integer androidSize = androidUser.size();
if(iosSize>0){
push(PhoneTypeEnum.ios,iosUser.toArray(new String[iosSize]));
}
if(androidSize>0){
push(PhoneTypeEnum.android,androidUser.toArray(new String[androidSize]));
}
}
//批量提交
prest.executeBatch();
//云信一分钟访问不超过120次
Thread.sleep(600);
}
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(result!=null){
try {
result.close();
result = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
stmt = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(prest!=null){
try {
prest.close();
prest = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
connection = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* 推送提醒
* @param type
* @param ids
*/
public void push(PhoneTypeEnum type,String[] ids){
try {
Map<String,String> map = new HashMap<String, String>();
map.put("timestamp", IfishUtil.format2(new Date()));
//推送android
if(type.equals(PhoneTypeEnum.android)){
System.out.println(new Date()+"android推送"+ids.length+"个");
jPushNotification.sendAndroidNotification(ids, "换水提醒", "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置", map);
}
//推送IOS
else if(type.equals(PhoneTypeEnum.ios)){
System.out.println(new Date()+"ios推送"+ids.length+"个");
jPushNotification2.sendIosNotification(ids, "换水提醒", "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置", map);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,80 @@
package com.ifish.jpush.examples;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ifish.jpush.JPushClient;
import com.ifish.jpush.common.TimeUnit;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.report.MessagesResult;
import com.ifish.jpush.report.ReceivedsResult;
import com.ifish.jpush.report.UsersResult;
public class ReportsExample {
protected static final Logger LOG = LoggerFactory.getLogger(ReportsExample.class);
// demo App defined in resources/jpush-api.conf
private static final String appKey = "dd1066407b044738b6479275";
private static final String masterSecret = "2b38ce69b1de2a7fa95706ea";
public static void main(String[] args) {
testGetReport();
testGetMessages();
testGetUsers();
}
public static void testGetReport() {
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
try {
ReceivedsResult result = jpushClient.getReportReceiveds("1942377665");
LOG.debug("Got result - " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testGetUsers() {
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
try {
UsersResult result = jpushClient.getReportUsers(TimeUnit.DAY, "2014-06-10", 3);
LOG.debug("Got result - " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testGetMessages() {
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
try {
MessagesResult result = jpushClient.getReportMessages("269978303");
LOG.debug("Got result - " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
}
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v7.0"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
@@ -0,0 +1,187 @@
package com.ifish.jpush.push.model.notification;
import java.util.Map;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.common.ServiceHelper;
/**
* APNs 通知类
* <p>
* 支持 APNs 默认的几个参数:
* <li>alert: 继承自父类 PlatformNotification 的 alert 属性;本类设置则覆盖。</li>
* <li>badge: 支持 setBadge(int) 方法来设置;支持 incrBadge(int) 方法来增加。</li>
* <li>sound: 支持 setSound(string) 方法来设置声音文件。</li>
* <li>content-available: 用来支持后台推送。如果该值赋值为 1,表示开启后台推送。</li>
* <li>extras: JSON object. 支持更多的自定义字段信息。</li>
* </p>
* <p>
* 需要特别留意的是,JPush SDK 会对以下几个值有特别的默认设置考虑:
* <li>badge: 默认为 "+1"。如果需要取消 badge 值,需要显式地调用 disableBadge().</li>
* <li>sound: 默认为 "",即默认的声音提示。如果需要取消 sound 值,即不要声音,需要显式地调用 disableSound(). </li>
* </p>
*/
public class IosNotification extends PlatformNotification {
public static final String NOTIFICATION_IOS = "ios";
private static final String DEFAULT_SOUND = "";
private static final String DEFAULT_BADGE = "+1";
private static final String BADGE = "badge";
private static final String SOUND = "sound";
private static final String CONTENT_AVAILABLE = "content-available";
private static final String CATEGORY = "category";
private static final String ALERT_VALID_BADGE = "Badge number should be 0~99999, "
+ "and can be prefixed with + to add, - to minus";
private final boolean soundDisabled;
private final boolean badgeDisabled;
private final String sound;
private final String badge;
private final boolean contentAvailable;
private final String category;
private IosNotification(Object alert, String sound, String badge,
boolean contentAvailable, boolean soundDisabled, boolean badgeDisabled,
String category,
Map<String, String> extras,
Map<String, Number> numberExtras,
Map<String, Boolean> booleanExtras,
Map<String, JsonObject> jsonExtras) {
super(alert, extras, numberExtras, booleanExtras, jsonExtras);
this.sound = sound;
this.badge = badge;
this.contentAvailable = contentAvailable;
this.soundDisabled = soundDisabled;
this.badgeDisabled = badgeDisabled;
this.category = category;
}
public static Builder newBuilder() {
return new Builder();
}
public static IosNotification alert(String alert) {
return newBuilder().setAlert(alert).build();
}
@Override
public String getPlatform() {
return NOTIFICATION_IOS;
}
@Override
public JsonElement toJSON() {
JsonObject json = super.toJSON().getAsJsonObject();
if (!badgeDisabled) {
if (null != badge) {
json.add(BADGE, new JsonPrimitive(this.badge));
} else {
json.add(BADGE, new JsonPrimitive(DEFAULT_BADGE));
}
}
if (!soundDisabled) {
if (null != sound) {
json.add(SOUND, new JsonPrimitive(sound));
} else {
json.add(SOUND, new JsonPrimitive(DEFAULT_SOUND));
}
}
if (contentAvailable) {
json.add(CONTENT_AVAILABLE, new JsonPrimitive(1));
}
if (null != category) {
json.add(CATEGORY, new JsonPrimitive(category));
}
return json;
}
public static class Builder extends PlatformNotification.Builder<IosNotification, Builder> {
private String sound;
private String badge;
private boolean contentAvailable = false;
private boolean soundDisabled = false;
private boolean badgeDisabled = false;
private String category;
protected Builder getThis() {
return this;
}
public Builder setSound(String sound) {
this.sound = sound;
return this;
}
public Builder disableSound() {
this.soundDisabled = true;
return this;
}
public Builder incrBadge(int badge) {
if (!ServiceHelper.isValidIntBadge(Math.abs(badge))) {
LOG.warn(ALERT_VALID_BADGE);
return this;
}
if (badge >= 0) {
this.badge = "+" + badge;
} else {
this.badge = "" + badge;
}
return this;
}
public Builder setBadge(int badge) {
if (!ServiceHelper.isValidIntBadge(badge)) {
LOG.warn(ALERT_VALID_BADGE);
return this;
}
this.badge = "" + badge;
return this;
}
/**
* equals to: +1
*/
public Builder autoBadge() {
return incrBadge(1);
}
public Builder disableBadge() {
this.badgeDisabled = true;
return this;
}
public Builder setContentAvailable(boolean contentAvailable) {
this.contentAvailable = contentAvailable;
return this;
}
public Builder setCategory(String category) {
this.category = category;
return this;
}
public Builder setAlert(Object alert) {
this.alert = alert;
return this;
}
public IosNotification build() {
return new IosNotification(alert, sound, badge, contentAvailable,
soundDisabled, badgeDisabled, category,
extrasBuilder, numberExtrasBuilder, booleanExtrasBuilder, jsonExtrasBuilder);
}
}
}
@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"
default-lazy-init="true">
<!-- 启动触发器的配置开始 -->
<bean name="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="myJobTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
</props>
</property>
</bean>
<!-- 启动触发器的配置结束 -->
<!-- quartz-2.x的配置 -->
<bean id="myJobTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="myJobDetail" />
</property>
<property name="cronExpression">
<!--每天10点开始推送 -->
<value>0 0 10 * * ?</value>
</property>
</bean>
<!-- 调度的配置结束 -->
<!-- job的配置开始 -->
<bean id="myJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="myJob" />
</property>
<property name="targetMethod">
<value>pushRemind</value>
</property>
</bean>
<!-- job的配置结束 -->
<!-- 工作的bean -->
<bean id="myJob" class=" com.ifish.job.job" />
<!-- 注册识别注解 -->
<context:annotation-config />
<!-- 导入外部的properties文件-->
<context:property-placeholder location="classpath*:jPpush.properties" ignore-unresolvable="true"/>
<!-- 极光推送 -->
<bean id="jPushNotification" class="com.ifish.jpush.JPushNotification">
<constructor-arg index="0">
<!-- appKey -->
<value>${jpush.android.appKey}</value>
</constructor-arg>
<constructor-arg index="1">
<!-- secret -->
<value>${jpush.android.secret}</value>
</constructor-arg>
<constructor-arg index="2">
<!-- production -->
<value>${jpush.android.productionMode}</value>
</constructor-arg>
</bean>
<!-- 极光推送 -->
<bean id="jPushNotification2" class="com.ifish.jpush.JPushNotification">
<constructor-arg index="0">
<!-- appKey -->
<value>${jpush.ios.appKey}</value>
</constructor-arg>
<constructor-arg index="1">
<!-- secret -->
<value>${jpush.ios.secret}</value>
</constructor-arg>
<constructor-arg index="2">
<!-- production -->
<value>${jpush.ios.productionMode}</value>
</constructor-arg>
</bean>
<!-- 云信 -->
<bean id="neteaseIM" class="com.ifish.netease.NeteaseIM">
<constructor-arg index="0">
<!-- appKey -->
<value>${netease.appKey}</value>
</constructor-arg>
<constructor-arg index="1">
<!-- appSecret -->
<value>${netease.appSecret}</value>
</constructor-arg>
</bean>
</beans>
@@ -0,0 +1,56 @@
package com.ifish.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
public class IfishUtil {
private static final String formatDate1 ="yyyy-MM-dd";
private static final String formatDate2 ="yyyy-MM-dd HH:mm:ss";
/**
* 格式化日期yyyy-MM-dd HH:mm:ss
* @param date
* @return
*/
public static String format2(Date date){
SimpleDateFormat format = new SimpleDateFormat(formatDate2);
return format.format(date);
}
/**
* 格式化日期yyyy-MM-dd
* @param date
* @return
*/
public static String format1(Date date){
SimpleDateFormat format = new SimpleDateFormat(formatDate1);
return format.format(date);
}
/**
* 随机生成字母与数字组合
* @param length
* @return
*/
public static String getCharAndNumr(int length) {
String val = "";
Random random = new Random();
for (int i = 0; i < length; i++) {
// 输出字母还是数字
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
// 字符串
if ("char".equalsIgnoreCase(charOrNum)) {
// 取得大写字母还是小写字母
int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
val += (char) (choice + random.nextInt(26));
// 数字
} else if ("num".equalsIgnoreCase(charOrNum)) {
val += String.valueOf(random.nextInt(10));
}
}
return val;
}
}
@@ -0,0 +1,48 @@
package com.ifish.netease;
import java.security.MessageDigest;
/**
* SHA1(AppSecret + Nonce + CurTime),三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写)
* @author Administrator
*
*/
public class CheckSumBuilder {
// 计算并获取CheckSum
public static String getCheckSum(String appSecret, String nonce, String curTime) {
return encode("sha1", appSecret + nonce + curTime);
}
// 计算并获取md5值
public static String getMD5(String requestBody) {
return encode("md5", requestBody);
}
private static String encode(String algorithm, String value) {
if (value == null) {
return null;
}
try {
MessageDigest messageDigest
= MessageDigest.getInstance(algorithm);
messageDigest.update(value.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
}
@@ -0,0 +1,117 @@
package com.ifish.jpush.common;
import java.util.HashMap;
import java.util.Map;
public class ClientConfig extends HashMap<String, Object> {
private static ClientConfig instance = new ClientConfig();
public static final String DEVICE_HOST_NAME = "device.host.name";
public static final Object DEVICE_HOST_NAME_SCHEMA = String.class;
public static final String DEVICES_PATH = "devices.path";
public static final Object DEVICES_PATH_SCHEMA = String.class;
public static final String TAGS_PATH = "tags.path";
public static final Object TAGS_PATH_SCHEMA = String.class;
public static final String ALIASES_PATH = "aliases.path";
public static final Object ALIASES_PATH_SCHEMA = String.class;
public static final String PUSH_HOST_NAME = "push.host.name";
public static final Object PUSH_HOST_NAME_SCHEMA = String.class;
public static final String PUSH_PATH = "push.path";
public static final Object PUSH_PATH_SCHEMA = String.class;
public static final String PUSH_VALIDATE_PATH = "push.validate.path";
public static final Object PUSH_VALIDATE_PATH_SCHMEA = String.class;
public static final String REPORT_HOST_NAME = "report.host.name";
public static final Object REPORT_HOST_NAME_SCHEMA = String.class;
public static final String REPORT_RECEIVE_PATH = "report.receive.path";
public static final Object REPORT_RECEIVE_PATH_SCHEMA = String.class;
public static final String REPORT_USER_PATH = "report.user.path";
public static final Object REPORT_USER_PATH_SCHEMA = String.class;
public static final String REPORT_MESSAGE_PATH = "report.message.path";
public static final Object REPORT_MESSAGE_PATH_SCHEMA = String.class;
public static final String SCHEDULE_HOST_NAME = "schedule.host.name";
public static final Object SCHEDULE_HOST_NAME_SCHEMA = String.class;
public static final String SCHEDULE_PATH = "schedule.path";
public static final Object SCHEDULE_PATH_SCHEMA = String.class;
private ClientConfig() {
super(12);
this.put(DEVICE_HOST_NAME, "https://device.jpush.cn");
this.put(DEVICES_PATH, "/v3/devices");
this.put(TAGS_PATH, "/v3/tags");
this.put(ALIASES_PATH, "/v3/aliases");
this.put(PUSH_HOST_NAME, "https://api.jpush.cn");
this.put(PUSH_PATH, "/v3/push");
this.put(PUSH_VALIDATE_PATH, "/v3/push/validate");
this.put(REPORT_HOST_NAME, "https://report.jpush.cn");
this.put(REPORT_RECEIVE_PATH, "/v3/received");
this.put(REPORT_USER_PATH, "/v3/users");
this.put(REPORT_MESSAGE_PATH, "/v3/messages");
this.put(SCHEDULE_HOST_NAME, "https://api.jpush.cn");
this.put(SCHEDULE_PATH, "/v3/schedules");
}
public static ClientConfig getInstance() {
return instance;
}
public static void setDeviceHostName(Map conf, String hostName) {
conf.put(DEVICE_HOST_NAME, hostName);
}
/**
* Setup custom device api host name, if using the JPush privacy cloud.
* @param hostName the custom api host name, default is JPush domain name
*/
public void setDeviceHostName(String hostName) {
setDeviceHostName(this, hostName);
}
public static void setPushHostName(Map conf, String hostName) {
conf.put(PUSH_HOST_NAME, hostName);
}
/**
* Setup custom push api host name, if using the JPush privacy cloud.
* @param hostName the custom api host name, default is JPush domain name
*/
public void setPushHostName(String hostName) {
setPushHostName(this, hostName);
}
public static void setReportHostName(Map conf, String hostName) {
conf.put(REPORT_HOST_NAME, hostName);
}
/**
* Setup custom report api host name, if using the JPush privacy cloud.
* @param hostName the custom api host name, default is JPush domain name
*/
public void setReportHostName(String hostName) {
setReportHostName(this, hostName);
}
public static void setScheduleHostName(Map conf, String hostName) {
conf.put(SCHEDULE_HOST_NAME, hostName);
}
public void setScheduleHostName(String hostName) {
setScheduleHostName(this, hostName);
}
}
@@ -0,0 +1,244 @@
package com.ifish.netease;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ifish.enums.NeteaseEnum;
import com.ifish.util.IfishUtil;
public class NeteaseIM {
String appKey = "";
String appSecret = "";
private static Logger log = LoggerFactory.getLogger(NeteaseIM.class);
public NeteaseIM(String appKey,String appSecret){
this.appKey=appKey;
this.appSecret=appSecret;
}
/**
* 创建云信ID
* @param accid 云信ID,最大长度32字符,必须保证一个APP内唯一
* @param name 云信ID昵称,最大长度64字符,用来PUSH推送 时显示的昵称
* @param icon 云信ID头像URL,第三方可选填,最大长度1024
* @param props json属性,第三方可选填,最大长度1024字符
* @return
* @throws Exception
*/
public Map<String, String> createAccid(String accid,String name,String icon,String props){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/user/create.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("accid", accid));
nvps.add(new BasicNameValuePair("name", name));
nvps.add(new BasicNameValuePair("icon", icon));
nvps.add(new BasicNameValuePair("props", props));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
//200
if(code.equals(NeteaseEnum.status200.getKey())){
JSONObject infoJson = json.getJSONObject("info");
String token = infoJson.getString("token");
map.put("token", token);
}
else if(code.equals(NeteaseEnum.status414.getKey())){
String desc = json.getString("desc");
}
return map;
} catch (Exception e) {
log.error("CreateAccid error message:{},{}",accid,e.toString());
}
return null;
}
/**
* 更新并获取新token
* @param accid
* @return
* @throws Exception
*/
public Map<String, String> refreshToken(String accid){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/user/refreshToken.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("accid", accid));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
//200
if(code.equals(NeteaseEnum.status200.getKey())){
JSONObject infoJson = json.getJSONObject("info");
String token = infoJson.getString("token");
map.put("token", token);
}
else if(code.equals(NeteaseEnum.status414.getKey())){
String desc = json.getString("desc");
}
return map;
} catch (Exception e) {
log.error("refreshToken error message:{},{}",accid,e.toString());
}
return null;
}
/**
* 发送普通消息
* @param from
* @param to
* @param msg
* @return
*/
public Map<String, String> sendMsg(String from,String to,String msg){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/msg/sendMsg.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("from", from));
nvps.add(new BasicNameValuePair("to", to));
nvps.add(new BasicNameValuePair("ope", "0"));
nvps.add(new BasicNameValuePair("type", "0"));
nvps.add(new BasicNameValuePair("body", "{\"msg\":\""+msg+"\"}"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
//200
if(code.equals(NeteaseEnum.status200.getKey())){
}
else if(code.equals(NeteaseEnum.status414.getKey())){
String desc = json.getString("desc");
}
return map;
} catch (Exception e) {
log.error("refreshToken error message:{}",e.toString());
}
return null;
}
/**
* 批量发送点对点普通消息
* @param fromAccid
* @param toAccids
* @param msg
* @return
*/
public Map<String, String> sendBatchMsg(String fromAccid,String toAccids,String msg){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/msg/sendBatchMsg.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("fromAccid", fromAccid));
nvps.add(new BasicNameValuePair("toAccids", toAccids));
nvps.add(new BasicNameValuePair("type", "0"));
nvps.add(new BasicNameValuePair("body", "{\"msg\":\""+msg+"\"}"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
//200
if(code.equals(NeteaseEnum.status200.getKey())){
}
else if(code.equals(NeteaseEnum.status414.getKey())){
String desc = json.getString("desc");
}
return map;
} catch (Exception e) {
log.error("refreshToken error message:{}",e.toString());
}
return null;
}
public static void main(String[] args) {
List<String> list= new ArrayList<String>();
list.add("hello");
list.add("hello1");
new NeteaseIM("87b0e3315dfc2df08060bcb54246da68", "e62f6c247b46").createAccid("ifish", "爱鱼奇", "", "");
}
}
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry kind="src" path="target/m2e-wtp/web-resources"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>
@@ -0,0 +1,50 @@
package com.ifish.jpush.report;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.reflect.TypeToken;
import com.ifish.jpush.common.resp.BaseResult;
import com.ifish.jpush.common.resp.ResponseWrapper;
public class MessagesResult extends BaseResult {
private static final Type MESSAGE_TYPE = new TypeToken<List<Message>>(){}.getType();
@Expose public List<Message> messages = new ArrayList<Message>();
public static class Message {
@Expose public long msg_id;
@Expose public Android android;
@Expose public Ios ios;
}
public static class Android {
@Expose public int received;
@Expose public int target;
@Expose public int online_push;
@Expose public int click;
@Expose public int msg_click;
}
public static class Ios {
@Expose public int apns_sent;
@Expose public int apns_target;
@Expose public int click;
@Expose public int target;
@Expose public int received;
@Expose public int msg_click;
}
static MessagesResult fromResponse(ResponseWrapper responseWrapper) {
MessagesResult result = new MessagesResult();
if (responseWrapper.isServerResponse()) {
result.messages = _gson.fromJson(responseWrapper.responseContent, MESSAGE_TYPE);
}
result.setResponseWrapper(responseWrapper);
return result;
}
}
@@ -0,0 +1,171 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>quartzPro</groupId>
<artifactId>quartzPro</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>quartzPro</name>
<url>http://mvnrepository.com</url>
<dependencies>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-annotations</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
<finalName>quartzPro</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.5.4</version>
<extensions>true</extensions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.hbm.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
<properties>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
</properties>
</project>
@@ -0,0 +1,44 @@
package com.ifish.jpush;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.push.PushResult;
public class JPushNotification {
protected final Logger LOG = LoggerFactory.getLogger(JPushNotification.class);
JPushClient jpushClient = null;
public JPushNotification(String appKey,String masterSecret,boolean productionModel){
jpushClient = new JPushClient(masterSecret, appKey , productionModel ,86400);
}
public void sendIosNotification(String[] alias,String title,String body,Map<String,String> extras) {
try {
JsonObject json = new JsonObject();
json.addProperty("title", title);
json.addProperty("body", body);
PushResult result = jpushClient.sendIosNotificationWithAlias(json, extras, alias);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error Message: " + e.getMessage());
}
}
public void sendAndroidNotification(String[] alias,String title,String alert,Map<String,String> map) {
try {
PushResult result = jpushClient.sendAndroidNotificationWithAlias(title ,alert, map, alias);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error Message: " + e.getMessage());
}
}
}
@@ -0,0 +1,44 @@
package com.ifish.jpush;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.push.PushResult;
public class JPushNotification {
protected final Logger LOG = LoggerFactory.getLogger(JPushNotification.class);
JPushClient jpushClient = null;
public JPushNotification(String appKey,String masterSecret,boolean productionModel){
jpushClient = new JPushClient(masterSecret, appKey , productionModel ,86400);
}
public void sendIosNotification(String[] alias,String title,String body,Map<String,String> extras) {
try {
JsonObject json = new JsonObject();
json.addProperty("title", title);
json.addProperty("body", body);
PushResult result = jpushClient.sendIosNotificationWithAlias(json, extras, alias);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error Message: " + e.getMessage());
}
}
/*public void sendAndroidNotification(String[] alias,String title,String alert,Map<String,String> map) {
try {
PushResult result = jpushClient.sendAndroidNotificationWithAlias(title ,alert, map, alias);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error Message: " + e.getMessage());
}
}*/
}
@@ -0,0 +1,109 @@
package com.ifish.jpush.common.resp;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ResponseWrapper {
private static final Logger LOG = LoggerFactory.getLogger(ResponseWrapper.class);
private static final int RESPONSE_CODE_NONE = -1;
private static Gson _gson = new Gson();
private static JsonParser jsonParser = new JsonParser();
public int responseCode = RESPONSE_CODE_NONE;
public String responseContent;
public ErrorObject error; // error for non-200 response, used by new API
public int rateLimitQuota;
public int rateLimitRemaining;
public int rateLimitReset;
public void setRateLimit(String quota, String remaining, String reset) {
if (null == quota) return;
try {
rateLimitQuota = Integer.parseInt(quota);
rateLimitRemaining = Integer.parseInt(remaining);
rateLimitReset = Integer.parseInt(reset);
LOG.debug("JPush API Rate Limiting params - quota:" + quota + ", remaining:" + remaining + ", reset:" + reset);
} catch (NumberFormatException e) {
LOG.debug("Unexpected - parse rate limiting headers error.");
}
}
public void setErrorObject() {
error = new ErrorObject();
error.error = new ErrorEntity();
try {
JsonElement element = jsonParser.parse(responseContent);
JsonObject errorObj = null;
if( element instanceof JsonArray) {
JsonArray array = (JsonArray) element;
for(int i = 0; i < array.size(); i++) {
if(array.get(i).getAsJsonObject().has("error")) {
errorObj = array.get(i).getAsJsonObject();
break;
}
}
} else if(element instanceof JsonObject) {
errorObj = (JsonObject) element;
} else {
// nothing
}
if(null != errorObj) {
JsonObject errorMsg = errorObj;
if(errorObj.has("msg_id")) {
error.msg_id = errorObj.get("msg_id").getAsLong();
}
if (errorObj.has("error")) {
errorMsg = (JsonObject) errorObj.get("error");
}
if(errorMsg.has("code")) {
error.error.code = errorMsg.get("code").getAsInt();
}
if(errorMsg.has("message")) {
error.error.message = errorMsg.get("message").getAsString();
}
}
} catch(JsonSyntaxException e) {
LOG.error("Unexpected - responseContent:" + responseContent, e);
} catch (Exception e) {
LOG.error("Unexpected - responseContent:" + responseContent, e);
}
}
public boolean isServerResponse() {
if (responseCode / 100 == 2) return true;
if (responseCode > 0 && null != error && error.error.code > 0) return true;
return false;
}
@Override
public String toString() {
return _gson.toJson(this);
}
public static class ErrorObject {
public long msg_id;
public ErrorEntity error;
}
public static class ErrorEntity {
public int code;
public String message;
@Override
public String toString() {
return _gson.toJson(this);
}
}
}
@@ -0,0 +1,93 @@
package com.ifish.jpush.common;
import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonArray;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.utils.Base64;
import com.ifish.jpush.utils.StringUtils;
public class ServiceHelper {
private static final Logger LOG = LoggerFactory.getLogger(ServiceHelper.class);
private final static Pattern PUSH_PATTERNS = Pattern.compile("[^a-zA-Z0-9]");
private final static String BASIC_PREFIX = "Basic";
private static final Random RANDOM = new Random(System.currentTimeMillis());
private static final int MIN = 100000;
private static final int MAX = Integer.MAX_VALUE;
private static final int MAX_BADGE_NUMBER = 99999;
private static final Pattern USERNAME_PATTERN = Pattern.compile("^[a-zA-Z0-9][a-zA-Z_0-9.、。@,-]*");
private static final Pattern DATE_PATTERN = Pattern.compile("[0-9]{4}-[0-9]{2}-[0-9]{2}");
private static final String DATE_FORMAT = "yyyy-MM-dd";
public static boolean isValidIntBadge(int intBadge) {
if (intBadge >= 0 && intBadge <= MAX_BADGE_NUMBER) {
return true;
}
return false;
}
public static int generateSendno() {
return RANDOM.nextInt((MAX - MIN) + 1) + MIN;
}
public static String getBasicAuthorization(String username, String password) {
String encodeKey = username + ":" + password;
return BASIC_PREFIX + " " + String.valueOf(Base64.encode(encodeKey.getBytes()));
}
public static void checkBasic(String appKey, String masterSecret) {
if (StringUtils.isEmpty(appKey)
|| StringUtils.isEmpty(masterSecret)) {
throw new IllegalArgumentException("appKey and masterSecret are both required.");
}
if (appKey.length() != 24
|| masterSecret.length() != 24
|| PUSH_PATTERNS.matcher(appKey).find()
|| PUSH_PATTERNS.matcher(masterSecret).find()) {
throw new IllegalArgumentException("appKey and masterSecret format is incorrect. "
+ "They should be 24 size, and be composed with alphabet and numbers. "
+ "Please confirm that they are coming from JPush Web Portal.");
}
}
public static JsonArray fromSet(Set<String> sets) {
JsonArray array = new JsonArray();
if (null != sets && sets.size() > 0) {
for (String item : sets) {
array.add(new JsonPrimitive(item));
}
}
return array;
}
public static boolean checkUsername(String username) {
return USERNAME_PATTERN.matcher(username).matches();
}
public static boolean isValidBirthday( String birthday) {
try {
if( ! DATE_PATTERN.matcher(birthday).matches() ) {
return false;
}
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
format.setLenient(false);
format.parse(birthday);
} catch (Exception e) {
LOG.error("incorrect date format. " + birthday, e);
return false;
}
return true;
}
}
@@ -0,0 +1,33 @@
package com.ifish.enums;
public enum PushTypeEnum {
remove_device("remove_device","解除设备"),
wendu_warn("wendu_warn","温度报警"),
qu_reply("qu_reply","问题反馈"),
app_update("app_update","IOS更新推送"),
remind_water("remind_water","换水提醒"),
offline_push("offline_push","设备离线推送");
private PushTypeEnum(String key,String value){
this.key = key;
this.value = value;
}
private String key;
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,73 @@
package com.ifish.jpush.common.resp;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ifish.jpush.common.resp.ResponseWrapper.ErrorObject;
public class APIRequestException extends Exception implements IRateLimiting {
private static final long serialVersionUID = -3921022835186996212L;
protected static Gson _gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
private final ResponseWrapper responseWrapper;
public APIRequestException(ResponseWrapper responseWrapper) {
super(responseWrapper.responseContent);
this.responseWrapper = responseWrapper;
}
public int getStatus() {
return this.responseWrapper.responseCode;
}
public long getMsgId() {
ErrorObject eo = getErrorObject();
if (null != eo) {
return eo.msg_id;
}
return 0;
}
public int getErrorCode() {
ErrorObject eo = getErrorObject();
if (null != eo && null != eo.error) {
return eo.error.code;
}
return -1;
}
public String getErrorMessage() {
ErrorObject eo = getErrorObject();
if (null != eo && null != eo.error) {
return eo.error.message;
}
return null;
}
@Override
public String toString() {
return _gson.toJson(this);
}
private ErrorObject getErrorObject() {
return this.responseWrapper.error;
}
@Override
public int getRateLimitQuota() {
return responseWrapper.rateLimitQuota;
}
@Override
public int getRateLimitRemaining() {
return responseWrapper.rateLimitRemaining;
}
@Override
public int getRateLimitReset() {
return responseWrapper.rateLimitReset;
}
}
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"
default-lazy-init="true">
<!-- 启动触发器的配置开始 -->
<bean name="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="myJobTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
</props>
</property>
</bean>
<!-- 启动触发器的配置结束 -->
<!-- quartz-2.x的配置 -->
<bean id="myJobTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="myJobDetail" />
</property>
<property name="cronExpression">
<!--每天8点开始推送 -->
<value>0 0 10 * * ?</value>
</property>
</bean>
<!-- 调度的配置结束 -->
<!-- job的配置开始 -->
<bean id="myJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="myJob" />
</property>
<property name="targetMethod">
<value>pushRemind</value>
</property>
</bean>
<!-- job的配置结束 -->
<!-- 工作的bean -->
<bean id="myJob" class=" com.ifish.job.job" />
<!-- 注册识别注解 -->
<context:annotation-config />
<!-- 导入外部的properties文件-->
<context:property-placeholder location="classpath*:jPpush.properties" ignore-unresolvable="true"/>
<!-- 极光推送 -->
<bean id="jPushNotification" class="com.ifish.jpush.JPushNotification">
<constructor-arg index="0">
<!-- appKey -->
<value>${jpush.android.appKey}</value>
</constructor-arg>
<constructor-arg index="1">
<!-- secret -->
<value>${jpush.android.secret}</value>
</constructor-arg>
<constructor-arg index="2">
<!-- production -->
<value>${jpush.android.productionMode}</value>
</constructor-arg>
</bean>
<!-- 极光推送 -->
<bean id="jPushNotification2" class="com.ifish.jpush.JPushNotification">
<constructor-arg index="0">
<!-- appKey -->
<value>${jpush.ios.appKey}</value>
</constructor-arg>
<constructor-arg index="1">
<!-- secret -->
<value>${jpush.ios.secret}</value>
</constructor-arg>
<constructor-arg index="2">
<!-- production -->
<value>${jpush.ios.productionMode}</value>
</constructor-arg>
</bean>
</beans>
@@ -0,0 +1,83 @@
package com.ifish.jpush.schedule.model;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.ifish.jpush.push.model.PushPayload;
import com.ifish.jpush.utils.StringUtils;
public class SchedulePayload implements IModel {
private static Gson gson = new Gson();
private String name;
private Boolean enabled;
private TriggerPayload trigger;
private PushPayload push;
private SchedulePayload(String name, Boolean enabled, TriggerPayload trigger, PushPayload push) {
this.name = name;
this.enabled = enabled;
this.trigger = trigger;
this.push = push;
}
public static Builder newBuilder() {
return new Builder();
}
@Override
public JsonElement toJSON() {
JsonObject json = new JsonObject();
if ( StringUtils.isNotEmpty(name) ) {
json.addProperty("name", name);
}
if ( null != enabled ) {
json.addProperty("enabled", enabled);
}
if ( null != trigger ) {
json.add("trigger", trigger.toJSON());
}
if ( null != push ) {
json.add("push", push.toJSON());
}
return json;
}
@Override
public String toString() {
return gson.toJson(toJSON());
}
public static class Builder{
private String name;
private Boolean enabled;
private TriggerPayload trigger;
private PushPayload push;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setEnabled(Boolean enabled) {
this.enabled = enabled;
return this;
}
public Builder setTrigger(TriggerPayload trigger) {
this.trigger = trigger;
return this;
}
public Builder setPush(PushPayload push) {
this.push = push;
return this;
}
public SchedulePayload build() {
return new SchedulePayload(name, enabled, trigger, push);
}
}
}
@@ -0,0 +1,439 @@
/*
* Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.ifish.jpush.utils;
/**
* Copied from Google Guava.
*
* Static convenience methods that help a method or constructor check whether it was invoked
* correctly (whether its <i>preconditions</i> have been met). These methods generally accept a
* {@code boolean} expression which is expected to be {@code true} (or in the case of {@code
* checkNotNull}, an object reference which is expected to be non-null). When {@code false} (or
* {@code null}) is passed instead, the {@code Preconditions} method throws an unchecked exception,
* which helps the calling method communicate to <i>its</i> caller that <i>that</i> caller has made
* a mistake. Example: <pre> {@code
*
* /**
* * Returns the positive square root of the given value.
* *
* * @throws IllegalArgumentException if the value is negative
* *}{@code /
* public static double sqrt(double value) {
* Preconditions.checkArgument(value >= 0.0, "negative value: %s", value);
* // calculate the square root
* }
*
* void exampleBadCaller() {
* double d = sqrt(-1.0);
* }}</pre>
*
* In this example, {@code checkArgument} throws an {@code IllegalArgumentException} to indicate
* that {@code exampleBadCaller} made an error in <i>its</i> call to {@code sqrt}.
*
* <h3>Warning about performance</h3>
*
* <p>The goal of this class is to improve readability of code, but in some circumstances this may
* come at a significant performance cost. Remember that parameter values for message construction
* must all be computed eagerly, and autoboxing and varargs array creation may happen as well, even
* when the precondition check then succeeds (as it should almost always do in production). In some
* circumstances these wasted CPU cycles and allocations can add up to a real problem.
* Performance-sensitive precondition checks can always be converted to the customary form:
* <pre> {@code
*
* if (value < 0.0) {
* throw new IllegalArgumentException("negative value: " + value);
* }}</pre>
*
* <h3>Other types of preconditions</h3>
*
* <p>Not every type of precondition failure is supported by these methods. Continue to throw
* standard JDK exceptions such as {@link java.util.NoSuchElementException} or {@link
* UnsupportedOperationException} in the situations they are intended for.
*
* <h3>Non-preconditions</h3>
*
* <p>It is of course possible to use the methods of this class to check for invalid conditions
* which are <i>not the caller's fault</i>. Doing so is <b>not recommended</b> because it is
* misleading to future readers of the code and of stack traces. See
* <a href="http://code.google.com/p/guava-libraries/wiki/ConditionalFailuresExplained">Conditional
* failures explained</a> in the Guava User Guide for more advice.
*
* <h3>{@code java.util.Objects.requireNonNull()}</h3>
*
* <p>Projects which use {@code com.google.common} should generally avoid the use of {@link
* java.util.Objects#requireNonNull(Object)}. Instead, use whichever of {@link
* #checkNotNull(Object)} or {@link Verify#verifyNotNull(Object)} is appropriate to the situation.
* (The same goes for the message-accepting overloads.)
*
* <h3>Only {@code %s} is supported</h3>
*
* <p>In {@code Preconditions} error message template strings, only the {@code "%s"} specifier is
* supported, not the full range of {@link java.util.Formatter} specifiers. However, note that if
* the number of arguments does not match the number of occurrences of {@code "%s"} in the format
* string, {@code Preconditions} will still behave as expected, and will still include all argument
* values in the error message; the message will simply not be formatted exactly as intended.
*
* <h3>More information</h3>
*
* <p>See the Guava User Guide on
* <a href="http://code.google.com/p/guava-libraries/wiki/PreconditionsExplained">using {@code
* Preconditions}</a>.
*
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
public final class Preconditions {
private Preconditions() {}
/**
* Ensures the truth of an expression involving one or more parameters to the calling method.
*
* @param expression a boolean expression
* @throws IllegalArgumentException if {@code expression} is false
*/
public static void checkArgument(boolean expression) {
if (!expression) {
throw new IllegalArgumentException();
}
}
/**
* Ensures the truth of an expression involving one or more parameters to the calling method.
*
* @param expression a boolean expression
* @param errorMessage the exception message to use if the check fails; will be converted to a
* string using {@link String#valueOf(Object)}
* @throws IllegalArgumentException if {@code expression} is false
*/
public static void checkArgument(boolean expression, @Nullable Object errorMessage) {
if (!expression) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
}
}
/**
* Ensures the truth of an expression involving one or more parameters to the calling method.
*
* @param expression a boolean expression
* @param errorMessageTemplate a template for the exception message should the check fail. The
* message is formed by replacing each {@code %s} placeholder in the template with an
* argument. These are matched by position - the first {@code %s} gets {@code
* errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message
* in square braces. Unmatched placeholders will be left as-is.
* @param errorMessageArgs the arguments to be substituted into the message template. Arguments
* are converted to strings using {@link String#valueOf(Object)}.
* @throws IllegalArgumentException if {@code expression} is false
* @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or
* {@code errorMessageArgs} is null (don't let this happen)
*/
public static void checkArgument(boolean expression,
@Nullable String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
if (!expression) {
throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs));
}
}
/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
*
* @param expression a boolean expression
* @throws IllegalStateException if {@code expression} is false
*/
public static void checkState(boolean expression) {
if (!expression) {
throw new IllegalStateException();
}
}
/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
*
* @param expression a boolean expression
* @param errorMessage the exception message to use if the check fails; will be converted to a
* string using {@link String#valueOf(Object)}
* @throws IllegalStateException if {@code expression} is false
*/
public static void checkState(boolean expression, @Nullable Object errorMessage) {
if (!expression) {
throw new IllegalStateException(String.valueOf(errorMessage));
}
}
/**
* Ensures the truth of an expression involving the state of the calling instance, but not
* involving any parameters to the calling method.
*
* @param expression a boolean expression
* @param errorMessageTemplate a template for the exception message should the check fail. The
* message is formed by replacing each {@code %s} placeholder in the template with an
* argument. These are matched by position - the first {@code %s} gets {@code
* errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message
* in square braces. Unmatched placeholders will be left as-is.
* @param errorMessageArgs the arguments to be substituted into the message template. Arguments
* are converted to strings using {@link String#valueOf(Object)}.
* @throws IllegalStateException if {@code expression} is false
* @throws NullPointerException if the check fails and either {@code errorMessageTemplate} or
* {@code errorMessageArgs} is null (don't let this happen)
*/
public static void checkState(boolean expression,
@Nullable String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
if (!expression) {
throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs));
}
}
/**
* Ensures that an object reference passed as a parameter to the calling method is not null.
*
* @param reference an object reference
* @return the non-null reference that was validated
* @throws NullPointerException if {@code reference} is null
*/
public static <T> T checkNotNull(T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}
/**
* Ensures that an object reference passed as a parameter to the calling method is not null.
*
* @param reference an object reference
* @param errorMessage the exception message to use if the check fails; will be converted to a
* string using {@link String#valueOf(Object)}
* @return the non-null reference that was validated
* @throws NullPointerException if {@code reference} is null
*/
public static <T> T checkNotNull(T reference, @Nullable Object errorMessage) {
if (reference == null) {
throw new NullPointerException(String.valueOf(errorMessage));
}
return reference;
}
/**
* Ensures that an object reference passed as a parameter to the calling method is not null.
*
* @param reference an object reference
* @param errorMessageTemplate a template for the exception message should the check fail. The
* message is formed by replacing each {@code %s} placeholder in the template with an
* argument. These are matched by position - the first {@code %s} gets {@code
* errorMessageArgs[0]}, etc. Unmatched arguments will be appended to the formatted message
* in square braces. Unmatched placeholders will be left as-is.
* @param errorMessageArgs the arguments to be substituted into the message template. Arguments
* are converted to strings using {@link String#valueOf(Object)}.
* @return the non-null reference that was validated
* @throws NullPointerException if {@code reference} is null
*/
public static <T> T checkNotNull(T reference,
@Nullable String errorMessageTemplate,
@Nullable Object... errorMessageArgs) {
if (reference == null) {
// If either of these parameters is null, the right thing happens anyway
throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs));
}
return reference;
}
/*
* All recent hotspots (as of 2009) *really* like to have the natural code
*
* if (guardExpression) {
* throw new BadException(messageExpression);
* }
*
* refactored so that messageExpression is moved to a separate String-returning method.
*
* if (guardExpression) {
* throw new BadException(badMsg(...));
* }
*
* The alternative natural refactorings into void or Exception-returning methods are much slower.
* This is a big deal - we're talking factors of 2-8 in microbenchmarks, not just 10-20%. (This
* is a hotspot optimizer bug, which should be fixed, but that's a separate, big project).
*
* The coding pattern above is heavily used in java.util, e.g. in ArrayList. There is a
* RangeCheckMicroBenchmark in the JDK that was used to test this.
*
* But the methods in this class want to throw different exceptions, depending on the args, so it
* appears that this pattern is not directly applicable. But we can use the ridiculous, devious
* trick of throwing an exception in the middle of the construction of another exception. Hotspot
* is fine with that.
*/
/**
* Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size
* {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive.
*
* @param index a user-supplied index identifying an element of an array, list or string
* @param size the size of that array, list or string
* @return the value of {@code index}
* @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size}
* @throws IllegalArgumentException if {@code size} is negative
*/
public static int checkElementIndex(int index, int size) {
return checkElementIndex(index, size, "index");
}
/**
* Ensures that {@code index} specifies a valid <i>element</i> in an array, list or string of size
* {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive.
*
* @param index a user-supplied index identifying an element of an array, list or string
* @param size the size of that array, list or string
* @param desc the text to use to describe this index in an error message
* @return the value of {@code index}
* @throws IndexOutOfBoundsException if {@code index} is negative or is not less than {@code size}
* @throws IllegalArgumentException if {@code size} is negative
*/
public static int checkElementIndex(
int index, int size, @Nullable String desc) {
// Carefully optimized for execution by hotspot (explanatory comment above)
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
}
return index;
}
private static String badElementIndex(int index, int size, String desc) {
if (index < 0) {
return format("%s (%s) must not be negative", desc, index);
} else if (size < 0) {
throw new IllegalArgumentException("negative size: " + size);
} else { // index >= size
return format("%s (%s) must be less than size (%s)", desc, index, size);
}
}
/**
* Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of
* size {@code size}. A position index may range from zero to {@code size}, inclusive.
*
* @param index a user-supplied index identifying a position in an array, list or string
* @param size the size of that array, list or string
* @return the value of {@code index}
* @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size}
* @throws IllegalArgumentException if {@code size} is negative
*/
public static int checkPositionIndex(int index, int size) {
return checkPositionIndex(index, size, "index");
}
/**
* Ensures that {@code index} specifies a valid <i>position</i> in an array, list or string of
* size {@code size}. A position index may range from zero to {@code size}, inclusive.
*
* @param index a user-supplied index identifying a position in an array, list or string
* @param size the size of that array, list or string
* @param desc the text to use to describe this index in an error message
* @return the value of {@code index}
* @throws IndexOutOfBoundsException if {@code index} is negative or is greater than {@code size}
* @throws IllegalArgumentException if {@code size} is negative
*/
public static int checkPositionIndex(int index, int size, @Nullable String desc) {
// Carefully optimized for execution by hotspot (explanatory comment above)
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc));
}
return index;
}
private static String badPositionIndex(int index, int size, String desc) {
if (index < 0) {
return format("%s (%s) must not be negative", desc, index);
} else if (size < 0) {
throw new IllegalArgumentException("negative size: " + size);
} else { // index > size
return format("%s (%s) must not be greater than size (%s)", desc, index, size);
}
}
/**
* Ensures that {@code start} and {@code end} specify a valid <i>positions</i> in an array, list
* or string of size {@code size}, and are in order. A position index may range from zero to
* {@code size}, inclusive.
*
* @param start a user-supplied index identifying a starting position in an array, list or string
* @param end a user-supplied index identifying a ending position in an array, list or string
* @param size the size of that array, list or string
* @throws IndexOutOfBoundsException if either index is negative or is greater than {@code size},
* or if {@code end} is less than {@code start}
* @throws IllegalArgumentException if {@code size} is negative
*/
public static void checkPositionIndexes(int start, int end, int size) {
// Carefully optimized for execution by hotspot (explanatory comment above)
if (start < 0 || end < start || end > size) {
throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
}
}
private static String badPositionIndexes(int start, int end, int size) {
if (start < 0 || start > size) {
return badPositionIndex(start, size, "start index");
}
if (end < 0 || end > size) {
return badPositionIndex(end, size, "end index");
}
// end < start
return format("end index (%s) must not be less than start index (%s)", end, start);
}
/**
* Substitutes each {@code %s} in {@code template} with an argument. These are matched by
* position: the first {@code %s} gets {@code args[0]}, etc. If there are more arguments than
* placeholders, the unmatched arguments will be appended to the end of the formatted message in
* square braces.
*
* @param template a non-null string containing 0 or more {@code %s} placeholders.
* @param args the arguments to be substituted into the message template. Arguments are converted
* to strings using {@link String#valueOf(Object)}. Arguments can be null.
*/
// Note that this is somewhat-improperly used from Verify.java as well.
static String format(String template, @Nullable Object... args) {
template = String.valueOf(template); // null -> "null"
// start substituting the arguments into the '%s' placeholders
StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
int templateStart = 0;
int i = 0;
while (i < args.length) {
int placeholderStart = template.indexOf("%s", templateStart);
if (placeholderStart == -1) {
break;
}
builder.append(template.substring(templateStart, placeholderStart));
builder.append(args[i++]);
templateStart = placeholderStart + 2;
}
builder.append(template.substring(templateStart));
// if we run out of placeholders, append the extra args in square braces
if (i < args.length) {
builder.append(" [");
builder.append(args[i++]);
while (i < args.length) {
builder.append(", ");
builder.append(args[i++]);
}
builder.append(']');
}
return builder.toString();
}
}
@@ -0,0 +1,3 @@
eclipse.preferences.version=1
encoding//src/main/resources/jPpush.properties=UTF-8
encoding/<project>=UTF-8
@@ -0,0 +1,34 @@
package com.ifish.jpush.schedule;
import com.google.gson.JsonObject;
import com.google.gson.annotations.Expose;
import com.ifish.jpush.common.resp.BaseResult;
public class ScheduleResult extends BaseResult{
@Expose String schedule_id;
@Expose String name;
@Expose Boolean enabled;
@Expose JsonObject trigger;
@Expose JsonObject push;
public String getSchedule_id() {
return schedule_id;
}
public String getName() {
return name;
}
public Boolean getEnabled() {
return enabled;
}
public JsonObject getTrigger() {
return trigger;
}
public JsonObject getPush() {
return push;
}
}
@@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
@@ -0,0 +1,34 @@
package com.ifish.jpush.report;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.reflect.TypeToken;
import com.ifish.jpush.common.resp.BaseResult;
import com.ifish.jpush.common.resp.ResponseWrapper;
public class ReceivedsResult extends BaseResult {
private static final Type RECEIVED_TYPE = new TypeToken<List<Received>>(){}.getType();
@Expose public List<Received> received_list = new ArrayList<Received>();
public static class Received {
@Expose public long msg_id;
@Expose public int android_received;
@Expose public int ios_apns_sent;
}
static ReceivedsResult fromResponse(ResponseWrapper responseWrapper) {
ReceivedsResult result = new ReceivedsResult();
if (responseWrapper.isServerResponse()) {
result.received_list = _gson.fromJson(responseWrapper.responseContent, RECEIVED_TYPE);
}
result.setResponseWrapper(responseWrapper);
return result;
}
}
@@ -0,0 +1,16 @@
#极光推送
#appKey
jpush.android.appKey=d970d5e193cb2a0bbe41653c
#secret
jpush.android.secret=60162c8cf195ce9f4dc76629
#production
jpush.android.productionMode=true
#appKey
jpush.ios.appKey=d147124018074eb970474e48
#secret
jpush.ios.secret=a7d41825e75082b13675c326
#production
jpush.ios.productionMode=true
#云信IM
netease.appKey=87b0e3315dfc2df08060bcb54246da68
netease.appSecret=e62f6c247b46
@@ -0,0 +1,35 @@
package com.ifish.jpush.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class TimeUtils {
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String TIME_ONLY_FORMAT = "HH:mm:ss";
public static boolean isDateFormat(String time) {
try {
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
format.setLenient(false);
format.parse(time);
} catch (ParseException e) {
return false;
}
return true;
}
public static boolean isTimeFormat(String time) {
try{
SimpleDateFormat format = new SimpleDateFormat(TIME_ONLY_FORMAT);
format.setLenient(false);
format.parse(time);
} catch (ParseException e) {
return false;
}
return true;
}
}
@@ -0,0 +1,126 @@
package com.ifish.jpush.report;
import java.net.URLEncoder;
import java.util.regex.Pattern;
import com.ifish.jpush.common.ClientConfig;
import com.ifish.jpush.common.ServiceHelper;
import com.ifish.jpush.common.TimeUnit;
import com.ifish.jpush.common.connection.HttpProxy;
import com.ifish.jpush.common.connection.IHttpClient;
import com.ifish.jpush.common.connection.NativeHttpClient;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.common.resp.BaseResult;
import com.ifish.jpush.common.resp.ResponseWrapper;
import com.ifish.jpush.utils.StringUtils;
public class ReportClient {
private final NativeHttpClient _httpClient;
private String _hostName;
private String _receivePath;
private String _userPath;
private String _messagePath;
public ReportClient(String masterSecret, String appKey) {
this(masterSecret, appKey, IHttpClient.DEFAULT_MAX_RETRY_TIMES, null);
}
public ReportClient(String masterSecret, String appKey, int maxRetryTimes) {
this(masterSecret, appKey, maxRetryTimes, null);
}
public ReportClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy) {
this(masterSecret, appKey, maxRetryTimes, proxy, ClientConfig.getInstance());
}
public ReportClient(String masterSecret, String appKey, int maxRetryTimes, HttpProxy proxy, ClientConfig conf) {
ServiceHelper.checkBasic(appKey, masterSecret);
_hostName = (String) conf.get(ClientConfig.REPORT_HOST_NAME);
_receivePath = (String) conf.get(ClientConfig.REPORT_RECEIVE_PATH);
_userPath = (String) conf.get(ClientConfig.REPORT_USER_PATH);
_messagePath = (String) conf.get(ClientConfig.REPORT_MESSAGE_PATH);
String authCode = ServiceHelper.getBasicAuthorization(appKey, masterSecret);
_httpClient = new NativeHttpClient(authCode, maxRetryTimes, proxy);
}
public ReceivedsResult getReceiveds(String[] msgIdArray)
throws APIConnectionException, APIRequestException {
return getReceiveds(StringUtils.arrayToString(msgIdArray));
}
public ReceivedsResult getReceiveds(String msgIds)
throws APIConnectionException, APIRequestException {
checkMsgids(msgIds);
String url = _hostName + _receivePath + "?msg_ids=" + msgIds;
ResponseWrapper response = _httpClient.sendGet(url);
return ReceivedsResult.fromResponse(response);
}
public MessagesResult getMessages(String msgIds)
throws APIConnectionException, APIRequestException {
checkMsgids(msgIds);
String url = _hostName + _messagePath + "?msg_ids=" + msgIds;
ResponseWrapper response = _httpClient.sendGet(url);
return MessagesResult.fromResponse(response);
}
public UsersResult getUsers(TimeUnit timeUnit, String start, int duration)
throws APIConnectionException, APIRequestException {
String startEncoded = null;
try {
startEncoded = URLEncoder.encode(start, "utf-8");
} catch (Exception e) {
}
String url = _hostName + _userPath
+ "?time_unit=" + timeUnit.toString()
+ "&start=" + startEncoded + "&duration=" + duration;
ResponseWrapper response = _httpClient.sendGet(url);
return BaseResult.fromResponse(response, UsersResult.class);
}
private final static Pattern MSGID_PATTERNS = Pattern.compile("[^0-9, ]");
public static void checkMsgids(String msgIds) {
if (StringUtils.isTrimedEmpty(msgIds)) {
throw new IllegalArgumentException("msgIds param is required.");
}
if (MSGID_PATTERNS.matcher(msgIds).find()) {
throw new IllegalArgumentException("msgIds param format is incorrect. "
+ "It should be msg_id (number) which response from JPush Push API. "
+ "If there are many, use ',' as interval. ");
}
msgIds = msgIds.trim();
if (msgIds.endsWith(",")) {
msgIds = msgIds.substring(0, msgIds.length() - 1);
}
String[] splits = msgIds.split(",");
try {
for (String s : splits) {
s = s.trim();
if (!StringUtils.isEmpty(s)) {
Long.parseLong(s);
}
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Every msg_id should be valid Long number which splits by ','");
}
}
}
@@ -0,0 +1,89 @@
package com.ifish.jpush.utils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
public class StringUtils {
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "A", "B", "C", "D", "E", "F" };
private static String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n = 256 + n;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String toMD5(String origin) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
} catch (Exception ex) {
ex.printStackTrace();
}
return resultString;
}
public static String encodeParam(String param) {
String encodeParam = null;
try {
encodeParam = URLEncoder.encode(param, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encodeParam;
}
public static String arrayToString(String[] values) {
if (null == values) return "";
StringBuffer buffer = new StringBuffer(values.length);
for (int i = 0; i < values.length; i++) {
buffer.append(values[i]).append(",");
}
if (buffer.length() > 0) {
return buffer.toString().substring(0, buffer.length() - 1);
}
return "";
}
public static boolean isEmpty(String s) {
return s == null || s.length() == 0;
}
public static boolean isTrimedEmpty(String s) {
return s == null || s.trim().length() == 0;
}
public static boolean isNotEmpty(String s) {
return s != null && s.length() > 0;
}
public static boolean isLineBroken(String s) {
if ( null == s ) {
return false;
}
if (s.contains("\n")) {
return true;
}
if (s.contains("\r\n")) {
return true;
}
return false;
}
}
@@ -0,0 +1,290 @@
package com.ifish.netease;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ifish.enums.NeteaseEnum;
import com.ifish.util.IfishUtil;
public class NeteaseIM {
String appKey = "";
String appSecret = "";
private static Logger log = LoggerFactory.getLogger(NeteaseIM.class);
public NeteaseIM(String appKey,String appSecret){
this.appKey=appKey;
this.appSecret=appSecret;
}
/**
* 创建云信ID
* @param accid 云信ID,最大长度32字符,必须保证一个APP内唯一
* @param name 云信ID昵称,最大长度64字符,用来PUSH推送 时显示的昵称
* @param icon 云信ID头像URL,第三方可选填,最大长度1024
* @param props json属性,第三方可选填,最大长度1024字符
* @return
* @throws Exception
*/
public Map<String, String> createAccid(String accid,String name,String icon,String props){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/user/create.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("accid", accid));
nvps.add(new BasicNameValuePair("name", name));
nvps.add(new BasicNameValuePair("icon", icon));
nvps.add(new BasicNameValuePair("props", props));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
System.out.println(responseStr);
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
//200
if(code.equals(NeteaseEnum.status200.getKey())){
JSONObject infoJson = json.getJSONObject("info");
String token = infoJson.getString("token");
map.put("token", token);
}
else if(code.equals(NeteaseEnum.status414.getKey())){
String desc = json.getString("desc");
}
return map;
} catch (Exception e) {
log.error("CreateAccid error message:{},{}",accid,e.toString());
}
return null;
}
/**
* 云信ID基本信息更新
* @param accid 云信ID,最大长度32字符,必须保证一个APP内唯一
* @param token 云信ID可以指定登录token值,最大长度128字符
* @param props json属性,第三方可选填,最大长度1024字符
* @return
* @throws Exception
*/
public Map<String, String> updateAccid(String accid,String token,String props){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/user/update.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("accid", accid));
nvps.add(new BasicNameValuePair("token", token));
nvps.add(new BasicNameValuePair("props", props));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
return map;
} catch (Exception e) {
log.error("updateAccid error message:{},{}",accid,e.toString());
}
return null;
}
/**
* 更新并获取新token
* @param accid
* @return
* @throws Exception
*/
public Map<String, String> refreshToken(String accid){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/user/refreshToken.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("accid", accid));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
//200
if(code.equals(NeteaseEnum.status200.getKey())){
JSONObject infoJson = json.getJSONObject("info");
String token = infoJson.getString("token");
map.put("token", token);
}
else if(code.equals(NeteaseEnum.status414.getKey())){
String desc = json.getString("desc");
}
return map;
} catch (Exception e) {
log.error("refreshToken error message:{},{}",accid,e.toString());
}
return null;
}
/**
* 发送普通消息
* @param from
* @param to
* @param msg
* @return
*/
public Map<String, String> sendMsg(String from,String to,String msg){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/msg/sendMsg.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("from", from));
nvps.add(new BasicNameValuePair("to", to));
nvps.add(new BasicNameValuePair("ope", "0"));
nvps.add(new BasicNameValuePair("type", "0"));
nvps.add(new BasicNameValuePair("body", "{\"msg\":\""+msg+"\"}"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
System.out.println(responseStr);
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
//200
if(code.equals(NeteaseEnum.status200.getKey())){
}
else if(code.equals(NeteaseEnum.status414.getKey())){
String desc = json.getString("desc");
}
return map;
} catch (Exception e) {
log.error("refreshToken error message:{}",e.toString());
}
return null;
}
/**
* 批量发送点对点普通消息
* @param fromAccid
* @param toAccids
* @param msg
* @return
*/
public Map<String, String> sendBatchMsg(String fromAccid,String toAccids,String msg){
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
String url = "https://api.netease.im/nimserver/msg/sendBatchMsg.action";
HttpPost httpPost = new HttpPost(url);
String nonce = IfishUtil.getCharAndNumr(10);
String curTime = String.valueOf((new Date()).getTime() / 1000L);
//计算CheckSum
String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce ,curTime);
//设置请求的header
httpPost.addHeader("AppKey", appKey);
httpPost.addHeader("Nonce", nonce);
httpPost.addHeader("CurTime", curTime);
httpPost.addHeader("CheckSum", checkSum);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
//设置请求的参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("fromAccid", fromAccid));
nvps.add(new BasicNameValuePair("toAccids", toAccids));
nvps.add(new BasicNameValuePair("type", "0"));
nvps.add(new BasicNameValuePair("body", "{\"msg\":\""+msg+"\"}"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
//执行请求
HttpResponse response = httpClient.execute(httpPost);
//执行结果
String responseStr = EntityUtils.toString(response.getEntity(), "utf-8");
System.out.println(responseStr);
JSONObject json = new JSONObject(responseStr);
String code = json.getString("code");
Map<String, String> map = new HashMap<String, String>();
map.put("code", code);
//200
if(code.equals(NeteaseEnum.status200.getKey())){
}
else if(code.equals(NeteaseEnum.status414.getKey())){
String desc = json.getString("desc");
}
return map;
} catch (Exception e) {
log.error("refreshToken error message:{}",e.toString());
}
return null;
}
public static void main(String[] args) {
List<String> list= new ArrayList<String>();
list.add("hello");
list.add("hello1");
new NeteaseIM("87b0e3315dfc2df08060bcb54246da68", "e62f6c247b46").createAccid("ifish", "爱鱼奇", "", "");
}
}
@@ -0,0 +1,17 @@
package com.ifish.jpush.common.resp;
public class DefaultResult extends BaseResult {
public static DefaultResult fromResponse(ResponseWrapper responseWrapper) {
DefaultResult result = null;
if (responseWrapper.isServerResponse()) {
result = new DefaultResult();
}
if(result!=null){
result.setResponseWrapper(responseWrapper);
}
return result;
}
}
@@ -0,0 +1,11 @@
package com.ifish.jpush.push.model;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
public interface PushModel {
public static Gson gson = new Gson();
public JsonElement toJSON();
}
@@ -0,0 +1,13 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
@@ -0,0 +1,93 @@
package com.ifish.jpush.common.resp;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public abstract class BaseResult implements IRateLimiting {
public static final int ERROR_CODE_NONE = -1;
public static final int ERROR_CODE_OK = 0;
public static final String ERROR_MESSAGE_NONE = "None error message.";
protected static final int RESPONSE_OK = 200;
protected static Gson _gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
private ResponseWrapper responseWrapper;
public void setResponseWrapper(ResponseWrapper responseWrapper) {
this.responseWrapper = responseWrapper;
}
public String getOriginalContent() {
if (null != responseWrapper) {
return responseWrapper.responseContent;
}
return null;
}
public int getResponseCode() {
if(null != responseWrapper) {
return responseWrapper.responseCode;
}
return -1;
}
public boolean isResultOK() {
if(null != responseWrapper) {
return ( responseWrapper.responseCode / 200 ) == 1;
}
return false;
}
public static <T extends BaseResult> T fromResponse(
ResponseWrapper responseWrapper, Class<T> clazz) {
T result = null;
if (responseWrapper.isServerResponse()) {
result = _gson.fromJson(responseWrapper.responseContent, clazz);
} else {
try {
result = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if(result!=null){
result.setResponseWrapper(responseWrapper);
}
return result;
}
@Override
public int getRateLimitQuota() {
if (null != responseWrapper) {
return responseWrapper.rateLimitQuota;
}
return 0;
}
@Override
public int getRateLimitRemaining() {
if (null != responseWrapper) {
return responseWrapper.rateLimitRemaining;
}
return 0;
}
@Override
public int getRateLimitReset() {
if (null != responseWrapper) {
return responseWrapper.rateLimitReset;
}
return 0;
}
@Override
public String toString() {
return _gson.toJson(this);
}
}
@@ -0,0 +1,204 @@
package com.ifish.jpush.examples;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import com.ifish.jpush.JPushClient;
import com.ifish.jpush.common.ClientConfig;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.push.PushResult;
import com.ifish.jpush.push.model.Message;
import com.ifish.jpush.push.model.Options;
import com.ifish.jpush.push.model.Platform;
import com.ifish.jpush.push.model.PushPayload;
import com.ifish.jpush.push.model.audience.Audience;
import com.ifish.jpush.push.model.audience.AudienceTarget;
import com.ifish.jpush.push.model.notification.AndroidNotification;
import com.ifish.jpush.push.model.notification.IosNotification;
import com.ifish.jpush.push.model.notification.Notification;
public class PushExample {
protected static final Logger LOG = LoggerFactory.getLogger(PushExample.class);
// demo App defined in resources/jpush-api.conf
private static final String appKey ="d970d5e193cb2a0bbe41653c";
private static final String masterSecret = "60162c8cf195ce9f4dc76629";
public static final String TITLE = "Test from API example";
public static final String ALERT = "Test from API Example - alert";
public static final String MSG_CONTENT = "Test from API Example - msgContent";
public static final String REGISTRATION_ID = "0900e8d85ef";
public static final String TAG = "tag_api";
public static void main(String[] args) {
//testSendPushWithCustomConfig();
Map<String,String> map = new HashMap<String, String>();
map.put("device_id", "1");
map.put("device_name", "设备1");
map.put("msg_type", "remove_device");
testSendIosAlert("300","设备解除绑定", "你已失去对“设备1”设备的控制权", map);
//testSendAndroidNotification("40","标题401","内容40",map);
//testSendAndroidNotification("40","标题","内容");
}
public static void testSendPush() {
// HttpProxy proxy = new HttpProxy("localhost", 3128);
// Can use this https proxy: https://github.com/Exa-Networks/exaproxy
JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3);
// For push, all you need do is to build PushPayload object.
PushPayload payload = buildPushObject_all_all_alert();
try {
PushResult result = jpushClient.sendPush(payload);
LOG.info("Got result - " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
LOG.info("Msg ID: " + e.getMsgId());
}
}
public static PushPayload buildPushObject_all_all_alert() {
return PushPayload.alertAll(ALERT);
}
public static PushPayload buildPushObject_all_alias_alert() {
return PushPayload.newBuilder()
.setPlatform(Platform.all())
.setAudience(Audience.alias("alias1"))
.setNotification(Notification.alert(ALERT))
.build();
}
public static PushPayload buildPushObject_android_tag_alertWithTitle() {
return PushPayload.newBuilder()
.setPlatform(Platform.android())
.setAudience(Audience.tag("tag1"))
.setNotification(Notification.android(ALERT, TITLE, null))
.build();
}
public static PushPayload buildPushObject_android_and_ios() {
return PushPayload.newBuilder()
.setPlatform(Platform.android_ios())
.setAudience(Audience.tag("tag1"))
.setNotification(Notification.newBuilder()
.setAlert("alert content")
.addPlatformNotification(AndroidNotification.newBuilder()
.setTitle("Android Title").build())
.addPlatformNotification(IosNotification.newBuilder()
.incrBadge(1)
.addExtra("extra_key", "extra_value").build())
.build())
.build();
}
public static PushPayload buildPushObject_ios_tagAnd_alertWithExtrasAndMessage() {
return PushPayload.newBuilder()
.setPlatform(Platform.ios())
.setAudience(Audience.tag_and("tag1", "tag_all"))
.setNotification(Notification.newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert(ALERT)
.setBadge(5)
.setSound("happy")
.addExtra("from", "JPush")
.build())
.build())
.setMessage(Message.content(MSG_CONTENT))
.setOptions(Options.newBuilder()
.setApnsProduction(true)
.build())
.build();
}
public static PushPayload buildPushObject_ios_audienceMore_messageWithExtras() {
return PushPayload.newBuilder()
.setPlatform(Platform.android_ios())
.setAudience(Audience.newBuilder()
.addAudienceTarget(AudienceTarget.tag("tag1", "tag2"))
.addAudienceTarget(AudienceTarget.alias("alias1", "alias2"))
.build())
.setMessage(Message.newBuilder()
.setMsgContent(MSG_CONTENT)
.addExtra("from", "JPush")
.build())
.build();
}
public static void testSendPushWithCustomConfig() {
ClientConfig config = ClientConfig.getInstance();
// Setup the custom hostname
config.setPushHostName("https://api.jpush.cn");
JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3, null, config);
// For push, all you need do is to build PushPayload object.
PushPayload payload = buildPushObject_all_all_alert();
try {
PushResult result = jpushClient.sendPush(payload);
LOG.info("Got result - " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
LOG.info("Msg ID: " + e.getMsgId());
}
}
public static void testSendIosAlert(String alias,String title,String body,Map<String,String> extras) {
JPushClient jpushClient = new JPushClient(masterSecret, appKey, true ,86400);
try {
JsonObject json = new JsonObject();
json.addProperty("title", title);
json.addProperty("body", body);
PushResult result = jpushClient.sendIosNotificationWithAlias(json, extras, alias);
System.out.println("Got result - " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. "+e);
LOG.error("HTTP Status: " + e.getStatus());
LOG.error("Error Code: " + e.getErrorCode());
System.out.println(e.getErrorCode());
LOG.error("Error Message: " + e.getErrorMessage());
}
}
public static void testSendAndroidNotification(String alias,String title,String alert,Map<String,String> map) {
JPushClient jpushClient = new JPushClient(masterSecret, appKey , true ,86400);
try {
PushResult result = jpushClient.sendAndroidNotificationWithAlias(title ,alert, map, alias);
System.out.println("Got result - " + result);
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. "+e);
LOG.error("HTTP Status: " + e.getStatus());
LOG.error("Error Code: " + e.getErrorCode());
System.out.println(e.getMessage());
LOG.error("Error Message: " + e.getErrorMessage());
}
}
}
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
@@ -0,0 +1,163 @@
package com.ifish.jpush.push.model.notification;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.push.model.PushModel;
import com.ifish.jpush.utils.Preconditions;
public class Notification implements PushModel {
private final Object alert;
private final Set<PlatformNotification> notifications;
private Notification(Object alert, Set<PlatformNotification> notifications) {
this.alert = alert;
this.notifications = notifications;
}
public static Builder newBuilder() {
return new Builder();
}
/**
* Quick set all platform alert.
* Platform notification can override this alert.
*
* @param alert Notification alert
* @return first level notification object
*/
public static Notification alert(Object alert) {
return newBuilder().setAlert(alert).build();
}
/**
* shortcut
*/
public static Notification android(String alert, String title, Map<String, String> extras) {
return newBuilder()
.addPlatformNotification(AndroidNotification.newBuilder()
.setAlert(alert)
.setTitle(title)
.setBuilderId(1)
.addExtras(extras)
.build())
.build();
}
/**
* shortcut
*/
public static Notification ios(Object alert, Map<String, String> extras) {
return newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert(alert)
.setSound("default")
.setCategory("INVITE_CATEGORY")
.addExtras(extras)
.build())
.build();
}
/**
* shortcut
*/
public static Notification ios_auto_badge() {
return newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert("")
.autoBadge()
.build())
.build();
}
/**
* shortcut
*/
public static Notification ios_set_badge(int badge) {
return newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert("")
.setBadge(badge)
.build())
.build();
}
/**
* shortcut
*/
public static Notification ios_incr_badge(int badge) {
return newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert("")
.incrBadge(badge)
.build())
.build();
}
/**
* shortcut
*/
public static Notification winphone(String alert, Map<String, String> extras) {
return newBuilder()
.addPlatformNotification(WinphoneNotification.newBuilder()
.setAlert(alert)
.addExtras(extras)
.build())
.build();
}
public JsonElement toJSON() {
JsonObject json = new JsonObject();
if (null != alert) {
if(alert instanceof JsonObject) {
json.add(PlatformNotification.ALERT, (JsonObject) alert);
} else if (alert instanceof IosAlert) {
json.add(PlatformNotification.ALERT, ((IosAlert) alert).toJSON());
} else {
json.add(PlatformNotification.ALERT, new JsonPrimitive(alert.toString()));
}
}
if (null != notifications) {
for (PlatformNotification pn : notifications) {
if (this.alert != null && pn.getAlert() == null) {
pn.setAlert(this.alert);
}
Preconditions.checkArgument(! (null == pn.getAlert()),
"For any platform notification, alert field is needed. It can be empty string.");
json.add(pn.getPlatform(), pn.toJSON());
}
}
return json;
}
public static class Builder {
private Object alert;
private Set<PlatformNotification> builder;
public Builder setAlert(Object alert) {
this.alert = alert;
return this;
}
public Builder addPlatformNotification(PlatformNotification notification) {
if (null == builder) {
builder = new HashSet<PlatformNotification>();
}
builder.add(notification);
return this;
}
public Notification build() {
Preconditions.checkArgument(! (null == builder && null == alert),
"No notification payload is set.");
return new Notification(alert, builder);
}
}
}
@@ -0,0 +1,331 @@
package com.ifish.jpush.common.connection;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.common.resp.ResponseWrapper;
/**
* The implementation has no connection pool mechanism, used origin java connection.
*
* 本实现没有连接池机制,基于 Java 原始的 HTTP 连接实现。
*
* 遇到连接超时,会自动重连指定的次数(默认为 3);如果是读取超时,则不会自动重连。
*
* 可选支持 HTTP 代理,同时支持 2 种方式:1) HTTP 头上加上 Proxy-Authorization 信息;2)全局配置 Authenticator.setDefault
*/
public class NativeHttpClient implements IHttpClient {
private static final Logger LOG = LoggerFactory.getLogger(NativeHttpClient.class);
private static final String KEYWORDS_CONNECT_TIMED_OUT = "connect timed out";
private static final String KEYWORDS_READ_TIMED_OUT = "Read timed out";
private int _maxRetryTimes = 0;
private String _authCode;
private HttpProxy _proxy;
/**
* 默认的重连次数是 3
*/
public NativeHttpClient(String authCode) {
this(authCode, DEFAULT_MAX_RETRY_TIMES, null);
}
public NativeHttpClient(String authCode, int maxRetryTimes, HttpProxy proxy) {
this._maxRetryTimes = maxRetryTimes;
LOG.info("Created instance with _maxRetryTimes = " + _maxRetryTimes);
this._authCode = authCode;
this._proxy = proxy;
if ( null != _proxy && _proxy.isAuthenticationNeeded()) {
Authenticator.setDefault(new SimpleProxyAuthenticator(
_proxy.getUsername(), _proxy.getPassword()));
}
initSSL();
}
public ResponseWrapper sendGet(String url)
throws APIConnectionException, APIRequestException {
return sendGet(url, null);
}
public ResponseWrapper sendGet(String url, String content)
throws APIConnectionException, APIRequestException {
return doRequest(url, content, RequestMethod.GET);
}
public ResponseWrapper sendDelete(String url)
throws APIConnectionException, APIRequestException {
return sendDelete(url, null);
}
public ResponseWrapper sendDelete(String url, String content)
throws APIConnectionException, APIRequestException {
return doRequest(url, content, RequestMethod.DELETE);
}
public ResponseWrapper sendPost(String url, String content)
throws APIConnectionException, APIRequestException {
return doRequest(url, content, RequestMethod.POST);
}
public ResponseWrapper sendPut(String url, String content)
throws APIConnectionException, APIRequestException {
return doRequest(url, content, RequestMethod.PUT);
}
public ResponseWrapper doRequest(String url, String content,
RequestMethod method) throws APIConnectionException, APIRequestException {
ResponseWrapper response = null;
for (int retryTimes = 0; ; retryTimes++) {
try {
response = _doRequest(url, content, method);
break;
} catch (SocketTimeoutException e) {
if (KEYWORDS_READ_TIMED_OUT.equals(e.getMessage())) {
// Read timed out. For push, maybe should not re-send.
throw new APIConnectionException(READ_TIMED_OUT_MESSAGE, e, true);
} else { // connect timed out
if (retryTimes >= _maxRetryTimes) {
throw new APIConnectionException(CONNECT_TIMED_OUT_MESSAGE, e, retryTimes);
} else {
LOG.debug("connect timed out - retry again - " + (retryTimes + 1));
}
}
}
}
return response;
}
private ResponseWrapper _doRequest(String url, String content,
RequestMethod method) throws APIConnectionException, APIRequestException,
SocketTimeoutException {
LOG.debug("Send request - " + method.toString() + " "+ url);
if (null != content) {
LOG.debug("Request Content - " + content);
}
HttpURLConnection conn = null;
OutputStream out = null;
StringBuffer sb = new StringBuffer();
ResponseWrapper wrapper = new ResponseWrapper();
try {
URL aUrl = new URL(url);
if (null != _proxy) {
conn = (HttpURLConnection) aUrl.openConnection(_proxy.getNetProxy());
if (_proxy.isAuthenticationNeeded()) {
conn.setRequestProperty("Proxy-Authorization", _proxy.getProxyAuthorization());
}
} else {
conn = (HttpURLConnection) aUrl.openConnection();
}
conn.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT);
conn.setReadTimeout(DEFAULT_READ_TIMEOUT);
conn.setUseCaches(false);
conn.setRequestMethod(method.name());
conn.setRequestProperty("User-Agent", JPUSH_USER_AGENT);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Accept-Charset", CHARSET);
conn.setRequestProperty("Charset", CHARSET);
conn.setRequestProperty("Authorization", _authCode);
conn.setRequestProperty("Content-Type", CONTENT_TYPE_JSON);
if(null == content) {
conn.setDoOutput(false);
} else {
conn.setDoOutput(true);
byte[] data = content.getBytes(CHARSET);
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
out = conn.getOutputStream();
out.write(data);
out.flush();
}
int status = conn.getResponseCode();
InputStream in = null;
if (status / 100 == 2) {
in = conn.getInputStream();
} else {
in = conn.getErrorStream();
}
if (null != in) {
InputStreamReader reader = new InputStreamReader(in, CHARSET);
char[] buff = new char[1024];
int len;
while ((len = reader.read(buff)) > 0) {
sb.append(buff, 0, len);
}
}
String responseContent = sb.toString();
wrapper.responseCode = status;
wrapper.responseContent = responseContent;
String quota = conn.getHeaderField(RATE_LIMIT_QUOTA);
String remaining = conn.getHeaderField(RATE_LIMIT_Remaining);
String reset = conn.getHeaderField(RATE_LIMIT_Reset);
wrapper.setRateLimit(quota, remaining, reset);
if (status >= 200 && status < 300) {
LOG.debug("Succeed to get response OK - responseCode:" + status);
LOG.debug("Response Content - " + responseContent);
} else if (status >= 300 && status < 400) {
LOG.warn("Normal response but unexpected - responseCode:" + status + ", responseContent:" + responseContent);
} else {
LOG.warn("Got error response - responseCode:" + status + ", responseContent:" + responseContent);
switch (status) {
case 400:
LOG.error("Your request params is invalid. Please check them according to error message.");
wrapper.setErrorObject();
break;
case 401:
LOG.error("Authentication failed! Please check authentication params according to docs.");
wrapper.setErrorObject();
break;
case 403:
LOG.error("Request is forbidden! Maybe your appkey is listed in blacklist or your params is invalid.");
wrapper.setErrorObject();
break;
case 404:
LOG.error("Request page is not found! Maybe your params is invalid.");
wrapper.setErrorObject();
break;
case 410:
LOG.error("Request resource is no longer in service. Please according to notice on official website.");
wrapper.setErrorObject();
case 429:
LOG.error("Too many requests! Please review your appkey's request quota.");
wrapper.setErrorObject();
break;
case 500:
case 502:
case 503:
case 504:
LOG.error("Seems encountered server error. Maybe JPush is in maintenance? Please retry later.");
break;
default:
LOG.error("Unexpected response.");
}
throw new APIRequestException(wrapper);
}
} catch (SocketTimeoutException e) {
if (e.getMessage().contains(KEYWORDS_CONNECT_TIMED_OUT)) {
throw e;
} else if (e.getMessage().contains(KEYWORDS_READ_TIMED_OUT)) {
throw new SocketTimeoutException(KEYWORDS_READ_TIMED_OUT);
}
LOG.debug(IO_ERROR_MESSAGE, e);
throw new APIConnectionException(IO_ERROR_MESSAGE, e);
} catch (IOException e) {
LOG.debug(IO_ERROR_MESSAGE, e);
throw new APIConnectionException(IO_ERROR_MESSAGE, e);
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e) {
LOG.error("Failed to close stream.", e);
}
}
if (null != conn) {
conn.disconnect();
}
}
return wrapper;
}
protected void initSSL() {
TrustManager[] tmCerts = new javax.net.ssl.TrustManager[1];
tmCerts[0] = new SimpleTrustManager();
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, tmCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HostnameVerifier hostnameVerifier = new SimpleHostnameVerifier();
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
} catch (Exception e) {
LOG.error("Init SSL error", e);
}
}
private static class SimpleHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
private static class SimpleTrustManager implements TrustManager, X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
return;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
return;
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
private static class SimpleProxyAuthenticator extends java.net.Authenticator {
private String username;
private String password;
public SimpleProxyAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
this.username,
this.password.toCharArray());
}
}
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="java" version="1.7"/>
<installed facet="jst.web" version="3.0"/>
</faceted-project>
@@ -0,0 +1,153 @@
package com.ifish.jpush.push.model;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.utils.Preconditions;
public class Message implements PushModel {
private static final String TITLE = "title";
private static final String MSG_CONTENT = "msg_content";
private static final String CONTENT_TYPE = "content_type";
private static final String EXTRAS = "extras";
private final String title;
private final String msgContent;
private final String contentType;
private final Map<String, String> extras;
private final Map<String, Number> numberExtras;
private final Map<String, Boolean> booleanExtras;
private Message(String title, String msgContent, String contentType,
Map<String, String> extras,
Map<String, Number> numberExtras,
Map<String, Boolean> booleanExtras) {
this.title = title;
this.msgContent = msgContent;
this.contentType = contentType;
this.extras = extras;
this.numberExtras = numberExtras;
this.booleanExtras = booleanExtras;
}
public static Builder newBuilder() {
return new Builder();
}
public static Message content(String msgContent) {
return new Builder().setMsgContent(msgContent).build();
}
@Override
public JsonElement toJSON() {
JsonObject json = new JsonObject();
if (null != title) {
json.add(TITLE, new JsonPrimitive(title));
}
if (null != msgContent) {
json.add(MSG_CONTENT, new JsonPrimitive(msgContent));
}
if (null != contentType) {
json.add(CONTENT_TYPE, new JsonPrimitive(contentType));
}
JsonObject extrasObject = null;
if (null != extras || null != numberExtras || null != booleanExtras) {
extrasObject = new JsonObject();
}
if (null != extras) {
for (String key : extras.keySet()) {
extrasObject.add(key, new JsonPrimitive(extras.get(key)));
}
}
if (null != numberExtras) {
for (String key : numberExtras.keySet()) {
extrasObject.add(key, new JsonPrimitive(numberExtras.get(key)));
}
}
if (null != booleanExtras) {
for (String key : booleanExtras.keySet()) {
extrasObject.add(key, new JsonPrimitive(booleanExtras.get(key)));
}
}
if (null != extras || null != numberExtras || null != booleanExtras) {
json.add(EXTRAS, extrasObject);
}
return json;
}
public static class Builder {
private String title;
private String msgContent;
private String contentType;
private Map<String, String> extrasBuilder;
private Map<String, Number> numberExtrasBuilder;
private Map<String, Boolean> booleanExtrasBuilder;
public Builder setTitle(String title) {
this.title = title;
return this;
}
public Builder setMsgContent(String msgContent) {
this.msgContent = msgContent;
return this;
}
public Builder setContentType(String contentType) {
this.contentType = contentType;
return this;
}
public Builder addExtra(String key, String value) {
Preconditions.checkArgument(! (null == key || null == value), "Key/Value should not be null.");
if (null == extrasBuilder) {
extrasBuilder = new HashMap<String, String>();
}
extrasBuilder.put(key, value);
return this;
}
public Builder addExtras(Map<String, String> extras) {
Preconditions.checkArgument(! (null == extras), "extras should not be null.");
if (null == extrasBuilder) {
extrasBuilder = new HashMap<String, String>();
}
for (String key : extras.keySet()) {
extrasBuilder.put(key, extras.get(key));
}
return this;
}
public Builder addExtra(String key, Number value) {
Preconditions.checkArgument(! (null == key || null == value), "Key/Value should not be null.");
if (null == numberExtrasBuilder) {
numberExtrasBuilder = new HashMap<String, Number>();
}
numberExtrasBuilder.put(key, value);
return this;
}
public Builder addExtra(String key, Boolean value) {
Preconditions.checkArgument(! (null == key || null == value), "Key/Value should not be null.");
if (null == booleanExtrasBuilder) {
booleanExtrasBuilder = new HashMap<String, Boolean>();
}
booleanExtrasBuilder.put(key, value);
return this;
}
public Message build() {
Preconditions.checkArgument(! (null == msgContent),
"msgContent should be set");
return new Message(title, msgContent, contentType,
extrasBuilder, numberExtrasBuilder, booleanExtrasBuilder);
}
}
}
@@ -0,0 +1,170 @@
package com.ifish.job;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import com.ifish.enums.PhoneTypeEnum;
import com.ifish.jpush.JPushNotification;
import com.ifish.netease.NeteaseIM;
import com.ifish.util.IfishUtil;
public class job{
@Autowired
private NeteaseIM neteaseIM;
@Autowired
private JPushNotification jPushNotification2;
private Connection connection = null;
private Statement stmt = null;
private PreparedStatement prest = null;
/**
* 查询需要推送的用户并且推送完修改为下一次提醒日期
*/
public void pushRemind(){
System.out.println(new Date()+"开始任务");
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myfishdb?characterEncoding=UTF-8", "ifish", "ifish7pwd");
stmt = connection.createStatement();
prest = connection.prepareStatement("update tbl_tmp_push_remind set is_push=? where user_id=? and device_id=?");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//结果集
ResultSet result = null;
try {
//推送提醒数
int rowCount = 0;
//按分页来获取数据
int pageNo = 0;
//云信限制每次最多500条
int pageSize = 500;
//查询总共需要推送的用户数
String countSql = "select count(1) as countRow from tbl_tmp_push_remind where is_push='0'";
result = stmt.executeQuery(countSql);
if(result.next()){
rowCount=result.getInt("countRow");
pageNo = (rowCount+pageSize-1)/pageSize;
}
System.out.println(pageNo);
for (int i = 0; i < pageNo; i++) {
result = stmt.executeQuery("select device_id,user_id,show_name,login_type from tbl_tmp_push_remind where is_push='0' limit 0,"+pageSize);
//推送的用户
List<String> androidUser = new ArrayList<String>();
List<String> iosUser = new ArrayList<String>();
List<String> ids = new ArrayList<String>();
//更新提醒过的用户
while(result.next()){
Integer deviceId= result.getInt("device_id");
Integer userId = result.getInt("user_id");
String loginType = result.getString("login_type");
prest.setString(1, "1");
prest.setInt(2, userId);
prest.setInt(3, deviceId);
prest.addBatch();
//云信
ids.add(userId.toString());
//极光
if(loginType.toLowerCase().equals(PhoneTypeEnum.android.getKey())){
androidUser.add(userId.toString());
}
else if(loginType.toLowerCase().equals(PhoneTypeEnum.ios.getKey())){
iosUser.add(userId.toString());
}
}
//发送云信消息
if(ids.size()>0){
neteaseIM.sendBatchMsg("ifish", JSONArray.fromObject(ids).toString(), "【换水提醒】您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置");
}
//极光推送
Integer iosSize = iosUser.size();
Integer androidSize = androidUser.size();
if(iosSize>0){
push(PhoneTypeEnum.ios,iosUser.toArray(new String[iosSize]));
}
if(androidSize>0){
push(PhoneTypeEnum.android,androidUser.toArray(new String[androidSize]));
}
//批量提交
prest.executeBatch();
//云信一分钟访问不超过120次
Thread.sleep(600);
}
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(result!=null){
try {
result.close();
result = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
stmt = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(prest!=null){
try {
prest.close();
prest = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
connection = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* 推送提醒
* @param type
* @param ids
*/
public void push(PhoneTypeEnum type,String[] ids){
try {
Map<String,String> map = new HashMap<String, String>();
map.put("timestamp", IfishUtil.format2(new Date()));
//推送android
/*if(type.equals(PhoneTypeEnum.android)){
System.out.println(new Date()+"android推送"+ids.length+"个");
jPushNotification.sendAndroidNotification(ids, "换水提醒", "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置", map);
}*/
//推送IOS
if(type.equals(PhoneTypeEnum.ios)){
System.out.println(new Date()+"ios推送"+ids.length+"个");
jPushNotification2.sendIosNotification(ids, "换水提醒", "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置", map);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,157 @@
package com.ifish.job;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import com.ifish.enums.PhoneTypeEnum;
import com.ifish.jpush.JPushNotification;
import com.ifish.util.IfishUtil;
public class job{
@Autowired
private JPushNotification jPushNotification;
@Autowired
private JPushNotification jPushNotification2;
private Connection connection = null;
private Statement stmt = null;
private PreparedStatement prest = null;
/**
* 查询需要推送的用户并且推送完修改为下一次提醒日期
*/
public void pushRemind(){
System.out.println(new Date()+"开始任务");
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myfishdb?characterEncoding=UTF-8", "ifish", "ifish7pwd");
stmt = connection.createStatement();
prest = connection.prepareStatement("update tbl_tmp_push_remind set is_push=? where user_id=? and device_id=?");
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//结果集
ResultSet result = null;
try {
//推送提醒数
int rowCount = 0;
//按分页来获取数据
int pageNo = 0;
int pageSize = 900;
//查询总共需要推送的用户数
String countSql = "select count(1) as countRow from tbl_tmp_push_remind where is_push='0'";
result = stmt.executeQuery(countSql);
if(result.next()){
rowCount=result.getInt("countRow");
pageNo = (rowCount+pageSize-1)/pageSize;
}
System.out.println(pageNo);
for (int i = 0; i < pageNo; i++) {
result = stmt.executeQuery("select device_id,user_id,show_name,login_type from tbl_tmp_push_remind where is_push='0' limit 0,"+pageSize);
//推送的用户
List<String> androidUser = new ArrayList<String>();
List<String> iosUser = new ArrayList<String>();
//更新提醒过的用户
while(result.next()){
Integer deviceId= result.getInt("device_id");
Integer userId = result.getInt("user_id");
String loginType = result.getString("login_type");
prest.setString(1, "1");
prest.setInt(2, userId);
prest.setInt(3, deviceId);
prest.addBatch();
if(loginType.toLowerCase().equals(PhoneTypeEnum.android.getKey())){
androidUser.add(userId.toString());
}
else if(loginType.toLowerCase().equals(PhoneTypeEnum.ios.getKey())){
iosUser.add(userId.toString());
}
}
//推送
Integer iosSize = iosUser.size();
Integer androidSize = androidUser.size();
if(iosSize>0){
push(PhoneTypeEnum.ios,iosUser.toArray(new String[iosSize]));
}
if(androidSize>0){
System.out.println(androidUser.toString());
push(PhoneTypeEnum.android,androidUser.toArray(new String[androidSize]));
}
//批量提交
prest.executeBatch();
}
} catch (SQLException e) {
e.printStackTrace();
}
finally{
if(result!=null){
try {
result.close();
result = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
stmt = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(prest!=null){
try {
prest.close();
prest = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
connection = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* 推送提醒
* @param type
* @param ids
*/
public void push(PhoneTypeEnum type,String[] ids){
try {
Map<String,String> map = new HashMap<String, String>();
map.put("timestamp", IfishUtil.format2(new Date()));
//推送android
if(type.equals(PhoneTypeEnum.android)){
System.out.println(new Date()+"android推送"+ids.length+"个");
jPushNotification.sendAndroidNotification(ids, "换水提醒", "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置", map);
}
//推送IOS
else if(type.equals(PhoneTypeEnum.ios)){
System.out.println(new Date()+"ios推送"+ids.length+"个");
jPushNotification2.sendIosNotification(ids, "换水提醒", "您的水族箱需要换水啦~您可以在水箱设置中更改提醒设置", map);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,61 @@
package com.ifish.jpush.common.connection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ifish.jpush.common.ServiceHelper;
import com.ifish.jpush.utils.Preconditions;
public class HttpProxy {
private static final Logger LOG = LoggerFactory.getLogger(HttpProxy.class);
private String host;
private int port;
private String username;
private String password;
private boolean authenticationNeeded = false;
public HttpProxy(String host, int port) {
this.host = host;
this.port = port;
}
public HttpProxy(String host, int port, String username, String password) {
this(host, port);
Preconditions.checkArgument(! (null == username), "username should not be null");
Preconditions.checkArgument(! (null == password), "password should not be null");
this.username = username;
this.password = password;
authenticationNeeded = true;
LOG.info("Http Proxy - host:" + host + ", port:" + port
+ ", username:" + username + ", password:" + password);
}
public Proxy getNetProxy() {
return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, port));
}
public boolean isAuthenticationNeeded() {
return this.authenticationNeeded;
}
public String getProxyAuthorization() {
return ServiceHelper.getBasicAuthorization(username, password);
}
public String getUsername() {
return this.username;
}
public String getPassword() {
return this.password;
}
}
@@ -0,0 +1,39 @@
package com.ifish.jpush.report;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.ifish.jpush.common.TimeUnit;
import com.ifish.jpush.common.resp.BaseResult;
public class UsersResult extends BaseResult {
@Expose public TimeUnit time_unit;
@Expose public String start;
@Expose public int duration;
@Expose public List<User> items = new ArrayList<User>();
public static class User {
@Expose public String time;
@Expose public Android android;
@Expose public Ios ios;
}
public static class Android {
@SerializedName("new") @Expose public long add;
@Expose public int online;
@Expose public int active;
}
public static class Ios {
@SerializedName("new") @Expose public long add;
@Expose public int online;
@Expose public int active;
}
}
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<!-- 尽量别用绝对路径,如果带参数不同容器路径解释可能不同 -->
<property name="LOG_HOME" value="/logs" />
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{50} %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/quartzPro/localhost.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/quartzPro/%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} 【%-5level】 【%logger{50}】 %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>
<!-- 将级别为“info”及大于“info”的日志信息传递给root处理,本身并不打印 -->
<root level="INFO">
<!-- root将级别为“INFO”及大于“INFO”的日志信息交给已经配置好的名为“Console”的appender处理,“Console”appender将信息打印到Console -->
<appender-ref ref="file" />
<!-- 标识这个appender将会添加到这个logger -->
<!-- <appender-ref ref="File" /> -->
</root>
</configuration>
@@ -0,0 +1,29 @@
package com.ifish.enums;
public enum PhoneTypeEnum {
ios("ios","ios"),
android("android","安卓");
private PhoneTypeEnum(String key,String value){
this.key = key;
this.value = value;
}
private String key;
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,108 @@
package com.ifish.jpush.push.model;
import java.util.HashSet;
import java.util.Set;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.common.DeviceType;
import com.ifish.jpush.utils.Preconditions;
public class Platform implements PushModel {
private static final String ALL = "all";
private final boolean all;
private final Set<DeviceType> deviceTypes;
private Platform(boolean all, Set<DeviceType> deviceTypes) {
this.all = all;
this.deviceTypes = deviceTypes;
}
public static Builder newBuilder() {
return new Builder();
}
public static Platform all() {
return newBuilder().setAll(true).build();
}
public static Platform android() {
return newBuilder().addDeviceType(DeviceType.Android).build();
}
public static Platform ios() {
return newBuilder().addDeviceType(DeviceType.IOS).build();
}
public static Platform winphone() {
return newBuilder().addDeviceType(DeviceType.WinPhone).build();
}
public static Platform android_ios() {
return newBuilder()
.addDeviceType(DeviceType.Android)
.addDeviceType(DeviceType.IOS)
.build();
}
public static Platform android_winphone() {
return newBuilder()
.addDeviceType(DeviceType.Android)
.addDeviceType(DeviceType.WinPhone)
.build();
}
public static Platform ios_winphone() {
return newBuilder()
.addDeviceType(DeviceType.IOS)
.addDeviceType(DeviceType.WinPhone)
.build();
}
public boolean isAll() {
return all;
}
@Override
public JsonElement toJSON() {
if (all) {
return new JsonPrimitive(ALL);
}
JsonArray json = new JsonArray();
for (DeviceType deviceType : deviceTypes) {
json.add(new JsonPrimitive(deviceType.value()));
}
return json;
}
public static class Builder {
private boolean all;
private Set<DeviceType> deviceTypes;
public Builder setAll(boolean all) {
this.all = all;
return this;
}
public Builder addDeviceType(DeviceType deviceType) {
if (null == deviceTypes) {
deviceTypes = new HashSet<DeviceType>();
}
deviceTypes.add(deviceType);
return this;
}
public Platform build() {
Preconditions.checkArgument(! (all && null != deviceTypes), "Since all is enabled, any platform should not be set.");
Preconditions.checkArgument(! (!all && null == deviceTypes), "No any deviceType is set.");
return new Platform(all, deviceTypes);
}
}
}
@@ -0,0 +1,14 @@
package com.ifish.jpush.device;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.ifish.jpush.common.resp.BaseResult;
public class TagAliasResult extends BaseResult {
@Expose public List<String> tags;
@Expose public String alias;
}
@@ -0,0 +1,107 @@
package com.ifish.tianqi;
import javax.crypto.Mac;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import javax.crypto.spec.SecretKeySpec;
public class javaDemo {
private static final char last2byte = (char) Integer.parseInt("00000011", 2);
private static final char last4byte = (char) Integer.parseInt("00001111", 2);
private static final char last6byte = (char) Integer.parseInt("00111111", 2);
private static final char lead6byte = (char) Integer.parseInt("11111100", 2);
private static final char lead4byte = (char) Integer.parseInt("11110000", 2);
private static final char lead2byte = (char) Integer.parseInt("11000000", 2);
private static final char[] encodeTable = new char[] { 'A', 'B', 'C', 'D',
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
public static String standardURLEncoder(String data, String key) {
byte[] byteHMAC = null;
String urlEncoder = "";
try {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec spec = new SecretKeySpec(key.getBytes(), "HmacSHA1");
mac.init(spec);
byteHMAC = mac.doFinal(data.getBytes());
if (byteHMAC != null) {
String oauth = encode(byteHMAC);
if (oauth != null) {
urlEncoder = URLEncoder.encode(oauth, "utf8");
}
}
} catch (InvalidKeyException e1) {
e1.printStackTrace();
} catch (Exception e2) {
e2.printStackTrace();
}
return urlEncoder;
}
public static String encode(byte[] from) {
StringBuffer to = new StringBuffer((int) (from.length * 1.34) + 3);
int num = 0;
char currentByte = 0;
for (int i = 0; i < from.length; i++) {
num = num % 8;
while (num < 8) {
switch (num) {
case 0:
currentByte = (char) (from[i] & lead6byte);
currentByte = (char) (currentByte >>> 2);
break;
case 2:
currentByte = (char) (from[i] & last6byte);
break;
case 4:
currentByte = (char) (from[i] & last4byte);
currentByte = (char) (currentByte << 2);
if ((i + 1) < from.length) {
currentByte |= (from[i + 1] & lead2byte) >>> 6;
}
break;
case 6:
currentByte = (char) (from[i] & last2byte);
currentByte = (char) (currentByte << 4);
if ((i + 1) < from.length) {
currentByte |= (from[i + 1] & lead4byte) >>> 4;
}
break;
}
to.append(encodeTable[currentByte]);
num += 6;
}
}
if (to.length() % 4 != 0) {
for (int i = 4 - to.length() % 4; i > 0; i--) {
to.append("=");
}
}
return to.toString();
}
public static void main(String[] args) {
try {
//需要加密的数据
String data = "http://open.weather.com.cn/data/?areaid=101020100&type=forecast_v&date=201603011100&appid=ee35072ca2850278";
//密钥
String key = "c4a99d_SmartWeatherAPI_a164e18";
String str = standardURLEncoder(data, key);
System.out.println(str);
// http://open.weather.com.cn/data/?areaid=101020100&type=forecast_v&date=201603011100&appid=ee3507&key=WCD90OiAMNfP3g5qhdhXiUnyBnA%3D
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
@@ -0,0 +1,128 @@
package com.ifish.jpush.push.model;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.common.ServiceHelper;
import com.ifish.jpush.utils.Preconditions;
public class Options implements PushModel {
private static final String SENDNO = "sendno";
private static final String OVERRIDE_MSG_ID = "override_msg_id";
private static final String TIME_TO_LIVE = "time_to_live";
private static final String APNS_PRODUCTION = "apns_production";
private static final String BIG_PUSH_DURATION = "big_push_duration";
private static final long NONE_TIME_TO_LIVE = -1;
private final int sendno;
private final long overrideMsgId;
private long timeToLive;
private boolean apnsProduction;
private int bigPushDuration; // minutes
private Options(int sendno, long overrideMsgId, long timeToLive, boolean apnsProduction,
int bigPushDuration) {
this.sendno = sendno;
this.overrideMsgId = overrideMsgId;
this.timeToLive = timeToLive;
this.apnsProduction = apnsProduction;
this.bigPushDuration = bigPushDuration;
}
public static Builder newBuilder() {
return new Builder();
}
public static Options sendno() {
return newBuilder().setSendno(ServiceHelper.generateSendno()).build();
}
public static Options sendno(int sendno) {
return newBuilder().setSendno(sendno).build();
}
public void setApnsProduction(boolean apnsProduction) {
this.apnsProduction = apnsProduction;
}
public void setTimeToLive(long timeToLive) {
this.timeToLive = timeToLive;
}
public void setBigPushDuration(int bigPushDuration) {
this.bigPushDuration = bigPushDuration;
}
public int getSendno() {
return this.sendno;
}
@Override
public JsonElement toJSON() {
JsonObject json = new JsonObject();
if (sendno > 0) {
json.add(SENDNO, new JsonPrimitive(sendno));
}
if (overrideMsgId > 0) {
json.add(OVERRIDE_MSG_ID, new JsonPrimitive(overrideMsgId));
}
if (timeToLive >= 0) {
json.add(TIME_TO_LIVE, new JsonPrimitive(timeToLive));
}
json.add(APNS_PRODUCTION, new JsonPrimitive(apnsProduction));
if (bigPushDuration > 0) {
json.add(BIG_PUSH_DURATION, new JsonPrimitive(bigPushDuration));
}
return json;
}
public static class Builder {
private int sendno = 0;
private long overrideMsgId = 0;
private long timeToLive = NONE_TIME_TO_LIVE;
private boolean apnsProduction = false;
private int bigPushDuration = 0;
public Builder setSendno(int sendno) {
this.sendno = sendno;
return this;
}
public Builder setOverrideMsgId(long overrideMsgId) {
this.overrideMsgId = overrideMsgId;
return this;
}
public Builder setTimeToLive(long timeToLive) {
this.timeToLive = timeToLive;
return this;
}
public Builder setApnsProduction(boolean apnsProduction) {
this.apnsProduction = apnsProduction;
return this;
}
public Builder setBigPushDuration(int bigPushDuration) {
this.bigPushDuration = bigPushDuration;
return this;
}
public Options build() {
Preconditions.checkArgument(sendno >= 0, "sendno should be greater than 0.");
Preconditions.checkArgument(overrideMsgId >= 0, "override_msg_id should be greater than 0.");
Preconditions.checkArgument(timeToLive >= NONE_TIME_TO_LIVE, "time_to_live should be greater than 0.");
Preconditions.checkArgument(bigPushDuration >= 0, "bigPushDuration should be greater than 0.");
if (sendno <= 0) {
sendno = ServiceHelper.generateSendno();
}
return new Options(sendno, overrideMsgId, timeToLive, apnsProduction, bigPushDuration);
}
}
}
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:quartz.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="quartzPro">
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<property name="context-root" value="quartzPro"/>
<property name="java-output-path" value="/quartzPro/target/classes"/>
</wb-module>
</project-modules>
@@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1
@@ -0,0 +1,10 @@
package com.ifish.jpush.common;
public enum TimeUnit {
HOUR,
DAY,
MONTH,
WEEK
}
@@ -0,0 +1,31 @@
package com.ifish.util;
import java.text.SimpleDateFormat;
import java.util.Date;
public class IfishUtil {
private static final String formatDate1 ="yyyy-MM-dd";
private static final String formatDate2 ="yyyy-MM-dd HH:mm:ss";
/**
* 格式化日期yyyy-MM-dd HH:mm:ss
* @param date
* @return
*/
public static String format2(Date date){
SimpleDateFormat format = new SimpleDateFormat(formatDate2);
return format.format(date);
}
/**
* 格式化日期yyyy-MM-dd
* @param date
* @return
*/
public static String format1(Date date){
SimpleDateFormat format = new SimpleDateFormat(formatDate1);
return format.format(date);
}
}
@@ -0,0 +1,148 @@
package com.ifish.jpush.push.model.audience;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.ifish.jpush.push.model.PushModel;
import com.ifish.jpush.utils.Preconditions;
public class Audience implements PushModel {
private static final String ALL = "all";
private final boolean all;
private final Set<AudienceTarget> targets;
private Audience(boolean all, Set<AudienceTarget> targets) {
this.all = all;
this.targets = targets;
}
public static Builder newBuilder() {
return new Builder();
}
public static Audience all() {
return newBuilder().setAll(true).build();
}
public static Audience tag(String... tagValue) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.TAG)
.addAudienceTargetValues(tagValue).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience tag(Collection<String> tagValues) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.TAG)
.addAudienceTargetValues(tagValues).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience tag_and(String... tagValue) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.TAG_AND)
.addAudienceTargetValues(tagValue).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience tag_and(Collection<String> tagValues) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.TAG_AND)
.addAudienceTargetValues(tagValues).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience alias(String... alias) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.ALIAS)
.addAudienceTargetValues(alias).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience alias(Collection<String> aliases) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.ALIAS)
.addAudienceTargetValues(aliases).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience segment(String... segment) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.SEGMENT)
.addAudienceTargetValues(segment).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience segment(Collection<String> segments) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.SEGMENT)
.addAudienceTargetValues(segments).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience registrationId(String... registrationId) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.REGISTRATION_ID)
.addAudienceTargetValues(registrationId).build();
return newBuilder().addAudienceTarget(target).build();
}
public static Audience registrationId(Collection<String> registrationIds) {
AudienceTarget target = AudienceTarget.newBuilder()
.setAudienceType(AudienceType.REGISTRATION_ID)
.addAudienceTargetValues(registrationIds).build();
return newBuilder().addAudienceTarget(target).build();
}
public boolean isAll() {
return this.all;
}
public JsonElement toJSON() {
if (all) {
return new JsonPrimitive(ALL);
}
// if not all, there will be target be set.
JsonObject json = new JsonObject();
if (null != targets) {
for (AudienceTarget target : targets) {
json.add(target.getAudienceTypeValue(), target.toJSON());
}
}
return json;
}
public static class Builder {
private boolean all = false;
private Set<AudienceTarget> audienceBuilder = null;
public Builder setAll(boolean all) {
this.all = all;
return this;
}
public Builder addAudienceTarget(AudienceTarget target) {
if (null == audienceBuilder) {
audienceBuilder = new HashSet<AudienceTarget>();
}
audienceBuilder.add(target);
return this;
}
public Audience build() {
Preconditions.checkArgument(! (all && null != audienceBuilder), "If audience is all, no any other audience may be set.");
Preconditions.checkArgument(! (all == false && null == audienceBuilder), "No any audience target is set.");
return new Audience(all, audienceBuilder);
}
}
}
@@ -0,0 +1,9 @@
package com.ifish.jpush.common.resp;
import com.google.gson.annotations.Expose;
public class BooleanResult extends DefaultResult {
@Expose public boolean result;
}
@@ -0,0 +1,68 @@
package com.ifish.jpush.examples;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ifish.jpush.JPushClient;
import com.ifish.jpush.common.resp.APIConnectionException;
import com.ifish.jpush.common.resp.APIRequestException;
import com.ifish.jpush.device.OnlineStatus;
import com.ifish.jpush.device.TagAliasResult;
public class DevcieExample {
protected static final Logger LOG = LoggerFactory.getLogger(DevcieExample.class);
private static final String appKey = "dd1066407b044738b6479275";
private static final String masterSecret = "6b135be0037a5c1e693c3dfa";
private static final String TAG1 = "tag1";
private static final String ALIAS1 = "alias1";
private static final String ALIAS2 = "alias2";
private static final String REGISTRATION_ID1 = "0900e8d85ef";
private static final String REGISTRATION_ID2 = "0a04ad7d8b4";
private static JPushClient jpushClient = new JPushClient(masterSecret, appKey);
public static void main(String[] args) {
// testGetDeviceTagAlias();
testGetUserOnlineStatus();
}
public static void testGetDeviceTagAlias() {
try {
TagAliasResult result = jpushClient.getDeviceTagAlias(REGISTRATION_ID1);
LOG.info(result.alias);
LOG.info(result.tags.toString());
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
public static void testGetUserOnlineStatus() {
try {
Map<String, OnlineStatus> result = jpushClient.getUserOnlineStatus(REGISTRATION_ID1, REGISTRATION_ID2);
LOG.info(result.get(REGISTRATION_ID1).toString());
LOG.info(result.get(REGISTRATION_ID2).toString());
} catch (APIConnectionException e) {
LOG.error("Connection error. Should retry later. ", e);
} catch (APIRequestException e) {
LOG.error("Error response from JPush server. Should review and fix it. ", e);
LOG.info("HTTP Status: " + e.getStatus());
LOG.info("Error Code: " + e.getErrorCode());
LOG.info("Error Message: " + e.getErrorMessage());
}
}
}
@@ -0,0 +1,31 @@
package com.ifish.jpush.schedule;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.ifish.jpush.common.resp.BaseResult;
public class ScheduleListResult extends BaseResult{
@Expose int total_count;
@Expose int total_pages;
@Expose int page;
@Expose List<ScheduleResult> schedules;
public int getTotal_count() {
return total_count;
}
public int getTotal_pages() {
return total_pages;
}
public int getPage() {
return page;
}
public List<ScheduleResult> getSchedules() {
return schedules;
}
}
@@ -0,0 +1,12 @@
package com.ifish.jpush.common.resp;
public interface IRateLimiting {
public int getRateLimitQuota();
public int getRateLimitRemaining();
public int getRateLimitReset();
}

Some files were not shown because too many files have changed in this diff Show More