From 67226c8ccd720ba9ec61ba616a367f14253177f8 Mon Sep 17 00:00:00 2001 From: Sutra Zhou Date: Thu, 16 Aug 2018 23:33:23 +0800 Subject: [PATCH 1/2] Implement WXA SecCheck API. --- .../foxinmy/weixin4j/wxa/WeixinAppFacade.java | 13 +++ .../foxinmy/weixin4j/wxa/api/SecCheckApi.java | 98 +++++++++++++++++++ .../weixin4j/wxa/api/weixin.properties | 12 ++- 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/SecCheckApi.java diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/WeixinAppFacade.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/WeixinAppFacade.java index c36f6a88..70984cb2 100644 --- a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/WeixinAppFacade.java +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/WeixinAppFacade.java @@ -12,6 +12,7 @@ import com.foxinmy.weixin4j.token.TokenManager; import com.foxinmy.weixin4j.wxa.api.CustomMessageApi; import com.foxinmy.weixin4j.wxa.api.LoginApi; import com.foxinmy.weixin4j.wxa.api.QrCodeApi; +import com.foxinmy.weixin4j.wxa.api.SecCheckApi; import com.foxinmy.weixin4j.wxa.api.TemplateApi; import com.foxinmy.weixin4j.wxa.api.TemplateMessageApi; @@ -27,6 +28,7 @@ public class WeixinAppFacade { private final TemplateApi templateApi; private final TemplateMessageApi templateMessageApi; private final CustomMessageApi customMessageApi; + private final SecCheckApi secCheckApi; /** * Constructs {@link WeixinAppFacade} using {@link FileCacheStorager}. @@ -108,6 +110,7 @@ public class WeixinAppFacade { this.templateApi = new TemplateApi(tokenManager, properties); this.templateMessageApi = new TemplateMessageApi(tokenManager, properties); this.customMessageApi = new CustomMessageApi(tokenManager, properties); + this.secCheckApi = new SecCheckApi(tokenManager, properties); } /** @@ -155,4 +158,14 @@ public class WeixinAppFacade { return customMessageApi; } + /** + * 获取内容安全相关的 API。 + * + * @return 内容安全相关的 API。 + * @since 1.9 + */ + public SecCheckApi getSecCheckApi() { + return secCheckApi; + } + } diff --git a/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/SecCheckApi.java b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/SecCheckApi.java new file mode 100644 index 00000000..aa94753d --- /dev/null +++ b/weixin4j-wxa/src/main/java/com/foxinmy/weixin4j/wxa/api/SecCheckApi.java @@ -0,0 +1,98 @@ +package com.foxinmy.weixin4j.wxa.api; + +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.imageio.ImageIO; + +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.apache.content.InputStreamBody; +import com.foxinmy.weixin4j.http.apache.mime.FormBodyPart; +import com.foxinmy.weixin4j.http.weixin.WeixinResponse; +import com.foxinmy.weixin4j.token.TokenManager; + +/** + * 违法违规内容检查。 + * + * @since 1.9 + */ +public class SecCheckApi extends TokenManagerApi { + + public SecCheckApi(TokenManager tokenManager) { + super(tokenManager); + } + + public SecCheckApi(TokenManager tokenManager, Properties properties) { + super(tokenManager, properties); + } + + private InputStream scale(InputStream inputStream, int maxWidth, int maxHeight) throws IOException { + final BufferedImage srcBufferedImage = ImageIO.read(inputStream); + + final int srcWidth = srcBufferedImage.getWidth(); + final int srcHeight = srcBufferedImage.getHeight(); + final float scale = Math.min((float) maxWidth / (float) srcWidth, (float) maxHeight / (float) srcHeight); + + final BufferedImage scaledBufferedImage; + if (scale < 1F) { + final int width = (int) (srcWidth * scale); + final int height = (int) (srcHeight * scale); + final Image scaledImage = srcBufferedImage.getScaledInstance(width, height, Image.SCALE_DEFAULT); + + scaledBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + scaledBufferedImage.getGraphics().drawImage(scaledImage, 0, 0 , null); + } else { + scaledBufferedImage = srcBufferedImage; + } + + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ImageIO.write(scaledBufferedImage, "png", outputStream); + return new ByteArrayInputStream(outputStream.toByteArray()); + } + + /** + * 校验一张图片是否含有违法违规内容。 + * + * @param inputStream the image input stream. + * @throws WeixinException indicates getting access token failed, or the content is risky. + * @see 校验一张图片是否含有违法违规内容 + */ + public void imgSecCheck(InputStream inputStream) throws WeixinException { + final String imgSecCheckUri = this.getAccessTokenRequestUri("wxa_img_sec_check"); + final InputStreamBody inputStreamBody = new InputStreamBody(inputStream, "media"); + final FormBodyPart formBodyPart = new FormBodyPart("media", inputStreamBody); + final WeixinResponse response = weixinExecutor.post(imgSecCheckUri, formBodyPart); + final WxaApiResult r = response.getAsObject(WxaApiResult.TYPE_REFERENCE); + r.checkErrCode(); + } + + public void imgSecCheck(InputStream inputStream, int maxWidth, int maxHeight) throws WeixinException { + try { + this.imgSecCheck(this.scale(inputStream, maxWidth, maxHeight)); + } catch (IOException e) { + throw new WeixinException(e); + } + } + + /** + * 检查一段文本是否含有违法违规内容。 + * + * @param content 要检测的文本内容,长度不超过 500KB,编码格式为 UTF-8。 + * @throws WeixinException indicates getting access token failed, or the content is risky. + * @see 检查一段文本是否含有违法违规内容 + */ + public void msgSecCheck(String content) throws WeixinException { + final Map params = new HashMap(1); + params.put("content", content); + final WxaApiResult r = this.post("wxa_msg_sec_check", params, WxaApiResult.TYPE_REFERENCE); + r.checkErrCode(); + } + +} diff --git a/weixin4j-wxa/src/main/resources/com/foxinmy/weixin4j/wxa/api/weixin.properties b/weixin4j-wxa/src/main/resources/com/foxinmy/weixin4j/wxa/api/weixin.properties index 8f43d7e8..db3376f5 100644 --- a/weixin4j-wxa/src/main/resources/com/foxinmy/weixin4j/wxa/api/weixin.properties +++ b/weixin4j-wxa/src/main/resources/com/foxinmy/weixin4j/wxa/api/weixin.properties @@ -3,6 +3,7 @@ # ---------------------------------------------------------------------------- api_base_url=https://api.weixin.qq.com +api_wxa_url={api_base_url}/wxa api_cgi_url={api_base_url}/cgi-bin # \u767b\u5f55\u51ed\u8bc1\u6821\u9a8c @@ -10,10 +11,10 @@ sns_jscode2session={api_base_url}/sns/jscode2session?appid=%s&secret=%s&js_code= # \u83b7\u53d6\u5c0f\u7a0b\u5e8f\u7801 \u63a5\u53e3A: \u9002\u7528\u4e8e\u9700\u8981\u7684\u7801\u6570\u91cf\u8f83\u5c11\u7684\u4e1a\u52a1\u573a\u666f -wxa_getwxacode={api_base_url}/wxa/getwxacode?access_token=%s +wxa_getwxacode={api_wxa_url}/getwxacode?access_token=%s # \u83b7\u53d6\u5c0f\u7a0b\u5e8f\u7801 \u63a5\u53e3B\uff1a\u9002\u7528\u4e8e\u9700\u8981\u7684\u7801\u6570\u91cf\u6781\u591a\u7684\u4e1a\u52a1\u573a\u666f -wxa_getwxacodeunlimit={api_base_url}/wxa/getwxacodeunlimit?access_token=%s +wxa_getwxacodeunlimit={api_wxa_url}/getwxacodeunlimit?access_token=%s # \u83b7\u53d6\u5c0f\u7a0b\u5e8f\u4e8c\u7ef4\u7801 \u63a5\u53e3C\uff1a\u9002\u7528\u4e8e\u9700\u8981\u7684\u7801\u6570\u91cf\u8f83\u5c11\u7684\u4e1a\u52a1\u573a\u666f wxaapp_createwxaqrcode={api_base_url}/cgi-bin/wxaapp/createwxaqrcode?access_token=%s @@ -43,3 +44,10 @@ message_custom_send={api_cgi_url}/message/custom/send?access_token=% # \u5ba2\u670d\u8f93\u5165\u72b6\u6001 message_custom_typing={api_cgi_url}/message/custom/typing?access_token=% + + +# imgSecCheck +wxa_img_sec_check={api_wxa_url}/img_sec_check?access_token=%s + +# msgSecCheck +wxa_msg_sec_check={api_wxa_url}/msg_sec_check?access_token=%s From ea13e82d6bd728c191e2490a280a86a80cbbd6bd Mon Sep 17 00:00:00 2001 From: Sutra Zhou Date: Thu, 16 Aug 2018 23:34:34 +0800 Subject: [PATCH 2/2] Bump version number from 1.8.2 to 1.9.0-SNAPSHOT. --- pom.xml | 2 +- weixin4j-base/pom.xml | 2 +- weixin4j-example/pom.xml | 2 +- weixin4j-mp/pom.xml | 2 +- weixin4j-qy/pom.xml | 2 +- weixin4j-server/pom.xml | 2 +- weixin4j-serverX/pom.xml | 2 +- weixin4j-wxa/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 6603589b..57fc8c48 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.foxinmy weixin4j - 1.8.2 + 1.9.0-SNAPSHOT pom weixin4j https://github.com/foxinmy/weixin4j diff --git a/weixin4j-base/pom.xml b/weixin4j-base/pom.xml index ed777db4..48ca0837 100644 --- a/weixin4j-base/pom.xml +++ b/weixin4j-base/pom.xml @@ -5,7 +5,7 @@ com.foxinmy weixin4j - 1.8.2 + 1.9.0-SNAPSHOT weixin4j-base weixin4j-base diff --git a/weixin4j-example/pom.xml b/weixin4j-example/pom.xml index 9f9c6600..e7a67f43 100644 --- a/weixin4j-example/pom.xml +++ b/weixin4j-example/pom.xml @@ -5,7 +5,7 @@ com.foxinmy weixin4j - 1.8.2 + 1.9.0-SNAPSHOT war weixin4j-example diff --git a/weixin4j-mp/pom.xml b/weixin4j-mp/pom.xml index afa06c5c..2c9ef8f3 100644 --- a/weixin4j-mp/pom.xml +++ b/weixin4j-mp/pom.xml @@ -5,7 +5,7 @@ com.foxinmy weixin4j - 1.8.2 + 1.9.0-SNAPSHOT weixin4j-mp weixin4j-mp diff --git a/weixin4j-qy/pom.xml b/weixin4j-qy/pom.xml index 700c6957..f22a034d 100644 --- a/weixin4j-qy/pom.xml +++ b/weixin4j-qy/pom.xml @@ -5,7 +5,7 @@ com.foxinmy weixin4j - 1.8.2 + 1.9.0-SNAPSHOT weixin4j-qy weixin4j-qy diff --git a/weixin4j-server/pom.xml b/weixin4j-server/pom.xml index 8413ff30..e0a0ed9e 100644 --- a/weixin4j-server/pom.xml +++ b/weixin4j-server/pom.xml @@ -5,7 +5,7 @@ com.foxinmy weixin4j - 1.8.2 + 1.9.0-SNAPSHOT weixin4j-server 1.1.9 diff --git a/weixin4j-serverX/pom.xml b/weixin4j-serverX/pom.xml index 1faa56d1..7b924bb5 100644 --- a/weixin4j-serverX/pom.xml +++ b/weixin4j-serverX/pom.xml @@ -6,7 +6,7 @@ com.foxinmy weixin4j - 1.8.2 + 1.9.0-SNAPSHOT weixin4j-serverX 0.0.1 diff --git a/weixin4j-wxa/pom.xml b/weixin4j-wxa/pom.xml index b5344a71..0d35ed4d 100644 --- a/weixin4j-wxa/pom.xml +++ b/weixin4j-wxa/pom.xml @@ -5,7 +5,7 @@ com.foxinmy weixin4j - 1.8.2 + 1.9.0-SNAPSHOT weixin4j-wxa weixin4j-wxa