diff --git a/README.md b/README.md index 0ddcfe29..318291db 100644 --- a/README.md +++ b/README.md @@ -358,6 +358,34 @@ try { } ``` +### Image Client 样例 + +> 以下片断来自项目代码里面的文件:example / cn.jpush.api.examples.ImageExample +* 支持通过URL或者文件来上传图片 +```Java + public static void testUploadImageByUrl() throws APIConnectionException, APIRequestException { + ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY); + ImageUrlPayload payload = ImageUrlPayload.newBuilder() + .setImageType(ImageType.LARGE_ICON) + .setImageUrl("http://xxx.com/image/a.jpg") + .build(); + ImageUploadResult imageUploadResult = client.uploadImage(payload); + String mediaId = imageUploadResult.getMediaId(); + } + + public static void testUploadImageByFile() { + ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY); + ImageFilePayload payload = ImageFilePayload.newBuilder() + .setImageType(ImageType.BIG_PICTURE) + // 本地文件路径 + .setOppoFileName("/MyDir/a.jpg") + .setXiaomiFileName("/MyDir/a.jpg") + .build(); + ImageUploadResult imageUploadResult = client.uploadImage(payload); + String mediaId = imageUploadResult.getMediaId(); + } +``` + ### Weblogic 使用Java SDK Weblogic在使用jpush-api-java-client时需要注意的一些事项。 diff --git a/example/main/java/cn/jpush/api/examples/ImageExample.java b/example/main/java/cn/jpush/api/examples/ImageExample.java new file mode 100644 index 00000000..a29ad866 --- /dev/null +++ b/example/main/java/cn/jpush/api/examples/ImageExample.java @@ -0,0 +1,56 @@ +package cn.jpush.api.image; + +import cn.jiguang.common.resp.APIConnectionException; +import cn.jiguang.common.resp.APIRequestException; +import cn.jpush.api.image.model.ImageFilePayload; +import cn.jpush.api.image.model.ImageType; +import cn.jpush.api.image.model.ImageUploadResult; +import cn.jpush.api.image.model.ImageUrlPayload; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ImageExample { + protected static final Logger LOG = LoggerFactory.getLogger(ImageExample.class); + + // demo App defined in resources/jpush-api.conf + protected static final String APP_KEY = "e4ceeaf7a53ad745dd4728f2"; + protected static final String MASTER_SECRET = "1582b986adeaf48ceec1e354"; + protected static final String GROUP_PUSH_KEY = "2c88a01e073a0fe4fc7b167c"; + protected static final String GROUP_MASTER_SECRET = "b11314807507e2bcfdeebe2e"; + + 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 long sendCount = 0; + private static long sendTotalTime = 0; + + public static void main(String[] args) throws APIConnectionException, APIRequestException { + testUploadImageByFile(); + testUploadImageByUrl(); + } + + public static void testUploadImageByUrl() throws APIConnectionException, APIRequestException { + ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY); + ImageUrlPayload payload = ImageUrlPayload.newBuilder() + .setImageType(ImageType.LARGE_ICON) + .setImageUrl("http://xxx.com/image/a.jpg") + .build(); + ImageUploadResult imageUploadResult = client.uploadImage(payload); + String mediaId = imageUploadResult.getMediaId(); + } + + public static void testUploadImageByFile() { + ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY); + ImageFilePayload payload = ImageFilePayload.newBuilder() + .setImageType(ImageType.BIG_PICTURE) + // 本地文件路径 + .setOppoFileName("/MyDir/a.jpg") + .setXiaomiFileName("/MyDir/a.jpg") + .build(); + ImageUploadResult imageUploadResult = client.uploadImage(payload); + String mediaId = imageUploadResult.getMediaId(); + } +} + diff --git a/pom.xml b/pom.xml index fdc07020..f8f5a173 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ cn.jpush.api jpush-client - 3.4.7 + 3.4.8 jar https://github.com/jpush/jpush-api-java-client JPush API Java Client @@ -51,7 +51,7 @@ cn.jpush.api jiguang-common - 1.1.9 + 1.1.10 org.apache.httpcomponents @@ -117,6 +117,18 @@ 2.0.0 test + + org.mockito + mockito-core + 1.10.19 + test + + + org.hamcrest + hamcrest-core + 2.2 + test + @@ -294,7 +306,6 @@ - ossrh diff --git a/src/main/java/cn/jpush/api/file/FileClient.java b/src/main/java/cn/jpush/api/file/FileClient.java index 601805cb..b7e11a2e 100644 --- a/src/main/java/cn/jpush/api/file/FileClient.java +++ b/src/main/java/cn/jpush/api/file/FileClient.java @@ -56,7 +56,7 @@ public FileUploadResult uploadFile(FileType type, String filename) String url = _baseUrl + _filesPath + "/" + typeStr; Map fileMap = new HashMap<>(); fileMap.put("filename", filename); - String response = client.formUpload(url, null, fileMap, null); + String response = client.formUploadByPost(url, null, fileMap, null); LOG.info("uploadFile:{}", response); return _gson.fromJson(response, new TypeToken() { diff --git a/src/main/java/cn/jpush/api/image/ImageClient.java b/src/main/java/cn/jpush/api/image/ImageClient.java new file mode 100644 index 00000000..87a2acd4 --- /dev/null +++ b/src/main/java/cn/jpush/api/image/ImageClient.java @@ -0,0 +1,162 @@ +package cn.jpush.api.image; + +import cn.jiguang.common.ClientConfig; +import cn.jiguang.common.ServiceHelper; +import cn.jiguang.common.connection.HttpProxy; +import cn.jiguang.common.connection.IHttpClient; +import cn.jiguang.common.connection.NativeHttpClient; +import cn.jiguang.common.resp.APIConnectionException; +import cn.jiguang.common.resp.APIRequestException; +import cn.jiguang.common.resp.ResponseWrapper; +import cn.jiguang.common.utils.Preconditions; +import cn.jiguang.common.utils.StringUtils; +import cn.jpush.api.image.model.ImageFilePayload; +import cn.jpush.api.image.model.ImageSource; +import cn.jpush.api.image.model.ImageUploadResult; +import cn.jpush.api.image.model.ImageUrlPayload; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonSyntaxException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +/** + * Provide the ability to upload images to the Jiguang server. Only images in JPG, JPEG and PNG format are supported. + * + * @author fuyx + * @version 2020-12-14 + */ +public class ImageClient { + + protected static final Logger LOG = LoggerFactory.getLogger(ImageClient.class); + + private IHttpClient _httpClient; + private String _baseUrl; + private String _imagesPath; + private Gson _gson = new Gson(); + + public ImageClient(String masterSecret, String appKey) { + this(masterSecret, appKey, null, ClientConfig.getInstance()); + } + + public ImageClient(String masterSecret, String appKey, HttpProxy proxy, ClientConfig conf) { + _baseUrl = (String) conf.get(ClientConfig.PUSH_HOST_NAME); + _imagesPath = (String) conf.get(ClientConfig.V3_IMAGES_PATH); + String authCode = ServiceHelper.getBasicAuthorization(appKey, masterSecret); + this._httpClient = new NativeHttpClient(authCode, proxy, conf); + } + + /** + * Upload image by url. Require at least one non-null url. + */ + public ImageUploadResult uploadImage(ImageUrlPayload imageUrlPayload) + throws APIConnectionException, APIRequestException { + Preconditions.checkArgument(imageUrlPayload.getImageType() != null, "Image type should not be null"); + checkImageUrlPayload(imageUrlPayload); + NativeHttpClient client = (NativeHttpClient) _httpClient; + String url = _baseUrl + _imagesPath + "/" + ImageSource.URL.value(); + JsonElement jsonElement = imageUrlPayload.toJSON(); + String content = _gson.toJson(jsonElement); + ResponseWrapper responseWrapper = client.sendPost(url, content); + if (responseWrapper.responseCode != 200) { + LOG.error("upload image failed: {}", responseWrapper); + } + ImageUploadResult imageUploadResult = _gson.fromJson(responseWrapper.responseContent, ImageUploadResult.class); + + LOG.info("upload image result:{}", imageUploadResult); + return imageUploadResult; + } + + /** + * Upload image by file. Require at least 1 non-null fileName. Currently only support Xiaomi and OPPO + */ + public ImageUploadResult uploadImage(ImageFilePayload imageFilePayload) { + Preconditions.checkArgument(imageFilePayload.getImageType() != null, "Image type should not be null"); + checkImageFilePayload(imageFilePayload); + NativeHttpClient client = (NativeHttpClient) _httpClient; + String url = _baseUrl + _imagesPath + "/" + ImageSource.FILE.value(); + + Map textMap = new HashMap<>(); + textMap.put("image_type", String.valueOf(imageFilePayload.getImageType().value())); + + Map fileMap = imageFilePayload.toFileMap(); + LOG.debug("upload fileMap: {}", fileMap); + String response = client.formUploadByPost(url, textMap, fileMap, null); + LOG.debug("upload image result: {}", response); + ImageUploadResult imageUploadResult; + try { + imageUploadResult = _gson.fromJson(response, ImageUploadResult.class); + } catch (JsonSyntaxException e) { + LOG.error("could not parse response: {}", response); + throw new IllegalStateException("could not parse response", e); + } + LOG.info("upload image result:{}", imageUploadResult); + return imageUploadResult; + } + + /** + * Modify image by url. Require at least one non-null url. + */ + public ImageUploadResult modifyImage(String mediaId, ImageUrlPayload imageUrlPayload) + throws APIConnectionException, APIRequestException { + Preconditions.checkArgument(StringUtils.isNotEmpty(mediaId), "mediaId should not be empty"); + checkImageUrlPayload(imageUrlPayload); + NativeHttpClient client = (NativeHttpClient) _httpClient; + String url = _baseUrl + _imagesPath + "/" + ImageSource.URL.value() + "/" + mediaId; + JsonElement jsonElement = imageUrlPayload.toJSON(); + String content = _gson.toJson(jsonElement); + ResponseWrapper responseWrapper = client.sendPut(url, content); + if (responseWrapper.responseCode != 200) { + LOG.error("upload image failed: {}", responseWrapper); + } + ImageUploadResult imageUploadResult = _gson.fromJson(responseWrapper.responseContent, ImageUploadResult.class); + + LOG.info("upload image result:{}", imageUploadResult); + return imageUploadResult; + } + + /** + * Modify image by file. Require at least 1 non-null fileName. Currently only support Xiaomi and OPPO + */ + public ImageUploadResult modifyImage(String mediaId, ImageFilePayload imageFilePayload) { + Preconditions.checkArgument(StringUtils.isNotEmpty(mediaId), "mediaId should not be empty"); + checkImageFilePayload(imageFilePayload); + NativeHttpClient client = (NativeHttpClient) _httpClient; + String url = _baseUrl + _imagesPath + "/" + ImageSource.FILE.value() + "/" + mediaId; + + Map fileMap = imageFilePayload.toFileMap(); + LOG.debug("upload image fileMap: {}", fileMap); + String response = client.formUploadByPut(url, null, fileMap, null); + LOG.debug("upload image result: {}", response); + ImageUploadResult imageUploadResult; + try { + imageUploadResult = _gson.fromJson(response, ImageUploadResult.class); + } catch (JsonSyntaxException e) { + LOG.error("could not parse response: {}", response); + throw new IllegalStateException("could not parse response", e); + } + LOG.info("upload image result:{}", imageUploadResult); + return imageUploadResult; + } + + private void checkImageUrlPayload(ImageUrlPayload imageUrlPayload) { + boolean anyUrlNotEmpty = StringUtils.isNotEmpty(imageUrlPayload.getImageUrl()) + || StringUtils.isNotEmpty(imageUrlPayload.getFcmImageUrl()) + || StringUtils.isNotEmpty(imageUrlPayload.getHuaweiImageUrl()) + || StringUtils.isNotEmpty(imageUrlPayload.getOppoImageUrl()) + || StringUtils.isNotEmpty(imageUrlPayload.getXiaomiImageUrl()) + || StringUtils.isNotEmpty(imageUrlPayload.getJiguangImageUrl()) ; + Preconditions.checkArgument(anyUrlNotEmpty, "Require at least 1 non-empty url"); + } + + private void checkImageFilePayload(ImageFilePayload imageFilePayload) { + boolean anyFileNotEmpty = StringUtils.isNotEmpty(imageFilePayload.getOppoFileName() ) + || StringUtils.isNotEmpty(imageFilePayload.getXiaomiFileName() ); + Preconditions.checkArgument(anyFileNotEmpty, "Require at least 1 non-empty fileName. Currently only support Xiaomi and OPPO"); + } + + +} diff --git a/src/main/java/cn/jpush/api/image/model/ImageFilePayload.java b/src/main/java/cn/jpush/api/image/model/ImageFilePayload.java new file mode 100644 index 00000000..7a4be086 --- /dev/null +++ b/src/main/java/cn/jpush/api/image/model/ImageFilePayload.java @@ -0,0 +1,105 @@ +package cn.jpush.api.image.model; + +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +@Data +public class ImageFilePayload { + private static final String IMAGE_TYPE = "image_type"; + private static final String OPPO_IMAGE_FILE = "oppo_file"; + private static final String XIAOMI_IMAGE_FILE = "xiaomi_file"; + private static final String HUAWEI_IMAGE_FILE = "huawei_file"; + private static final String FCM_IMAGE_FILE = "fcm_file"; + private static final String JIGUANG_IMAGE_FILE = "jiguang_file"; + + private ImageType imageType; + private String oppoFileName; + private String xiaomiFileName; + private String huaweiFileName; + private String fcmFileName; + private String jiguangFileName; + + public Map toFileMap() { + HashMap fileMap = new HashMap<>(); + if (null != oppoFileName) { + fileMap.put(OPPO_IMAGE_FILE, oppoFileName); + } + if (null != xiaomiFileName) { + fileMap.put(XIAOMI_IMAGE_FILE, xiaomiFileName); + } + if (null != huaweiFileName) { + fileMap.put(HUAWEI_IMAGE_FILE, huaweiFileName); + } + if (null != fcmFileName) { + fileMap.put(FCM_IMAGE_FILE, fcmFileName); + } + if (null != jiguangFileName) { + fileMap.put(JIGUANG_IMAGE_FILE, jiguangFileName); + } + return fileMap; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + private ImageType imageType; + private String oppoFileName; + private String xiaomiFileName; + private String huaweiFileName; + private String fcmFileName; + private String jiguangFileName; + + private Builder() { + } + + public static Builder builder() { + return new Builder(); + } + + public Builder setImageType(ImageType imageType) { + this.imageType = imageType; + return this; + } + + public Builder setOppoFileName(String oppoFileName) { + this.oppoFileName = oppoFileName; + return this; + } + + public Builder setXiaomiFileName(String xiaomiFileName) { + this.xiaomiFileName = xiaomiFileName; + return this; + } + + public Builder setHuaweiFileName(String huaweiFileName) { + this.huaweiFileName = huaweiFileName; + return this; + } + + public Builder setFcmFileName(String fcmFileName) { + this.fcmFileName = fcmFileName; + return this; + } + + public Builder setJiguangFileName(String jiguangFileName) { + this.jiguangFileName = jiguangFileName; + return this; + } + + public ImageFilePayload build() { + ImageFilePayload imageFilePayload = new ImageFilePayload(); + imageFilePayload.setImageType(imageType); + imageFilePayload.setOppoFileName(oppoFileName); + imageFilePayload.setXiaomiFileName(xiaomiFileName); + imageFilePayload.setHuaweiFileName(huaweiFileName); + imageFilePayload.setFcmFileName(fcmFileName); + imageFilePayload.setJiguangFileName(jiguangFileName); + return imageFilePayload; + } + } + +} \ No newline at end of file diff --git a/src/main/java/cn/jpush/api/image/model/ImageSource.java b/src/main/java/cn/jpush/api/image/model/ImageSource.java new file mode 100644 index 00000000..5bd847c1 --- /dev/null +++ b/src/main/java/cn/jpush/api/image/model/ImageSource.java @@ -0,0 +1,27 @@ +package cn.jpush.api.image.model; + +/** + * @author fuyx + * @version 2020-12-14 + */ +public enum ImageSource { + + /** + * Network Resource + */ + URL("byurls"), + /** + * File Resource + */ + FILE("byfiles"); + + private final String value; + + ImageSource(final String value) { + this.value = value; + } + + public String value() { + return this.value; + } +} diff --git a/src/main/java/cn/jpush/api/image/model/ImageType.java b/src/main/java/cn/jpush/api/image/model/ImageType.java new file mode 100644 index 00000000..24b37425 --- /dev/null +++ b/src/main/java/cn/jpush/api/image/model/ImageType.java @@ -0,0 +1,27 @@ +package cn.jpush.api.image.model; + +import com.google.gson.annotations.SerializedName; + +/** + * @author fuyx + * @version 2020-12-14 + */ +public enum ImageType { + + @SerializedName("1") + BIG_PICTURE(1), + @SerializedName("2") + LARGE_ICON(2), + @SerializedName("3") + SMALL_ICON(3); + + private final int value; + + ImageType(final int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/src/main/java/cn/jpush/api/image/model/ImageUploadResult.java b/src/main/java/cn/jpush/api/image/model/ImageUploadResult.java new file mode 100644 index 00000000..2435eb22 --- /dev/null +++ b/src/main/java/cn/jpush/api/image/model/ImageUploadResult.java @@ -0,0 +1,31 @@ +package cn.jpush.api.image.model; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +@Data +public class ImageUploadResult { + + @SerializedName("media_id") + private String mediaId; + @SerializedName("oppo_image_url") + private String oppoImageUrl; + @SerializedName("xiaomi_image_url") + private String xiaomiImageUrl; + @SerializedName("huawei_image_url") + private String huaweiImageUrl; + @SerializedName("fcm_image_url") + private String fcmImageUrl; + @SerializedName("jiguang_image_url") + private String jiguangImageUrl; + @SerializedName("error") + private Error error; + + @Data + public static class Error { + @SerializedName("message") + private String message; + @SerializedName("code") + private int code; + } +} \ No newline at end of file diff --git a/src/main/java/cn/jpush/api/image/model/ImageUrlPayload.java b/src/main/java/cn/jpush/api/image/model/ImageUrlPayload.java new file mode 100644 index 00000000..62cd0626 --- /dev/null +++ b/src/main/java/cn/jpush/api/image/model/ImageUrlPayload.java @@ -0,0 +1,119 @@ +package cn.jpush.api.image.model; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import lombok.Data; + +@Data +public class ImageUrlPayload { + private static final String IMAGE_TYPE = "image_type"; + private static final String IMAGE_URL = "image_url"; + private static final String OPPO_IMAGE_URL = "oppo_image_url"; + private static final String XIAOMI_IMAGE_URL = "xiaomi_image_url"; + private static final String HUAWEI_IMAGE_URL = "huawei_image_url"; + private static final String FCM_IMAGE_URL = "fcm_image_url"; + private static final String JIGUANG_IMAGE_URL = "jiguang_image_url"; + + private ImageType imageType; + private String imageUrl; + private String oppoImageUrl; + private String xiaomiImageUrl; + private String huaweiImageUrl; + private String fcmImageUrl; + private String jiguangImageUrl; + + public JsonElement toJSON() { + JsonObject json = new JsonObject(); + if (null != imageType) { + json.addProperty(IMAGE_TYPE, imageType.value()); + } + if (null != imageUrl) { + json.addProperty(IMAGE_URL, imageUrl); + } + if (null != oppoImageUrl) { + json.addProperty(OPPO_IMAGE_URL, oppoImageUrl); + } + if (null != xiaomiImageUrl) { + json.addProperty(XIAOMI_IMAGE_URL, xiaomiImageUrl); + } + if (null != huaweiImageUrl) { + json.addProperty(HUAWEI_IMAGE_URL, huaweiImageUrl); + } + if (null != fcmImageUrl) { + json.addProperty(FCM_IMAGE_URL, fcmImageUrl); + } + if (null != jiguangImageUrl) { + json.addProperty(JIGUANG_IMAGE_URL, jiguangImageUrl); + } + return json; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + private ImageType imageType; + private String imageUrl; + private String oppoImageUrl; + private String xiaomiImageUrl; + private String huaweiImageUrl; + private String fcmImageUrl; + private String jiguangImageUrl; + + private Builder() { + } + + public static Builder builder() { + return new Builder(); + } + + public Builder setImageType(ImageType imageType) { + this.imageType = imageType; + return this; + } + + public Builder setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + return this; + } + + public Builder setOppoImageUrl(String oppoImageUrl) { + this.oppoImageUrl = oppoImageUrl; + return this; + } + + public Builder setXiaomiImageUrl(String xiaomiImageUrl) { + this.xiaomiImageUrl = xiaomiImageUrl; + return this; + } + + public Builder setHuaweiImageUrl(String huaweiImageUrl) { + this.huaweiImageUrl = huaweiImageUrl; + return this; + } + + public Builder setFcmImageUrl(String fcmImageUrl) { + this.fcmImageUrl = fcmImageUrl; + return this; + } + + public Builder setJiguangImageUrl(String jiguangImageUrl) { + this.jiguangImageUrl = jiguangImageUrl; + return this; + } + + public ImageUrlPayload build() { + ImageUrlPayload imageUrlPayload = new ImageUrlPayload(); + imageUrlPayload.setImageType(imageType); + imageUrlPayload.setImageUrl(imageUrl); + imageUrlPayload.setOppoImageUrl(oppoImageUrl); + imageUrlPayload.setXiaomiImageUrl(xiaomiImageUrl); + imageUrlPayload.setHuaweiImageUrl(huaweiImageUrl); + imageUrlPayload.setFcmImageUrl(fcmImageUrl); + imageUrlPayload.setJiguangImageUrl(jiguangImageUrl); + return imageUrlPayload; + } + } + +} \ No newline at end of file diff --git a/src/main/java/cn/jpush/api/push/model/notification/AndroidNotification.java b/src/main/java/cn/jpush/api/push/model/notification/AndroidNotification.java index dcc0d197..ab2407cd 100644 --- a/src/main/java/cn/jpush/api/push/model/notification/AndroidNotification.java +++ b/src/main/java/cn/jpush/api/push/model/notification/AndroidNotification.java @@ -3,10 +3,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import lombok.*; -import lombok.experimental.Accessors; -import java.util.LinkedHashMap; import java.util.Map; public class AndroidNotification extends PlatformNotification { @@ -23,6 +20,7 @@ public class AndroidNotification extends PlatformNotification { private static final String PRIORITY = "priority"; private static final String CATEGORY = "category"; private static final String LARGE_ICON = "large_icon"; + private static final String SMALL_ICON_URI = "small_icon_uri"; private static final String INTENT = "intent"; private final String title; @@ -38,6 +36,7 @@ public class AndroidNotification extends PlatformNotification { private int priority; private String category; private String large_icon; + private String small_icon_uri; private JsonObject intent; private AndroidNotification(Object alert, @@ -51,6 +50,7 @@ private AndroidNotification(Object alert, int priority, String category, String large_icon, + String small_icon_uri, JsonObject intent, String channelId, Map extras, @@ -70,6 +70,7 @@ private AndroidNotification(Object alert, this.priority = priority; this.category = category; this.large_icon = large_icon; + this.small_icon_uri = small_icon_uri; this.intent = intent; this.channelId = channelId; } @@ -142,6 +143,10 @@ public JsonElement toJSON() { json.add(LARGE_ICON, new JsonPrimitive(large_icon)); } + if (null != small_icon_uri) { + json.add(SMALL_ICON_URI, new JsonPrimitive(small_icon_uri)); + } + if (null != intent) { json.add(INTENT, intent); } @@ -164,6 +169,7 @@ public static class Builder extends PlatformNotification.Builder textMap = new HashMap<>(); + textMap.put("image_type", "2"); + HashMap fileMap = new HashMap<>(); + fileMap.put("oppo_file", "oppoXX.jpg"); + fileMap.put("xiaomi_file", "dir/xiaomiXX.jpg"); + verify(mockIHttpClient).formUploadByPost("https://api.jpush.cn/v3/images/byfiles", textMap, fileMap, null); + + assertThat(imageUploadResult.getMediaId(), equalTo("jgmedia-2-14b23451-0001-41ce-89d9-987b465122da")); + assertThat(imageUploadResult.getOppoImageUrl(), equalTo("3653918_5f92b5739ae676f5745bcbf4")); + assertThat(imageUploadResult.getXiaomiImageUrl(), equalTo("http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png")); + assertThat(imageUploadResult.getHuaweiImageUrl(), nullValue()); + } + + @Test + public void testModifyImageByUrl() throws NoSuchFieldException, APIConnectionException, APIRequestException { + ResponseWrapper mockResponseWrapper = new ResponseWrapper(); + mockResponseWrapper.responseCode = 200; + mockResponseWrapper.responseContent = "{\n" + + " \"media_id\": \"jgmedia-2-14b23451-0001-41ce-89d9-987b465122da\", \n" + + " \"oppo_image_url\": \"3653918_5f92b5739ae676f5745bcbf4\", \n" + + " \"xiaomi_image_url\": \"http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png\" \n" + + "}"; + String mediaId = "jgmedia-2-14b23451-0001-41ce-89d9-987b465122da"; + NativeHttpClient mockIHttpClient = mock(NativeHttpClient.class); + when(mockIHttpClient.sendPut(anyString(), anyString())).thenReturn(mockResponseWrapper); + + ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY); + new FieldSetter(client, client.getClass().getDeclaredField("_httpClient")).set(mockIHttpClient); + ImageClient spyClient = Mockito.spy(client); + ImageUrlPayload payload = ImageUrlPayload.newBuilder() + .setImageUrl("xxx.jpg") + .setFcmImageUrl("xxx.png") + .setHuaweiImageUrl("xxx.jpeg") + .build(); + ImageUploadResult imageUploadResult = spyClient.modifyImage(mediaId, payload); + verify(mockIHttpClient).sendPut("https://api.jpush.cn/v3/images/byurls/" + mediaId, "{\"image_url\":\"xxx.jpg\",\"huawei_image_url\":\"xxx.jpeg\",\"fcm_image_url\":\"xxx.png\"}"); + + assertThat(imageUploadResult.getMediaId(), equalTo("jgmedia-2-14b23451-0001-41ce-89d9-987b465122da")); + assertThat(imageUploadResult.getOppoImageUrl(), equalTo("3653918_5f92b5739ae676f5745bcbf4")); + assertThat(imageUploadResult.getXiaomiImageUrl(), equalTo("http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png")); + assertThat(imageUploadResult.getHuaweiImageUrl(), nullValue()); + } + + @Test + public void testModifyImageByFile() throws NoSuchFieldException { + String content = "{\n" + + " \"media_id\": \"jgmedia-2-14b23451-0001-41ce-89d9-987b465122da\", \n" + + " \"oppo_image_url\": \"3653918_5f92b5739ae676f5745bcbf4\", \n" + + " \"xiaomi_image_url\": \"http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png\" \n" + + "}"; + String mediaId = "jgmedia-2-14b23451-0001-41ce-89d9-987b465122da"; + + NativeHttpClient mockIHttpClient = mock(NativeHttpClient.class); + when(mockIHttpClient.formUploadByPut(anyString(), anyMap(), anyMap(), anyString())).thenReturn(content); + + ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY); + new FieldSetter(client, client.getClass().getDeclaredField("_httpClient")).set(mockIHttpClient); + ImageClient spyClient = Mockito.spy(client); + ImageFilePayload payload = ImageFilePayload.newBuilder() + .setOppoFileName("oppoXX.jpg") + .setXiaomiFileName("dir/xiaomiXX.jpg") + .build(); + ImageUploadResult imageUploadResult = spyClient.modifyImage(mediaId, payload); + HashMap fileMap = new HashMap<>(); + fileMap.put("oppo_file", "oppoXX.jpg"); + fileMap.put("xiaomi_file", "dir/xiaomiXX.jpg"); + verify(mockIHttpClient).formUploadByPut("https://api.jpush.cn/v3/images/byfiles/" + mediaId, null, fileMap, null); + + assertThat(imageUploadResult.getMediaId(), equalTo("jgmedia-2-14b23451-0001-41ce-89d9-987b465122da")); + assertThat(imageUploadResult.getOppoImageUrl(), equalTo("3653918_5f92b5739ae676f5745bcbf4")); + assertThat(imageUploadResult.getXiaomiImageUrl(), equalTo("http://f6.market.xiaomi.com/download/MiPass/01fff50f50ba193f94074ec/d1671936d468383f.png")); + assertThat(imageUploadResult.getHuaweiImageUrl(), nullValue()); + } + + @Test + public void testUploadImageByUrl2() throws APIConnectionException, APIRequestException { + + ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY); + ImageUrlPayload payload = ImageUrlPayload.newBuilder() + .setImageType(ImageType.LARGE_ICON) + .setImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009232P5.jpg") + .setOppoImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009232P5.jpg") + .setHuaweiImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009232P5.jpg") + .build(); + ImageUploadResult imageUploadResult = client.uploadImage(payload); + assertThat(imageUploadResult, notNullValue()); + String mediaId = imageUploadResult.getMediaId(); + assertThat(mediaId, notNullValue()); + ImageUrlPayload payload2 = ImageUrlPayload.newBuilder() + .setImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg") + .setFcmImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg") + .setHuaweiImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg") + .build(); + ImageUploadResult imageUploadResult2 = client.modifyImage(mediaId, payload2); + assertThat(imageUploadResult2, notNullValue()); + assertThat(imageUploadResult2.getHuaweiImageUrl(), notNullValue()); + } + + @Test + public void testUploadImageByFile2() { + ImageClient client = new ImageClient(MASTER_SECRET, APP_KEY); + ImageFilePayload payload = ImageFilePayload.newBuilder() + .setImageType(ImageType.BIG_PICTURE) + .setOppoFileName("/Users/yongxing/Downloads/Xnip2020-12-11_14-24-28.jpg") + .setXiaomiFileName("/Users/yongxing/Downloads/Xnip2020-12-11_14-24-28.jpg") + .build(); + ImageUploadResult imageUploadResult = client.uploadImage(payload); + assertThat(imageUploadResult, notNullValue()); + assertThat(imageUploadResult.getError(), nullValue()); + String mediaId = imageUploadResult.getMediaId(); + assertThat(mediaId, notNullValue()); + ImageFilePayload payload2 = ImageFilePayload.newBuilder() + .setOppoFileName("/Users/yongxing/Downloads/IMG_2778.jpeg") + .setXiaomiFileName("/Users/yongxing/Downloads/IMG_2778.jpeg") + .build(); + imageUploadResult = client.modifyImage(mediaId, payload2); + assertThat(imageUploadResult, notNullValue()); + assertThat(imageUploadResult.getOppoImageUrl(), notNullValue()); + } +} \ No newline at end of file diff --git a/src/test/java/cn/jpush/api/push/remote/NotificationTest.java b/src/test/java/cn/jpush/api/push/remote/NotificationTest.java index d296b74a..6b73954c 100644 --- a/src/test/java/cn/jpush/api/push/remote/NotificationTest.java +++ b/src/test/java/cn/jpush/api/push/remote/NotificationTest.java @@ -2,6 +2,10 @@ import cn.jiguang.common.resp.APIRequestException; import cn.jpush.api.SlowTests; +import cn.jpush.api.image.ImageClient; +import cn.jpush.api.image.model.ImageType; +import cn.jpush.api.image.model.ImageUploadResult; +import cn.jpush.api.image.model.ImageUrlPayload; import cn.jpush.api.push.PushResult; import cn.jpush.api.push.model.Platform; import cn.jpush.api.push.model.PushPayload; @@ -18,16 +22,16 @@ @Category(SlowTests.class) public class NotificationTest extends BaseRemotePushTest { - + @Test public void sendNotification_alert_json() throws Exception { JsonObject json = new JsonObject(); json.addProperty("key1", "value1"); json.addProperty("key2", true); - + String alert = json.toString(); System.out.println(alert); - + PushPayload payload = PushPayload.newBuilder() .setAudience(Audience.all()) .setPlatform(Platform.all()) @@ -39,9 +43,9 @@ public void sendNotification_alert_json() throws Exception { PushResult result = _client.sendPush(payload); assertTrue(result.isResultOK()); } - + // --------------- Android - + @Test public void sendNotification_android_title() throws Exception { PushPayload payload = PushPayload.newBuilder() @@ -55,7 +59,7 @@ public void sendNotification_android_title() throws Exception { PushResult result = _client.sendPush(payload); assertTrue(result.isResultOK()); } - + @Test public void sendNotification_android_buildId() throws Exception { PushPayload payload = PushPayload.newBuilder() @@ -70,7 +74,7 @@ public void sendNotification_android_buildId() throws Exception { PushResult result = _client.sendPush(payload); assertTrue(result.isResultOK()); } - + @Test public void sendNotification_android_extras() throws Exception { PushPayload payload = PushPayload.newBuilder() @@ -86,10 +90,43 @@ public void sendNotification_android_extras() throws Exception { PushResult result = _client.sendPush(payload); assertTrue(result.isResultOK()); } - - + + @Test + public void sendNotification_android_media_id() throws Exception { + ImageClient imageClient = new ImageClient(MASTER_SECRET, APP_KEY); + ImageUploadResult imageUploadResult = imageClient.uploadImage(ImageUrlPayload.newBuilder() + .setImageType(ImageType.SMALL_ICON) + .setImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg") + .setXiaomiImageUrl("http://img.aiimg.com/uploads/allimg/151009/280082-151009225435.jpg") + .build()); + String mediaId = imageUploadResult.getMediaId(); + JsonObject json = new JsonObject(); + json.addProperty("key1", "value1"); + json.addProperty("key2", true); + + String alert = json.toString(); + System.out.println(alert); + + PushPayload payload = PushPayload.newBuilder() + .setAudience(Audience.all()) + .setPlatform(Platform.all()) + .setNotification(Notification.newBuilder() + .addPlatformNotification(AndroidNotification.newBuilder() + .setAlert(alert) + .setSmallIconUri(mediaId) + .setLargeIcon(mediaId) + .setBigPicPath(mediaId) + .setInbox(mediaId) + .setBigText(mediaId) + .setTitle("title") + .build()).build()) + .build(); + PushResult result = _client.sendPush(payload); + assertTrue(result.isResultOK()); + } + // ------------------ ios - + @Test public void sendNotification_ios_badge() throws Exception { PushPayload payload = PushPayload.newBuilder()