Skip to content

百度内容审核

pom.xml

xml
		<!--百度内容审核SDK-->
        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.15.7</version>
        </dependency>

SDK默认使用slf4j-simple包进行日志输出,若需要使用自定义日志实现,可去除slf4j-simple依赖包,再额外添加相应的日志实现包即可(一个项目中有多个slf4j项目包可能会导致冲突)

maven去除slf4j-simple依赖包示例:

xml
        <!--百度内容审核SDK-->
        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.15.7</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-simple</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

默认返回JSONObject类型(org.json.JSONObject)

java
        AipContentCensor acc = new AipContentCensor(APP_ID,API_KEY,SECRET_KEY);
        JSONObject jsonObject = acc.textCensorUserDefined("你好世界");
        System.out.println(jsonObject.toString());
        JSONObject jsonObject1 = acc.textCensorUserDefined("傻逼");
        System.out.println(jsonObject1.toString(2));
        if (jsonObject1.has("data"))
            System.out.println(jsonObject1.get("data").toString());

toString打印示例

{"conclusion":"合规","log_id":16931468069262180,"isHitMd5":false,"conclusionType":1}
{
  "conclusion": "不合规",
  "log_id": 16931468074792029,
  "data": [{
    "msg": "存在低俗辱骂不合规",
    "conclusion": "不合规",
    "hits": [{
      "wordHitPositions": [{
        "positions": [[
          0,
          1
        ]],
        "label": "500200",
        "keyword": "傻逼"
      }],
      "probability": 1,
      "datasetName": "百度默认文本反作弊库",
      "words": ["傻逼"],
      "modelHitPositions": [[
        0,
        1,
        1
      ]]
    }],
    "subType": 5,
    "conclusionType": 2,
    "type": 12
  }],
  "isHitMd5": false,
  "conclusionType": 2
}
[{"msg":"存在低俗辱骂不合规","conclusion":"不合规","hits":[{"wordHitPositions":[{"positions":[[0,1]],"label":"500200","keyword":"傻逼"}],"probability":1,"datasetName":"百度默认文本反作弊库","words":["傻逼"],"modelHitPositions":[[0,1,1]]}],"subType":5,"conclusionType":2,"type":12}]

注意JSONObject类型无法直接作为添加了@ResponseBody注解控制层的返回值,不是Spring MVC中默认支持的数据类型,可以使用toMap()方法转化为Map类型

java
            Map<String, Object> map = jsonObject1.toMap();
            System.out.println(map);
            System.out.println(map.get("data"));

打印结果

{conclusion=不合规, log_id=16931474587780050, data=[{msg=存在低俗辱骂不合规, conclusion=不合规, hits=[{wordHitPositions=[{positions=[[0, 1]], label=500200, keyword=傻逼}], probability=1.0, datasetName=百度默认文本反作弊库, words=[傻逼], modelHitPositions=[[0, 1, 1.0]]}], subType=5, conclusionType=2, type=12}], isHitMd5=false, conclusionType=2}
[{msg=存在低俗辱骂不合规, conclusion=不合规, hits=[{wordHitPositions=[{positions=[[0, 1]], label=500200, keyword=傻逼}], probability=1.0, datasetName=百度默认文本反作弊库, words=[傻逼], modelHitPositions=[[0, 1, 1.0]]}], subType=5, conclusionType=2, type=12}]

工具类代码

AipContentCensorClientConfig.java

java
import com.baidu.aip.contentcensor.AipContentCensor;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = "ruoyi.censor")
@Component
@Data
public class AipContentCensorClientConfig {
    /**
     * 百度云审核的AppID
     */
    private String AppID;

    /**
     * 百度云审核的Api Key
     */
    private String API_Key;

    /**
     * 百度云审核的Secret Key
     */
    private String Secret_Key;

    @Bean
    AipContentCensor commonTextCensorClient() {
        /**
         * 可以选择在客户端中添加参数,参考 https://ai.baidu.com/ai-doc/ANTIPORN/ik3h6xdze
         * 如:
         *         // 可选:设置网络连接参数
         *         client.setConnectionTimeoutInMillis(2000);
         *         client.setSocketTimeoutInMillis(60000);
         *
         *         // 可选:设置代理服务器地址, http和socket二选一,或者均不设置
         *         client.setHttpProxy("proxy_host", proxy_port);  // 设置http代理
         *         client.setSocketProxy("proxy_host", proxy_port);  // 设置socket代理
         *
         *         // 可选:设置log4j日志输出格式,若不设置,则使用默认配置
         *         // 也可以直接通过jvm启动参数设置此环境变量
         *         System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");
         */
        return new AipContentCensor(AppID, API_Key, Secret_Key);
    }
}

配置信息在application.yaml文件下

ContentWithCensorStateEnum.java

java
/**
 * 内容审核状态
 */
public enum ContentWithCensorStateEnum {
    /**
     * 正常状态
     */
    ADD,

    /**
     * 删除状态
     */
    REMOVE,

    /**
     * Ai审核不通过
     */
    CENSOR_FAIL,

