Skip to content

Commit 7cb92a8

Browse files
committed
#857 添加微信小程序敏感文本检测接口
1 parent a73d6e6 commit 7cb92a8

File tree

6 files changed

+164
-39
lines changed

6 files changed

+164
-39
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package cn.binarywang.wx.miniapp.api;
2+
3+
import java.io.File;
4+
5+
import me.chanjar.weixin.common.error.WxErrorException;
6+
7+
/**
8+
* <pre>
9+
* 内容安全相关接口.
10+
* Created by Binary Wang on 2018/11/24.
11+
* </pre>
12+
*
13+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
14+
*/
15+
public interface WxMaSecCheckService {
16+
17+
String IMG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/img_sec_check";
18+
19+
String MSG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/msg_sec_check";
20+
21+
/**
22+
* <pre>
23+
* 校验一张图片是否含有违法违规内容.
24+
* 应用场景举例:
25+
* 1)图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等;
26+
* 2)敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。频率限制:单个 appId 调用上限为 1000 次/分钟,100,000 次/天
27+
* 详情请见: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/sec-check/imgSecCheck.html
28+
* </pre>
29+
*/
30+
boolean checkImage(File file) throws WxErrorException;
31+
32+
/**
33+
* <pre>
34+
* 检查一段文本是否含有违法违规内容。
35+
* 应用场景举例:
36+
* 用户个人资料违规文字检测;
37+
* 媒体新闻类用户发表文章,评论内容检测;
38+
* 游戏类用户编辑上传的素材(如答题类小游戏用户上传的问题及答案)检测等。 频率限制:单个 appId 调用上限为 4000 次/分钟,2,000,000 次/天*
39+
* 详情请见: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/sec-check/msgSecCheck.html
40+
* </pre>
41+
*/
42+
boolean checkMessage(String msgString);
43+
}

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package cn.binarywang.wx.miniapp.api;
22

