Springboot整合抖音小程序获取access-token图片检测V3

news2024/11/23 21:33:08

抽取配置文件

appId以及secret需要自行在抖音开放平台获取

dy:
  appId: ttb0xxxxx
  secret: 12a19a426xxxxxxxxxxxxx

获取access-token

参照文档我们调用此接口需要先获取access-token

获取access-token官方文档地址

注意事项

client_token 的有效时间为 2 个小时,重复获取 client_token 后会使上次的 client_token 失效(但有 5 分钟的缓冲时间,连续多次获取 client_token 只会保留最新的两个 client_token)。

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.hss.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zr 2024/10/12
 */

@Service
@Slf4j
public class DyService {
    @Value("${dy.appId}")
    private  String CLIENT_KEY;  // appId
    @Value("${dy.secret}")
    private  String CLIENT_SECRET;  // secret

    private static final String CLIENT_TOKEN_URL = "https://open.douyin.com/oauth/client_token/";

    /**
     * 获取 access_token
     *
     * @return 返回 access_token
     */
    public String getAccessToken() {
        // 构建请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("grant_type", "client_credential");
        requestBody.put("client_key", CLIENT_KEY);
        requestBody.put("client_secret", CLIENT_SECRET);

        // 发送 POST 请求
        HttpResponse response = HttpRequest.post(CLIENT_TOKEN_URL)
                .header("Content-Type", "application/json")
                .body(JSONUtil.toJsonStr(requestBody))  // 将请求体转换为 JSON 字符串
                .timeout(20000)  // 设置超时时间为 20 秒
                .execute();

        // 解析响应
        String responseBody = response.body();
        JSONObject res = JSON.parseObject(responseBody);

        log.info("Url: " + CLIENT_TOKEN_URL);
        log.info("body: " + JSONUtil.toJsonStr(requestBody));
        log.info("res: " + res);

        if (!"success".equals(res.getString("message"))){
           throw new ServiceException("抖音token错误:" + res.get("message"));
        }
        String token = res.getJSONObject("data").getString("access_token").toString();
        return token;
    }

}

图片检测V3

提供给开发者进行图片合法合规校验

图片检测V3原文档地址

请求参数可以使用图片链接或者base64数据,我使用的图片链接,读者有需要可以更换参数使用base64数据

  • censorImage方法传入图片url返回true表示图片合法,false表示图片不合法
  • 图片检测一次请求会检测多项如下图:(****predicts下的所有项目都为false图片才检测为合法)

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.hss.common.core.domain.R;
import com.hss.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zr 2024/10/12
 */

@Service
@Slf4j
public class DyService {
    @Value("${dy.appId}")
    private  String CLIENT_KEY;  // appId
    @Value("${dy.secret}")
    private  String CLIENT_SECRET;  // secret

    private static final String CENSOR_IMAGE_URL = "https://open.douyin.com/api/apps/v1/censor/image";
    private static final String CLIENT_TOKEN_URL = "https://open.douyin.com/oauth/client_token/";



    /**
     * 获取 access_token
     *
     * @return 返回 access_token
     */
    public String getAccessToken() {
        // 构建请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("grant_type", "client_credential");
        requestBody.put("client_key", CLIENT_KEY);
        requestBody.put("client_secret", CLIENT_SECRET);

        // 发送 POST 请求
        HttpResponse response = HttpRequest.post(CLIENT_TOKEN_URL)
                .header("Content-Type", "application/json")
                .body(JSONUtil.toJsonStr(requestBody))  // 将请求体转换为 JSON 字符串
                .timeout(20000)  // 设置超时时间为 20 秒
                .execute();

        // 解析响应
        String responseBody = response.body();
        JSONObject res = JSON.parseObject(responseBody);

        log.info("Url: " + CLIENT_TOKEN_URL);
        log.info("body: " + JSONUtil.toJsonStr(requestBody));
        log.info("res: " + res);

        if (!"success".equals(res.getString("message"))){
           throw new ServiceException("抖音token错误:" + res.get("message"));
        }
        String token = res.getJSONObject("data").getString("access_token").toString();
        return token;
    }