    /**
     * Ai审核疑似不通过
     */
    CENSOR_SUSPECT,

    /**
     * Ai审核错误
     */
    CENSOR_ERROR,

    /**
     * 人工审核不通过
     */
    BLOCK
}

CensorResult.java

java
import com.ruoyi.common.enums.ContentWithCensorStateEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CensorResult {

    /**
     * 内容是否审核通过
     */
    Boolean isPass;

    /**
     * 审核结果
     */
    ContentWithCensorStateEnum contentWithCensorStateEnum;

    /**
     * 文字审核结果的Json字符串
     */
    String textCensorJson;

    /**
     * 图片审核结果的Json字符串
     */
    String imageCensorJson;

}

AipContentCensorClientUtils.java

java
import com.baidu.aip.contentcensor.AipContentCensor;
import com.baidu.aip.contentcensor.EImgType;
import com.ruoyi.common.enums.ContentWithCensorStateEnum;
import com.ruoyi.jkqcyl.domain.CensorResult;
import lombok.Data;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

@Component
@Data
public class AipContentCensorClientUtils {

    /**
     * 百度文本审核,识别审核结果的JSON KEY
     */
    private static String CENSOR_CONCLUSION_TYPE_KEY = "conclusionType";

    @Autowired
    private AipContentCensor commonTextCensorClient;

    /**
     * 获取常规文本审核结果
     *
     * @param content 内容
     * @return 百度内容审核JSON
     */
    public CensorResult getCommonTextCensorResult(String content) {

        //如果内容为空,则直接返回
        if (content == null || content.isEmpty()) {
            return getCensorResult(null);
        }

        try {
            JSONObject response = commonTextCensorClient.textCensorUserDefined(content);
            return getCensorResult(response);
        } catch (Exception exception) {
            System.out.println(exception);
            return getCensorResult(null);
        }
    }

    /**
     * 获取图片审核结果
     *
     * @param imagePath 图片的本地路径或者Url
     * @return 百度图片审核JSON
     */
    public CensorResult getImageCensorResult(String imagePath) {

        //如果内容为空,则直接返回
        if (imagePath == null || imagePath.isEmpty()) {
            return getCensorResult(null);
        }

        try {
            JSONObject response = null;
            if (imagePath.contains("http")){
                response = commonTextCensorClient.imageCensorUserDefined(imagePath, EImgType.URL, null);
            }else {
                response = commonTextCensorClient.imageCensorUserDefined(imagePath, EImgType.FILE, null);
            }
            return getCensorResult(response);
        } catch (Exception exception) {
            System.out.println(exception);
            return getCensorResult(null);
        }
    }

    public CensorResult getImageCensorResult(InputStream inputStream){

        //如果内容为空,则直接返回
        if (inputStream == null) {
            return getCensorResult(null);
        }

        byte[] imgData = getImgData(inputStream);

        try {
            JSONObject response = commonTextCensorClient.imageCensorUserDefined(imgData, null);
            return getCensorResult(response);
        } catch (Exception exception) {
            System.out.println(exception);
            return getCensorResult(null);
        }
    }

    /**
     * 获取审核结果
     *
     * @param clientJsonObject 百度审核的JSON字段
     * @return 审核结果
     */
    private CensorResult getCensorResult(JSONObject clientJsonObject) {

        //获取代表审核结果的字段
        //审核结果类型,可取值1.合规,2.不合规,3.疑似,4.审核失败
        int conclusionType;

        //如果是null就直接判定为失败
        if (clientJsonObject == null) {
            conclusionType = 4;
        } else {
            conclusionType = clientJsonObject.getInt(CENSOR_CONCLUSION_TYPE_KEY);
        }

        try {
            ContentWithCensorStateEnum result;

            switch (conclusionType) {
                case 1:
                    //合规情况
                    result = ContentWithCensorStateEnum.ADD;
                    break;
                case 2:
                    //不合规情况
                    result = ContentWithCensorStateEnum.CENSOR_FAIL;
                    break;
                case 3:
                    //疑似不合规
                    result = ContentWithCensorStateEnum.CENSOR_SUSPECT;
                    break;
                default:
                    //审核失败和其他情况,都归结到censor_error上去
                    result = ContentWithCensorStateEnum.CENSOR_ERROR;
                    break;
            }

            //过审要求:只能是合规情况
            //解释:因为百度云控制台是可以调节不合规和疑似不合规的参数值的,因此这里只写合规情况就可以了
            boolean isPass = result == ContentWithCensorStateEnum.ADD;

            return new CensorResult(isPass, result, clientJsonObject != null ? clientJsonObject.toString() : null, null);

        } catch (Exception exception) {
            System.out.println(exception);
            //如果出错,就直接返回true
            return new CensorResult(true, null, null, null);
        }
    }

    /**
     * 处理图片的输入流
     * @param inputStream 图片的输入流
     * @return 返回字节数组
     */
    private byte[] getImgData(InputStream inputStream){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        byte[] imgData = null;
        int len;
        try{
            while ((len = inputStream.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
        imgData = baos.toByteArray();
        return imgData;
    }
}