Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ec0d932
Begin to add IM client - implement IM Message builder from/to
Feb 14, 2015
f29e667
ongoing: im client
Feb 26, 2015
57c1911
Refactored msg json structure - from and to
Feb 27, 2015
50cab54
add jpush im api client
Liuchy1 Apr 29, 2015
2a03c0e
Merge pull request #5 from Liuchy1/master
Liuchy1 Apr 29, 2015
f8f2b3a
modify Readme add IM API sample
Liuchy1 Apr 29, 2015
a85ae4d
Merge pull request #6 from Liuchy1/master
Liuchy1 Apr 29, 2015
8d2b57e
add log for api example
Liuchy1 May 6, 2015
5ba489b
add log for jmessage api test case
Liuchy1 May 6, 2015
668ca6b
modify Readme fix print log
Liuchy1 May 6, 2015
397f02f
Merge pull request #7 from Liuchy1/master
Liuchy1 May 6, 2015
a132d9c
remove jmessage api
Liuchy1 May 28, 2015
db8820f
modify ResponseWrapper setErrorObject add exception process
Liuchy1 May 29, 2015
15aaceb
Merge pull request #8 from Liuchy1/master
Liuchy1 May 29, 2015
ef4e8ca
modify pom.xml add SNAPSHOT
Liuchy1 May 29, 2015
0974e07
Merge pull request #9 from Liuchy1/master
Liuchy1 May 29, 2015
74632b1
remove im impl from this project
Liuchy1 Jun 23, 2015
97cdd70
remove im test from this project
Liuchy1 Jun 23, 2015
cb99966
modify README add code style
Liuchy1 Jun 23, 2015
aef6bc5
Merge pull request #11 from Liuchy1/master
Liuchy1 Jun 23, 2015
42ff2df
modify ReportClient change msgid from int to long
Liuchy1 Jun 24, 2015
62a3dec
Merge pull request #12 from Liuchy1/master
Liuchy1 Jun 24, 2015
ad69a1f
modify Readme dependency version
Liuchy1 Jun 24, 2015
d2107cc
Merge pull request #13 from Liuchy1/master
Liuchy1 Jun 24, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.2.3</version>
<version>3.2.5</version>
</dependency>
```
### jar 包方式
Expand Down Expand Up @@ -86,7 +86,7 @@

> 以下片断来自项目代码里的文件:example / cn.jpush.api.examples.PushExample

```
```Java
JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3);

// For push, all you need do is to build PushPayload object.
Expand Down Expand Up @@ -114,15 +114,15 @@

* 快捷地构建推送对象:所有平台,所有设备,内容为 ALERT 的通知。

```
```Java
public static PushPayload buildPushObject_all_all_alert() {
return PushPayload.alertAll(ALERT);
}
```

* 构建推送对象:所有平台,推送目标是别名为 "alias1",通知内容为 ALERT。

