初始化
This commit is contained in:
+23
@@ -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,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,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
|
||||
@@ -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,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
|
||||
@@ -0,0 +1 @@
|
||||
12
|
||||
@@ -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>
|
||||
Binary file not shown.
@@ -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
Reference in New Issue
Block a user