3-
import java.io.File;
4-
53
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
64
import cn.binarywang.wx.miniapp.config.WxMaConfig;
75
import me.chanjar.weixin.common.error.WxErrorException;
@@ -20,17 +18,6 @@ public interface WxMaService {
2018

2119
String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";
2220

23-
String IMG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/img_sec_check";
24-
25-
/**
26-
* <pre>
27-
* 校验一张图片是否含有违法违规内容.
28-
* 应用场景举例:1)图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等;2)敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。频率限制:单个 appId 调用上限为 1000 次/分钟,100,000 次/天
29-
* 详情请见: https://developers.weixin.qq.com/miniprogram/dev/api/imgSecCheck.html
30-
* </pre>
31-
*/
32-
boolean imgSecCheck(File file) throws WxErrorException;
33-
3421
/**
3522
* 获取登录后的session信息.
3623
*
@@ -186,11 +173,17 @@ public interface WxMaService {
186173
WxMaShareService getShareService();
187174

188175
/**
189-
* 返回维新运动相关接口服务对象.
176+
* 返回微信运动相关接口服务对象.
190177
* @return WxMaShareService
191178
*/
192179
WxMaRunService getRunService();
193180

181+
/**
182+
* 返回内容安全相关接口服务对象.
183+
* @return WxMaShareService
184+
*/
185+
WxMaSecCheckService getSecCheckService();
186+
194187
/**
195188
* 初始化http请求对象.
196189
*/
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package cn.binarywang.wx.miniapp.api.impl;
2+
3+
import java.io.File;
4+
5+
import cn.binarywang.wx.miniapp.api.WxMaSecCheckService;
6+
import cn.binarywang.wx.miniapp.api.WxMaService;
7+
import com.google.gson.JsonObject;
8+
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
9+
import me.chanjar.weixin.common.error.WxErrorException;
10+
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
11+
12+
/**
13+
* <pre>
14+
*
15+
* Created by Binary Wang on 2018/11/24.
16+
* </pre>
17+
*
18+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
19+
*/
20+
public class WxMaSecCheckServiceImpl implements WxMaSecCheckService {
21+
private WxMaService service;
22+
23+
public WxMaSecCheckServiceImpl(WxMaService service) {
24+
this.service = service;
25+
}
26+
27+
@Override
28+
public boolean checkImage(File file) throws WxErrorException {
29+
//这里只是借用MediaUploadRequestExecutor,并不使用其返回值WxMediaUploadResult
30+
WxMediaUploadResult result = this.service.execute(MediaUploadRequestExecutor
31+
.create(this.service.getRequestHttp()), IMG_SEC_CHECK_URL, file);
32+
return result != null;
33+
}
34+
35+
@Override
36+
public boolean checkMessage(String msgString) {
37+
JsonObject jsonObject = new JsonObject();
38+
jsonObject.addProperty("content", msgString);
39+
try {
40+
this.service.post(MSG_SEC_CHECK_URL, jsonObject.toString());
41+
} catch (WxErrorException e) {
42+
return false;
43+
}
44+
45+
return true;
46+
}
47+
48+
}

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cn.binarywang.wx.miniapp.api.impl;
22

3-
import java.io.File;
43
import java.io.IOException;
54
import java.util.HashMap;
65
import java.util.Map;
@@ -12,8 +11,6 @@
1211
import org.apache.http.client.methods.HttpGet;
1312
import org.apache.http.impl.client.BasicResponseHandler;
1413
import org.apache.http.impl.client.CloseableHttpClient;
15-
import org.slf4j.Logger;
16-
import org.slf4j.LoggerFactory;
1714

1815
import cn.binarywang.wx.miniapp.api.WxMaAnalysisService;
1916
import cn.binarywang.wx.miniapp.api.WxMaCodeService;
@@ -22,6 +19,7 @@
2219
import cn.binarywang.wx.miniapp.api.WxMaMsgService;
2320
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
2421
import cn.binarywang.wx.miniapp.api.WxMaRunService;
22+
import cn.binarywang.wx.miniapp.api.WxMaSecCheckService;
2523
import cn.binarywang.wx.miniapp.api.WxMaService;
2624
import cn.binarywang.wx.miniapp.api.WxMaSettingService;
2725
import cn.binarywang.wx.miniapp.api.WxMaShareService;
@@ -31,14 +29,13 @@
3129
import cn.binarywang.wx.miniapp.config.WxMaConfig;
3230
import com.google.common.base.Joiner;
3331
import com.google.gson.Gson;
32+
import lombok.extern.slf4j.Slf4j;
3433
import me.chanjar.weixin.common.bean.WxAccessToken;
35-
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
3634
import me.chanjar.weixin.common.error.WxError;
3735
import me.chanjar.weixin.common.error.WxErrorException;
3836
import me.chanjar.weixin.common.util.DataUtils;
3937
import me.chanjar.weixin.common.util.crypto.SHA1;
4038
import me.chanjar.weixin.common.util.http.HttpType;
41-
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
4239
import me.chanjar.weixin.common.util.http.RequestExecutor;
4340
import me.chanjar.weixin.common.util.http.RequestHttp;
4441
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
@@ -51,9 +48,8 @@
5148
/**
5249
* @author <a href="https://github.com/binarywang">Binary Wang</a>
5350
*/
51+
@Slf4j
5452
public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpClient, HttpHost> {
55-
private final Logger log = LoggerFactory.getLogger(this.getClass());
56-
5753
private CloseableHttpClient httpClient;
5854
private HttpHost httpProxy;
5955
private WxMaConfig wxMaConfig;
@@ -69,6 +65,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
6965
private WxMaJsapiService jsapiService = new WxMaJsapiServiceImpl(this);
7066
private WxMaShareService shareService = new WxMaShareServiceImpl(this);
7167
private WxMaRunService runService = new WxMaRunServiceImpl(this);
68+
private WxMaSecCheckService secCheckService = new WxMaSecCheckServiceImpl(this);
7269

7370
private int retrySleepMillis = 1000;
7471
private int maxRetryTimes = 5;
@@ -153,13 +150,6 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
153150
return this.getWxMaConfig().getAccessToken();
154151
}
155152

156-
@Override
157-
public boolean imgSecCheck(File file) throws WxErrorException {
158-
//这里只是借用MediaUploadRequestExecutor,并不使用其返回值WxMediaUploadResult
159-
WxMediaUploadResult result = this.execute(MediaUploadRequestExecutor.create(this.getRequestHttp()), IMG_SEC_CHECK_URL, file);
160-
return result != null;
161-
}
162-
163153
@Override
164154
public WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException {
165155
final WxMaConfig config = getWxMaConfig();
@@ -209,7 +199,7 @@ public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) thro
209199
return this.executeInternal(executor, uri, data);
210200
} catch (WxErrorException e) {
211201
if (retryTimes + 1 > this.maxRetryTimes) {
212-
this.log.warn("重试达到最大次数【{}】", maxRetryTimes);
202+
log.warn("重试达到最大次数【{}】", maxRetryTimes);
213203
//最后一次重试失败后,直接抛出异常,不再等待
214204
throw new RuntimeException("微信服务端异常,超出重试次数");
215205
}
@@ -219,7 +209,7 @@ public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) thro
219209
if (error.getErrorCode() == -1) {
220210
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
221211
try {
222-
this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
212+
log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
223213
Thread.sleep(sleepMillis);
224214
} catch (InterruptedException e1) {
225215
throw new RuntimeException(e1);
@@ -230,7 +220,7 @@ public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) thro
230220
}
231221
} while (retryTimes++ < this.maxRetryTimes);
232222