```
```Java
public static PushPayload buildPushObject_all_alias_alert() {
return PushPayload.newBuilder()
.setPlatform(Platform.all())
Expand All @@ -134,7 +134,7 @@

* 构建推送对象:平台是 Android,目标是 tag 为 "tag1" 的设备,内容是 Android 通知 ALERT,并且标题为 TITLE。

```
```Java
public static PushPayload buildPushObject_android_tag_alertWithTitle() {
return PushPayload.newBuilder()
.setPlatform(Platform.android())
Expand All @@ -146,7 +146,7 @@

* 构建推送对象:平台是 iOS,推送目标是 "tag1", "tag_all" 的并集,推送内容同时包括通知与消息 - 通知信息是 ALERT,角标数字为 5,通知声音为 "happy",并且附加字段 from = "JPush";消息内容是 MSG_CONTENT。通知是 APNs 推送通道的,消息是 JPush 应用内消息通道的。APNs 的推送环境是“生产”(如果不显式设置的话,Library 会默认指定为开发)

```
```Java
public static PushPayload buildPushObject_ios_tagAnd_alertWithExtrasAndMessage() {
return PushPayload.newBuilder()
.setPlatform(Platform.ios())
Expand All @@ -169,7 +169,7 @@

* 构建推送对象:平台是 Andorid 与 iOS,推送目标是 ("tag1" 与 "tag2" 的交集)并("alias1" 与 "alias2" 的交集),推送内容是 - 内容为 MSG_CONTENT 的消息,并且附加字段 from = JPush。

```
```Java
public static PushPayload buildPushObject_ios_audienceMore_messageWithExtras() {
return PushPayload.newBuilder()
.setPlatform(Platform.android_ios())
Expand All @@ -189,7 +189,7 @@

> 以下片断来自项目代码里的文件:example / cn.jpush.api.examples.ReportsExample

```
```Java
JPushClient jpushClient = new JPushClient(masterSecret, appKey);
try {
ReceivedsResult result = jpushClient.getReportReceiveds("1942377665");
Expand All @@ -212,7 +212,7 @@

> 以下片断来自项目代码里的文件:example / cn.jpush.api.examples.DeviceExample

```
```Java
try {
TagAliasResult result = jpushClient.getDeviceTagAlias(REGISTRATION_ID1);

Expand All @@ -229,4 +229,3 @@
LOG.info("Error Message: " + e.getErrorMessage());
}
```

2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.2.4-SNAPSHOT</version>
<version>3.2.5-SNAPSHOT</version>
<packaging>jar</packaging>
<url>https://github.com/jpush/jpush-api-java-client</url>
<name>JPush API Java Client</name>
Expand Down
34 changes: 31 additions & 3 deletions src/main/java/cn/jpush/api/common/ServiceHelper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cn.jpush.api.common;

import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;
Expand All @@ -9,9 +10,12 @@

import com.google.gson.JsonArray;
import com.google.gson.JsonPrimitive;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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";

Expand All @@ -20,8 +24,15 @@ public class ServiceHelper {
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 SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

static {
DATE_FORMAT.setLenient(false);
}

public static boolean isValidIntBadge(int intBadge) {
if (intBadge >= 0 && intBadge <= MAX_BADGE_NUMBER) {
return true;
Expand All @@ -37,7 +48,7 @@ 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)) {
Expand All @@ -63,4 +74,21 @@ public static JsonArray fromSet(Set<String> sets) {
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;
}
DATE_FORMAT.parse(birthday);
} catch (Exception e) {
LOG.error("incorrect date format. " + birthday, e);
return false;
}
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import cn.jpush.api.utils.Preconditions;

public class HttpProxy {
private static final Logger LOG = LoggerFactory.getLogger(NativeHttpClient.class);
private static final Logger LOG = LoggerFactory.getLogger(HttpProxy.class);

private String host;
private int port;
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/cn/jpush/api/common/connection/IHttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public interface IHttpClient {
public enum RequestMethod {
GET,
POST,
PUT,
DELETE
}

Expand Down Expand Up @@ -63,4 +64,6 @@ public ResponseWrapper sendPost(String url, String content)
throws APIConnectionException, APIRequestException;


public ResponseWrapper sendPut(String url, String content)
throws APIConnectionException, APIRequestException;
}
40 changes: 30 additions & 10 deletions src/main/java/cn/jpush/api/common/connection/NativeHttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@
import cn.jpush.api.common.resp.APIRequestException;
import cn.jpush.api.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";
Expand All @@ -35,6 +44,9 @@ public class NativeHttpClient implements IHttpClient {
private String _authCode;
private HttpProxy _proxy;

/**
* 默认的重连次数是 3
*/
public NativeHttpClient(String authCode) {
this(authCode, DEFAULT_MAX_RETRY_TIMES, null);
}
Expand All @@ -46,6 +58,11 @@ public NativeHttpClient(String authCode, int maxRetryTimes, HttpProxy proxy) {
this._authCode = authCode;
this._proxy = proxy;

if ( null != _proxy && _proxy.isAuthenticationNeeded()) {
Authenticator.setDefault(new SimpleProxyAuthenticator(
_proxy.getUsername(), _proxy.getPassword()));
}

initSSL();
}

Expand All @@ -63,6 +80,11 @@ 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 {
Expand Down Expand Up @@ -108,8 +130,6 @@ private ResponseWrapper _doRequest(String url, String content,
conn = (HttpURLConnection) aUrl.openConnection(_proxy.getNetProxy());
if (_proxy.isAuthenticationNeeded()) {
conn.setRequestProperty("Proxy-Authorization", _proxy.getProxyAuthorization());
Authenticator.setDefault(new SimpleProxyAuthenticator(
_proxy.getUsername(), _proxy.getPassword()));
}
} else {
conn = (HttpURLConnection) aUrl.openConnection();
Expand All @@ -124,14 +144,14 @@ private ResponseWrapper _doRequest(String url, String content,
conn.setRequestProperty("Accept-Charset", CHARSET);
conn.setRequestProperty("Charset", CHARSET);
conn.setRequestProperty("Authorization", _authCode);

conn.setRequestProperty("Content-Type", CONTENT_TYPE_JSON);

if (RequestMethod.GET == method) {
conn.setDoOutput(false);
} else if (RequestMethod.DELETE == method) {
conn.setDoOutput(false);
} else if (RequestMethod.POST == method) {
} else if (RequestMethod.POST == method || RequestMethod.PUT == method) {
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", CONTENT_TYPE_JSON);
byte[] data = content.getBytes(CHARSET);
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
out = conn.getOutputStream();
Expand All @@ -141,7 +161,7 @@ private ResponseWrapper _doRequest(String url, String content,

int status = conn.getResponseCode();
InputStream in = null;
if (status == 200) {
if (status / 100 == 2) {
in = conn.getInputStream();
} else {
in = conn.getErrorStream();
Expand All @@ -165,11 +185,11 @@ private ResponseWrapper _doRequest(String url, String content,
String reset = conn.getHeaderField(RATE_LIMIT_Reset);
wrapper.setRateLimit(quota, remaining, reset);

if (status == 200) {
LOG.debug("Succeed to get response - 200 OK");
if (status >= 200 && status < 300) {
LOG.debug("Succeed to get response OK - responseCode:" + status);
LOG.debug("Response Content - " + responseContent);

} else if (status > 200 && status < 400) {
} else if (status >= 300 && status < 400) {
LOG.warn("Normal response but unexpected - responseCode:" + status + ", responseContent:" + responseContent);

} else {
Expand All @@ -185,7 +205,7 @@ private ResponseWrapper _doRequest(String url, String content,
wrapper.setErrorObject();
break;
case 403:
LOG.error("Request is forbidden! Maybe your appkey is listed in blacklist?");
LOG.error("Request is forbidden! Maybe your appkey is listed in blacklist or your params is invalid.");
wrapper.setErrorObject();
break;
case 410:
Expand Down
20 changes: 18 additions & 2 deletions src/main/java/cn/jpush/api/common/resp/ResponseWrapper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cn.jpush.api.common.resp;

import com.google.gson.JsonSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -35,11 +36,26 @@ public void setRateLimit(String quota, String remaining, String reset) {
}

public void setErrorObject() {
error = _gson.fromJson(responseContent, ErrorObject.class);
try {
error = _gson.fromJson(responseContent, ErrorObject.class);
} catch (JsonSyntaxException e) {
int index = responseContent.indexOf("error");
if( -1 != index ) {
int from = responseContent.indexOf("{", index);
int to = responseContent.indexOf("}", from);
String errorStr = responseContent.substring(from, to + 1);
error = new ErrorObject();
try {
error.error = _gson.fromJson(errorStr, ErrorEntity.class);
} catch (JsonSyntaxException e1) {
LOG.error("unknown response content:" + responseContent, e);
}
}
}
}

public boolean isServerResponse() {
if (responseCode == 200) return true;
if (responseCode / 100 == 2) return true;
if (responseCode > 0 && null != error && error.error.code > 0) return true;
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/cn/jpush/api/report/ReportClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ public static void checkMsgids(String msgIds) {
for (String s : splits) {
s = s.trim();
if (!StringUtils.isEmpty(s)) {
Integer.parseInt(s);
Long.parseLong(s);
}
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Every msg_id should be valid Integer number which splits by ','");
throw new IllegalArgumentException("Every msg_id should be valid Long number which splits by ','");
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/main/java/cn/jpush/api/utils/StringUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,17 @@ 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;
}

}