    /**
     * 图片合法合规校验
     * @param imageUrl
     * @return 返回 true/false
     */
    public R<Boolean> censorImage(String imageUrl) {

        String accessToken = getAccessToken();
        // 构建请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("app_id", CLIENT_KEY);
        requestBody.put("access-token", accessToken);
        requestBody.put("image", imageUrl);


        // 发送 POST 请求
        HttpResponse response = HttpRequest.post(CENSOR_IMAGE_URL)
                .header("access-token", accessToken)  // 在请求头中加入 access-token
                .header("Content-Type", "application/json")  // 设置Content-Type为application/json
                .body(JSONUtil.toJsonStr(requestBody))  // 将请求体转换为 JSON 字符串
                .timeout(20000)  // 设置超时时间
                .execute();

        // 解析响应
        String responseBody = response.body();
        log.info("Url: " + CLIENT_TOKEN_URL);
        log.info("body: " + JSONUtil.toJsonStr(requestBody));
        log.info("res: " + responseBody);

        JSONObject res = JSON.parseObject(responseBody);
        if (!"0".equals(res.getString("err_no"))){
            log.info("抖音图片审核错误:" + res.get("err_msg"));
            throw new ServiceException("抖音图片审核错误:" + res.get("err_msg"));
        }
        List<JSONObject> predicts = res.getList("predicts", JSONObject.class);
        // 使用流的方式检查是否有任何 hit 为 true 的项目
        boolean anyHitTrue = predicts.stream()
                .anyMatch(predict -> predict.getBoolean("hit"));
        if (anyHitTrue) {
            return R.ok(false, "图片含有敏感信息");
        } else {
            return R.ok(true);
        }

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2212711.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Matlab使用蚁群算法寻找最优路径

基于Matlab使用蚁群算法寻找最优路径 与Dijkstra算法使用相同的地图。 每只蚂蚁都从起点出发&#xff0c;直到抵达终点。这与Example5_1.m 中解决旅行商问题不一样&#xff0c;旅行商问题中每一代的蚂蚁都是随机从一个节点出发。 文件说明 Example5_1.m 简单对参考资料2中的…

重启Windows远程的复制粘贴功能

有些时候远程Windows电脑偶尔会出现复制粘贴失效的情况 打开任务管理器&#xff0c;进程搜索RDP 剪贴板监视程序右键关闭任务。 因为远程剪切板程序位于C:\Windows\System32&#xff0c;所以直接winr输入rdpclip.exe执行即可启动。

Java项目实战II基于Java的医院急诊系统设计与实现(开发文档+源码+数据库)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在现代医疗…

提升正则表达式性能:全面解析Golang regexp/syntax包

提升正则表达式性能&#xff1a;全面解析Golang regexp/syntax包 介绍基本概念正则表达式简介regexp/syntax包的作用 regexp/syntax包的结构核心组件结构详解ParserRegexpOpInstProg 使用Parser解析正则表达式解析正则表达式AST的结构 分析解析后的正则表达式树AST节点类型分析…

Linux下Git操作

一、基本命令 1、创建 git 目录&#xff08;工作区&#xff09; mkdir gitcode 2、创建本地仓库&#xff0c;生成 .git 隐藏目录 git init 3、设置配置项 git config user.name "xxx" git config user.email "....." 4、查看配置项 git config -l …

将SpringBoot的Maven项目打成jar包和war包

先需要明确的是&#xff0c;该项目打包的形态是可执行的jar包&#xff0c;还是在tomcat下运行的war包。 springboot自带的maven打包 1.创建一个springboot web项目 1.api控制层HelloWorld.java RestController RequestMapping("/hello") public class HelloWorld …

SpringBoot基础(五):集成JUnit5

SpringBoot基础系列文章 SpringBoot基础(一)&#xff1a;快速入门 SpringBoot基础(二)&#xff1a;配置文件详解 SpringBoot基础(三)&#xff1a;Logback日志 SpringBoot基础(四)&#xff1a;bean的多种加载方式 SpringBoot基础(五)&#xff1a;集成JUnit5 目录 一、JUnit…

使用dotnet-counters和dotnet-dump 分析.NET Core 项目内存占用问题

在.NET Core 项目部署后&#xff0c;我们往往会遇到内存占用越来越高的问题&#xff0c;但是由于项目部署在Linux上&#xff0c;因此无法使用VS的远程调试工具来排查内存占用问题。那么这篇文章我们大家一起来学习一下如何排查内存占用问题。 首先&#xff0c;我们来看一下应用…

Python | Leetcode Python题解之第478题在圆内随机生成点

题目&#xff1a; 题解&#xff1a; class Solution:def __init__(self, radius: float, x_center: float, y_center: float):self.xc x_centerself.yc y_centerself.r radiusdef randPoint(self) -> List[float]:u, theta random.random(), random.random() * 2 * mat…

rancher hello-world

创建一个Deployment, 只填名称和容器镜像rancher/hello-world 成功后: 查看日志 结果&#xff1a; 部署了工作负载。这个过程可能需要几分钟完成。 当您的工作负载部署完成后&#xff0c;它的状态将变为Active&#xff0c;您可以从项目的工作负载页面查看工作负载当前的状态…

Golang | Leetcode Golang题解之第475题供暖器

题目&#xff1a; 题解&#xff1a; func findRadius(houses, heaters []int) (ans int) {sort.Ints(houses)sort.Ints(heaters)j : 0for _, house : range houses {dis : abs(house - heaters[j])for j1 < len(heaters) && abs(house-heaters[j]) > abs(house-…

threejs 前言

Three.js 中文官方网站 一、项目结构 二、相关开源库 下面表格列举了一些Three.js相关的开源库。

【赵渝强老师】K8s中Deployment控制器与StatefulSet控制器的区别

一、K8s的Deployment与StatefulSets 在K8s中&#xff0c;Deployment将Pod部署成无状态的应用程序&#xff0c;它只关心Pod的数量、Pod更新方式、使用的镜像和资源限制等。由于是无状态的管理方式&#xff0c;因此Deployment中没有角色和顺序的概念&#xff0c;换句话说&#xf…

关于VS Studio2022如何使用scanf函数

前言&#xff1a; 小编在最近给别人安装VS2022的时候&#xff0c;忘记让他弄一段代码来解决VS不能使用scanf函数这个问题了&#xff0c;导致他编写代码的时候出错了&#xff0c;小编考虑到可能有一些读者朋友同样也会遇到这种问题&#xff0c;于是我就写下了这一篇文章来帮助一…

并发编程-线程池

并发编程-线程池 本篇我们主要围绕线程池的原理以及源码进行分析&#xff0c;事实上线程池本身并不是什么新的技术&#xff0c;而是在池化技术的思想上把一些工具类整合起来。话不多说&#xff0c;我们开始进入正题。我们先来认识一下什么是线程池 概念 线程池&#xff08;T…

Linux进程间通信(一)——管道通信

目录 前言 1.管道实现进程间通信 ①管道的所属问题 ②匿名管道通信 ③命名管道通信 2.使用管道通信实现一个进程池 ①进程池类图 ②Channel类实现 ③ProcessPoll类实现 ④代码一览 前言 在学习Linux中的进程时&#xff0c;曾提到过进程的独立性。进程独立性的是进程与进程之间…

SpringMVC后台控制端校验-表单验证深度分析与实战优化

前言 在实战开发中&#xff0c;数据校验也是十分重要的环节之一&#xff0c;数据校验大体分为三部分&#xff1a; 前端校验后端校验数据库校验 本文讲解如何在后端控制端进行表单校验的工作 案例实现 在进行项目开发的时候,前端(jquery-validate),后端,数据库都要进行相关的数据…

【数据结构】图的最短路径

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C游记》《进击的C》《Linux迷航》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、最短路径的概念二、Dijkstra算法2.1 思想2.2 实现 三、Bellman-Ford算法3.1 思想3.2 实现 四、Floyd-Warsh…

操作教程|基于DataEase用RFM分析法分析零售交易数据

DataEase开源BI工具可以在店铺运营的数据分析及可视化方面提供非常大的帮助。同样&#xff0c;在用于客户评估的RFM&#xff08;即Recency、Frequency和Monetary的简称&#xff09;分析中&#xff0c;DataEase也可以发挥出积极的价值&#xff0c;通过数据可视化大屏的方式实时展…

液态神经网络 LNN

神经网络 (NN) 是 机器学习 模仿人脑结构和运算能力以从训练数据中识别模式的算法。 通过处理和传输信息的互连人工神经元网络&#xff0c;神经网络可以执行复杂的任务&#xff0c;例如 人脸识别, 自然语言理解&#xff0c;以及无需人工协助的预测分析。 尽管神经网络是一种强…