233-
this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
223+
log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
234224
throw new RuntimeException("微信服务端异常,超出重试次数");
235225
}
236226

@@ -246,7 +236,7 @@ private <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E d
246236

247237
try {
248238
T result = executor.execute(uriWithAccessToken, data);
249-
this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
239+
log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result);
250240
return result;
251241
} catch (WxErrorException e) {
252242
WxError error = e.getError();
@@ -264,12 +254,12 @@ private <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E d
264254
}
265255

266256
if (error.getErrorCode() != 0) {
267-
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
257+
log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error);
268258
throw new WxErrorException(error, e);
269259
}
270260
return null;
271261
} catch (IOException e) {
272-
this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
262+
log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage());
273263
throw new RuntimeException(e);
274264
}
275265
}
@@ -349,4 +339,9 @@ public WxMaShareService getShareService() {
349339
public WxMaRunService getRunService() {
350340
return this.runService;
351341
}
342+
343+
@Override
344+
public WxMaSecCheckService getSecCheckService() {
345+
return this.secCheckService;
346+
}
352347
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package cn.binarywang.wx.miniapp.api.impl;
2+
3+
import java.io.File;
4+
5+
import org.testng.annotations.*;
6+
7+
import cn.binarywang.wx.miniapp.api.WxMaService;
8+
import cn.binarywang.wx.miniapp.test.ApiTestModule;
9+
import com.google.inject.Inject;
10+
import me.chanjar.weixin.common.error.WxErrorException;
11+
12+
import static org.assertj.core.api.Assertions.assertThat;
13+
import static org.testng.Assert.*;
14+
15+
/**
16+
* <pre>
17+
*
18+
* Created by Binary Wang on 2018/11/24.
19+
* </pre>
20+
*
21+
* @author <a href="https://github.com/binarywang">Binary Wang</a>
22+
*/
23+
@Test
24+
@Guice(modules = ApiTestModule.class)
25+
public class WxMaSecCheckServiceImplTest {
26+
@Inject
27+
private WxMaService wxService;
28+
29+
@Test
30+
public void testCheckImage() throws WxErrorException {
31+
boolean result = this.wxService.getSecCheckService()
32+
.checkImage(new File(ClassLoader.getSystemResource("tmp.png").getFile()));
33+
assertTrue(result);
34+
}
35+
36+
@DataProvider
37+
public Object[][] secData() {
38+
return new Object[][]{
39+
{"特3456书yuuo莞6543李zxcz蒜7782法fgnv级", false},
40+
{"完2347全dfji试3726测asad感3847知qwez到", false},
41+
{"hello world!", true}
42+
};
43+
}
44+
45+
@Test(dataProvider = "secData")
46+
public void testCheckMessage(String msg, boolean result) {
47+
assertThat(this.wxService.getSecCheckService()
48+
.checkMessage(msg))
49+
.isEqualTo(result);
50+
}
51+
}

weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,4 @@ public void testRefreshAccessToken() throws WxErrorException {
3333
assertTrue(StringUtils.isNotBlank(after));
3434
}
3535

36-
@Test
37-
public void testImgSecCheck() throws WxErrorException {
38-
boolean result = this.wxService.imgSecCheck(new File(ClassLoader.getSystemResource("tmp.png").getFile()));
39-
assertTrue(result);
40-
}
4136
}

0 commit comments

Comments
 (0)