1. 百度云文本审核工具类概述
在当今互联网应用中,内容安全审核已成为不可或缺的一环。百度云内容审核服务提供了强大的文本审核能力,能够有效识别文本中的违禁内容、敏感信息和垃圾广告等。对于Java开发者而言,将这些能力封装成工具类可以极大提升开发效率和代码复用性。
文本审核工具类的核心价值在于:
- 简化API调用流程,隐藏底层HTTP请求细节
- 提供统一的异常处理机制
- 支持超长文本的自动分片处理
- 标准化返回结果格式
提示:百度云文本审核API支持检测包括色情、暴恐、政治敏感、广告、辱骂等12大类违禁内容,准确率超过99%。
2. 工具类设计与实现
2.1 基础环境准备
首先需要在项目中添加必要的依赖:
xml复制<!-- HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
2.2 核心工具类结构
java复制public class BaiduContentModerationUtil {
private static final String API_URL = "https://aip.baidubce.com/rest/2.0/solution/v1/text_censor/v2/user_defined";
private static final int MAX_TEXT_LENGTH = 20000; // 单次请求最大文本长度
private String accessToken;
private CloseableHttpClient httpClient;
// 初始化方法
public BaiduContentModerationUtil(String apiKey, String secretKey) {
this.accessToken = getAccessToken(apiKey, secretKey);
this.httpClient = HttpClients.createDefault();
}
// 获取access token
private String getAccessToken(String apiKey, String secretKey) {
// 实现token获取逻辑
}
// 文本审核主方法
public ModerationResult checkText(String content) {
// 实现文本审核逻辑
}
// 关闭资源
public void close() throws IOException {
httpClient.close();
}
}
2.3 超长文本处理策略
当文本长度超过API限制时,需要采用分片处理策略:
- 按段落分片:优先按自然段落分割文本
- 按句子分片:无段落时按标点符号分割
- 固定长度分片:前两种方式不可用时按固定长度分割
实现代码示例:
java复制private List<String> splitLongText(String content) {
List<String> segments = new ArrayList<>();
// 先尝试按段落分割
String[] paragraphs = content.split("\n\n");
if (paragraphs.length > 1) {
for (String para : paragraphs) {
if (para.length() > MAX_TEXT_LENGTH) {
segments.addAll(splitBySentences(para));
} else {
segments.add(para);
}
}
return segments;
}
// 再尝试按句子分割
return splitBySentences(content);
}
private List<String> splitBySentences(String text) {
// 实现按句子分割逻辑
}
3. HTTPS请求实现细节
3.1 安全连接配置
为确保HTTPS请求的安全性,需要配置SSLContext:
java复制private CloseableHttpClient createSecureHttpClient() {
SSLContext sslContext;
try {
sslContext = SSLContexts.custom()
.loadTrustMaterial(null, (chain, authType) -> true)
.build();
} catch (Exception e) {
throw new RuntimeException("SSL context初始化失败", e);
}
return HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
}
注意:生产环境中应使用正规CA颁发的证书,此处简化处理仅用于演示。
3.2 请求重试机制
网络请求需要添加合理的重试策略:
java复制private HttpRequestRetryHandler createRetryHandler() {
return (exception, executionCount, context) -> {
if (executionCount >= 3) {
return false; // 最大重试次数
}
if (exception instanceof NoHttpResponseException) {
return true; // 服务器无响应可重试
}
if (exception instanceof SSLException) {
return false; // SSL错误不应重试
}
return false;
};
}
4. 结果解析与异常处理
4.1 标准结果格式
百度云API返回的JSON结果示例:
json复制{
"conclusion": "不合规",
"log_id": 123456789,
"data": [
{
"type": 1,
"subType": 2,
"msg": "存在色情内容",
"probability": 0.95,
"words": "敏感词示例"
}
]
}
对应的Java实体类:
java复制public class ModerationResult {
private String conclusion;
private long logId;
private List<ModerationItem> data;
// getters & setters
}
public class ModerationItem {
private int type;
private int subType;
private String msg;
private double probability;
private String words;
// getters & setters
}
4.2 异常分类处理
需要处理的典型异常情况:
| 异常类型 | 处理方式 | 重试建议 |
|---|---|---|
| 网络超时 | 记录日志并重试 | 是 |
| 认证失败 | 刷新access token | 是 |
| 参数错误 | 校验输入参数 | 否 |
| 服务限流 | 延迟后重试 | 是 |
| 系统错误 | 记录错误日志 | 视情况 |
异常处理代码示例:
java复制public ModerationResult checkText(String content) throws ModerationException {
try {
// 执行审核逻辑
} catch (IOException e) {
if (e instanceof ConnectTimeoutException) {
throw new ModerationException("连接超时", e, true);
} else if (e instanceof SocketTimeoutException) {
throw new ModerationException("读取超时", e, true);
} else {
throw new ModerationException("网络异常", e, false);
}
}
}
5. 性能优化与实践经验
5.1 连接池配置
合理配置HTTP连接池可以显著提升性能:
java复制private PoolingHttpClientConnectionManager createConnectionManager() {
PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();
manager.setMaxTotal(200); // 最大连接数
manager.setDefaultMaxPerRoute(50); // 每个路由最大连接数
manager.setValidateAfterInactivity(30000); // 空闲连接验证间隔(ms)
return manager;
}
5.2 实际使用中的经验
- 超时设置:建议连接超时设为3秒,读取超时设为5秒
- 日志记录:记录每次请求的logId便于后续排查
- 缓存策略:对重复内容可添加本地缓存
- 异步处理:对于批量审核建议使用异步方式
java复制// 异步处理示例
public CompletableFuture<ModerationResult> checkTextAsync(String content) {
return CompletableFuture.supplyAsync(() -> checkText(content));
}
5.3 监控指标建议
应当监控的关键指标:
- 请求成功率
- 平均响应时间
- 违规内容占比统计
- 各违规类型分布
- 超长文本分片情况
6. 完整工具类实现
以下是整合后的完整工具类代码:
java复制public class BaiduContentModerationUtil implements Closeable {
private static final Logger logger = LoggerFactory.getLogger(BaiduContentModerationUtil.class);
private static final String AUTH_URL = "https://aip.baidubce.com/oauth/2.0/token";
private static final String API_URL = "https://aip.baidubce.com/rest/2.0/solution/v1/text_censor/v2/user_defined";
private static final int MAX_TEXT_LENGTH = 20000;
private final String apiKey;
private final String secretKey;
private String accessToken;
private long tokenExpireTime;
private final CloseableHttpClient httpClient;
public BaiduContentModerationUtil(String apiKey, String secretKey) {
this.apiKey = apiKey;
this.secretKey = secretKey;
this.httpClient = createHttpClient();
refreshAccessToken();
}
private CloseableHttpClient createHttpClient() {
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(3000)
.setSocketTimeout(5000)
.build();
return HttpClients.custom()
.setConnectionManager(createConnectionManager())
.setDefaultRequestConfig(config)
.setRetryHandler(createRetryHandler())
.build();
}
public ModerationResult checkText(String content) throws ModerationException {
if (StringUtils.isBlank(content)) {
return new ModerationResult("合规", -1, Collections.emptyList());
}
try {
List<String> segments = splitLongText(content);
if (segments.size() == 1) {
return doCheckText(segments.get(0));
}
// 处理超长文本
List<ModerationResult> results = new ArrayList<>();
for (String segment : segments) {
results.add(doCheckText(segment));
}
return mergeResults(results);
} catch (Exception e) {
throw new ModerationException("文本审核失败", e);
}
}
private ModerationResult doCheckText(String text) throws IOException {
if (System.currentTimeMillis() > tokenExpireTime - 60000) {
refreshAccessToken();
}
HttpPost httpPost = new HttpPost(API_URL);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("access_token", accessToken));
params.add(new BasicNameValuePair("text", text));
httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
String responseBody = EntityUtils.toString(response.getEntity());
return parseResult(responseBody);
}
}
@Override
public void close() throws IOException {
httpClient.close();
}
// 其他辅助方法...
}
在实际项目中,这个工具类可以进一步扩展以下功能:
- 支持自定义审核策略
- 添加本地敏感词过滤作为前置检查
- 实现结果缓存机制
- 支持异步回调通知
- 集成Spring等框架的自动配置
我在多个生产项目中使用的经验表明,良好的工具类设计可以降低30%以上的开发工作量,同时提高系统的稳定性和可维护性。特别是在处理超长文本时,合理的分片策略能有效避免内容截断导致的审核遗漏问题。
