Spring Boot 集成国内AI,包含文心一言、通义千问和讯飞星火平台实战教程

Spring Boot 集成国内AI,包含文心一言、通义千问和讯飞星火平台实战教程

  • 一、项目结构
  • 二、添加Maven依赖
  • 三、配置API密钥 (application.yml)
  • 四、配置类
    • 1. AI配置类 (AiProperties.java)
    • 2. 启用配置类 (AiConfig.java)
  • 五、服务层实现
    • 1. 文心一言服务 (WenxinService.java)
    • 2. 通义千问服务 (QianwenService.java)
    • 3. 讯飞星火服务 (XinghuoService.java)
  • 六、统一控制器 (AiController.java)
  • 七、安全增强配置
    • 1. 添加API密钥保护(自定义Filter)
    • 2. 添加Rate Limiting(使用Resilience4j)
  • 八、应用入口 (AiIntegrationApplication.java)
  • 九、测试示例
  • 十、最佳实践建议

Spring Boot集成国内主流AI平台的详细实现方案,包含文心一言、通义千问和讯飞星火的对接代码,助力快速构建智能应用。

一、项目结构

ai-integration-demo/
├── src/main/java
│   ├── com/example/ai
│   │   ├── config                # 配置类
│   │   ├── controller            # API控制器
│   │   ├── service               # 服务层
│   │   │   ├── impl              # 服务实现
│   │   ├── dto                   # 数据传输对象
├── resources
│   ├── application.yml           # 配置文件

二、添加Maven依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- HTTP客户端 --><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.11.0</version></dependency><!-- JSON处理 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><!-- 配置处理 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>
</dependencies>

三、配置API密钥 (application.yml)

ai:wenxin:api-key: YOUR_WENXIN_API_KEYsecret-key: YOUR_WENXIN_SECRET_KEYapi-url: https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completionsqianwen:api-key: YOUR_QIANWEN_API_KEYapi-url: https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generationxinghuo:api-key: YOUR_XINGHUO_API_KEYsecret: YOUR_XINGHUO_SECRETappid: YOUR_XINGHUO_APPIDapi-url: https://spark-api.xf-yun.com/v3.5/chat

四、配置类

1. AI配置类 (AiProperties.java)

@ConfigurationProperties(prefix = "ai")
@Data
public class AiProperties {private Wenxin wenxin;private Qianwen qianwen;private Xinghuo xinghuo;@Datapublic static class Wenxin {private String apiKey;private String secretKey;private String apiUrl;}@Datapublic static class Qianwen {private String apiKey;private String apiUrl;}@Datapublic static class Xinghuo {private String apiKey;private String secret;private String appid;private String apiUrl;}
}

2. 启用配置类 (AiConfig.java)

@Configuration
@EnableConfigurationProperties(AiProperties.class)
public class AiConfig {@Beanpublic OkHttpClient okHttpClient() {return new OkHttpClient();}
}

五、服务层实现

1. 文心一言服务 (WenxinService.java)

@Service
@RequiredArgsConstructor
public class WenxinService {private final AiProperties aiProperties;private final OkHttpClient okHttpClient;// 获取AccessTokenprivate String getAccessToken() {String url = "https://aip.baidubce.com/oauth/2.0/token?"+ "grant_type=client_credentials"+ "&client_id=" + aiProperties.getWenxin().getApiKey()+ "&client_secret=" + aiProperties.getWenxin().getSecretKey();Request request = new Request.Builder().url(url).get().build();try (Response response = okHttpClient.newCall(request).execute()) {String responseBody = response.body().string();ObjectMapper objectMapper = new ObjectMapper();JsonNode rootNode = objectMapper.readTree(responseBody);return rootNode.get("access_token").asText();} catch (Exception e) {throw new RuntimeException("获取文心一言Token失败", e);}}public String chatCompletion(String prompt) {String accessToken = getAccessToken();String url = aiProperties.getWenxin().getApiUrl() + "?access_token=" + accessToken;JSONObject body = new JSONObject();body.put("messages", new JSONArray().put(new JSONObject().put("role", "user").put("content", prompt)));Request request = new Request.Builder().url(url).post(RequestBody.create(body.toString(), MediaType.get("application/json"))).build();try (Response response = okHttpClient.newCall(request).execute()) {if (!response.isSuccessful()) {throw new RuntimeException("文心一言API请求失败: " + response);}String responseBody = response.body().string();JSONObject jsonResponse = new JSONObject(responseBody);return jsonResponse.getJSONObject("result").getString("content");} catch (Exception e) {throw new RuntimeException("调用文心一言API出错", e);}}
}

2. 通义千问服务 (QianwenService.java)

@Service
@RequiredArgsConstructor
public class QianwenService {private final AiProperties aiProperties;private final OkHttpClient okHttpClient;public String generateText(String prompt) {JSONObject body = new JSONObject();body.put("model", "qwen-turbo");JSONObject input = new JSONObject();input.put("prompt", prompt);body.put("input", input);JSONObject parameters = new JSONObject();parameters.put("temperature", 0.85);parameters.put("top_p", 0.8);parameters.put("max_tokens", 1500);body.put("parameters", parameters);Request request = new Request.Builder().url(aiProperties.getQianwen().getApiUrl()).header("Authorization", "Bearer " + aiProperties.getQianwen().getApiKey()).post(RequestBody.create(body.toString(), MediaType.get("application/json"))).build();try (Response response = okHttpClient.newCall(request).execute()) {if (!response.isSuccessful()) {throw new RuntimeException("通义千问API请求失败: " + response);}String responseBody = response.body().string();JSONObject jsonResponse = new JSONObject(responseBody);return jsonResponse.getJSONObject("output").getString("text");} catch (Exception e) {throw new RuntimeException("调用通义千问API出错", e);}}
}

3. 讯飞星火服务 (XinghuoService.java)

@Service
@RequiredArgsConstructor
public class XinghuoService {private final AiProperties aiProperties;private final OkHttpClient okHttpClient;public String chat(String prompt) {try {// 构造鉴权URLString authUrl = generateAuthUrl();// 构造请求体JSONObject body = new JSONObject();JSONObject header = new JSONObject();header.put("app_id", aiProperties.getXinghuo().getAppid());JSONObject parameter = new JSONObject();JSONObject chat = new JSONObject();chat.put("domain", "generalv3.5");chat.put("temperature", 0.5);chat.put("max_tokens", 4096);parameter.put("chat", chat);JSONObject payload = new JSONObject();JSONObject message = new JSONObject();JSONArray text = new JSONArray();text.put(new JSONObject().put("role", "user").put("content", prompt));message.put("text", text);payload.put("message", message);body.put("header", header);body.put("parameter", parameter);body.put("payload", payload);// 发送请求Request request = new Request.Builder().url(authUrl).post(RequestBody.create(body.toString(), MediaType.get("application/json"))).build();try (Response response = okHttpClient.newCall(request).execute()) {if (!response.isSuccessful()) {throw new RuntimeException("讯飞星火API请求失败: " + response);}String responseBody = response.body().string();JSONObject jsonResponse = new JSONObject(responseBody);return extractContent(jsonResponse);}} catch (Exception e) {throw new RuntimeException("调用讯飞星火API出错", e);}}// 生成带鉴权信息的URLprivate String generateAuthUrl() throws ParseException, InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {String apiUrl = aiProperties.getXinghuo().getApiUrl();String host = new URL(apiUrl).getHost();String path = new URL(apiUrl).getPath();// 创建日期对象SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);sdf.setTimeZone(TimeZone.getTimeZone("GMT"));String date = sdf.format(new Date());// 构造签名String signatureOrigin = "host: " + host + "\n";signatureOrigin += "date: " + date + "\n";signatureOrigin += "POST " + path + " HTTP/1.1";Mac mac = Mac.getInstance("hmacsha256");SecretKeySpec secretKeySpec = new SecretKeySpec(aiProperties.getXinghuo().getSecret().getBytes("UTF-8"), "hmacsha256");mac.init(secretKeySpec);byte[] signatureSha = mac.doFinal(signatureOrigin.getBytes("UTF-8"));String signature = Base64.getEncoder().encodeToString(signatureSha);// 构造授权头String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"",aiProperties.getXinghuo().getApiKey(), "hmac-sha256", "host date request-line", signature);return apiUrl + "?authorization=" + Base64.getEncoder().encodeToString(authorization.getBytes("UTF-8"))+ "&date=" + URLEncoder.encode(date, "UTF-8")+ "&host=" + URLEncoder.encode(host, "UTF-8");}// 提取响应内容private String extractContent(JSONObject response) {JSONObject payload = response.getJSONObject("payload");JSONObject message = payload.getJSONObject("message");JSONArray text = message.getJSONArray("text");StringBuilder result = new StringBuilder();for (int i = 0; i < text.length(); i++) {JSONObject textObj = text.getJSONObject(i);if (textObj.has("content")) {result.append(textObj.getString("content"));}}return result.toString();}
}

六、统一控制器 (AiController.java)

@RestController
@RequestMapping("/api/ai")
@RequiredArgsConstructor
public class AiController {private final WenxinService wenxinService;private final QianwenService qianwenService;private final XinghuoService xinghuoService;@PostMapping("/wenxin")public ResponseEntity<String> wenxinChat(@RequestBody @Valid AiRequest request) {return ResponseEntity.ok(wenxinService.chatCompletion(request.getPrompt()));}@PostMapping("/qianwen")public ResponseEntity<String> qianwenGenerate(@RequestBody @Valid AiRequest request) {return ResponseEntity.ok(qianwenService.generateText(request.getPrompt()));}@PostMapping("/xinghuo")public ResponseEntity<String> xinghuoChat(@RequestBody @Valid AiRequest request) {return ResponseEntity.ok(xinghuoService.chat(request.getPrompt()));}@Datastatic class AiRequest {@NotBlank(message = "提示语不能为空")private String prompt;}
}

七、安全增强配置

1. 添加API密钥保护(自定义Filter)

@Component
@RequiredArgsConstructor
public class ApiKeyFilter extends OncePerRequestFilter {private final AiProperties aiProperties;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {String clientId = request.getHeader("X-API-CLIENT-ID");String clientSecret = request.getHeader("X-API-CLIENT-SECRET");// 验证客户端凭证if (!isValidCredentials(clientId, clientSecret)) {response.sendError(HttpStatus.UNAUTHORIZED.value(), "无效的API凭证");return;}filterChain.doFilter(request, response);}private boolean isValidCredentials(String clientId, String clientSecret) {// 这里应该是从数据库或配置中读取验证信息// 简化示例:使用配置中的文心API密钥做演示return clientId != null && clientSecret != null && clientId.equals("demo-app") && clientSecret.equals(aiProperties.getWenxin().getApiKey());}
}

2. 添加Rate Limiting(使用Resilience4j)

@Configuration
public class RateLimiterConfig {@Beanpublic RateLimiter wenxinRateLimiter() {return RateLimiter.of("wenxin-limiter", RateLimiterConfig.custom().limitRefreshPeriod(Duration.ofSeconds(10)).limitForPeriod(5).timeoutDuration(Duration.ofSeconds(5)).build());}
}// 在控制器中使用
@RestController
@RequestMapping("/api/ai")
public class AiController {private final RateLimiter wenxinRateLimiter;@PostMapping("/wenxin")@RateLimiter(name = "wenxin-limiter")public ResponseEntity<String> wenxinChat(@RequestBody AiRequest request) {// ...}
}

八、应用入口 (AiIntegrationApplication.java)

@SpringBootApplication
public class AiIntegrationApplication {public static void main(String[] args) {SpringApplication.run(AiIntegrationApplication.class, args);}
}

九、测试示例

使用cURL测试:

# 通义千问测试
curl -X POST http://localhost:8080/api/ai/qianwen \-H "Content-Type: application/json" \-d '{"prompt": "用100字介绍Spring Boot"}'# 文心一言测试
curl -X POST http://localhost:8080/api/ai/wenxin \-H "Content-Type: application/json" \-d '{"prompt": "用Java写一个快速排序算法"}'# 讯飞星火测试
curl -X POST http://localhost:8080/api/ai/xinghuo \-H "Content-Type: application/json" \-d '{"prompt": "如何做好电商运营"}'

十、最佳实践建议

  1. 异步处理:使用@Async注解异步调用AI接口,避免阻塞
  2. 缓存结果:对常见问题的结果进行缓存,减少API调用
  3. 错误重试:实现指数退避重试机制处理临时错误
  4. 流量控制:针对不同AI平台设置不同的QPS限制
  5. 统一接口:创建统一的AI门面服务,提供平台无关的调用
@Service
public class AiFacadeService {private enum AiProvider { WENXIN, QIANWEN, XINGHUO }private final WenxinService wenxinService;private final QianwenService qianwenService;private final XinghuoService xinghuoService;public String unifiedChat(String prompt) {// 简单轮询策略AiProvider[] providers = AiProvider.values();AiProvider provider = providers[(int)(System.currentTimeMillis() % providers.length)];switch (provider) {case WENXIN: return wenxinService.chatCompletion(prompt);case QIANWEN: return qianwenService.generateText(prompt);case XINGHUO: return xinghuoService.chat(prompt);default: throw new IllegalStateException("未知的AI提供商");}}
}

本项目提供了完整的企业级Spring Boot集成国内主流AI平台的实现方案,可根据实际需求进行扩展和优化。

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

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

相关文章

Elastic Search 学习笔记

1. Elasticsearch 是什么&#xff1f;有哪些应用场景&#xff1f; Elasticsearch 整体原理流程&#xff1f; Elasticsearch 是一个为海量数据提供近实时搜索和分析能力的分布式搜索引擎&#xff0c;广泛应用于全文检索、日志分析和大数据处理场景中。 Elasticsearch 整体原理…

动态规划之斐波那契数(一)

解法一&#xff1a;递归 class Solution { public:int fib(int n) {if(n<2) return n;return fib(n-1)fib(n-2);} }; 解法二&#xff1a;dp class Solution { public:int fib(int N) {if (N < 1) return N;int dp[2];dp[0] 0;dp[1] 1;for (int i 2; i < N; i) {…

如何设置爬虫的访问频率?

设置爬虫的访问频率是爬虫开发中的一个重要环节&#xff0c;尤其是在爬取大型网站&#xff08;如1688&#xff09;时&#xff0c;合理的访问频率可以避免对目标网站造成过大负担&#xff0c;同时也能降低被封禁的风险。以下是一些常见的方法和建议&#xff0c;帮助你合理设置爬…

前端面试六之axios

一、axios简介 Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;用于浏览器和 Node.js 环境。在浏览器端&#xff0c;Axios 的底层实现是基于原生的 XMLHttpRequest&#xff08;XHR&#xff09;。它对 XHR 进行了封装&#xff0c;增加了 Promise 支持、自动转换 JSON 数据…

模板方法模式Template Method Pattern

模式定义 定义一个操作中算法的骨架&#xff0c;而将一些步骤延迟到子类中&#xff0c;模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 类行为型模式 模式结构 AbstractClass&#xff1a;抽象类ConcreteClass&#xff1a;具体子类 只有类之间的继…

【行云流水AI笔记】游戏里面的强化学习使用场景

强化学习在游戏中的应用已从早期的棋类博弈扩展到现代复杂游戏的全流程优化&#xff0c;以下是结合最新技术进展的核心应用场景及典型案例&#xff1a; 一、竞技游戏的策略突破 1. 策略博弈类游戏 代表案例&#xff1a;AlphaGo/AlphaZero&#xff08;围棋&#xff09;、Alph…

使用Python和PyTorch框架,基于RetinaNet模型进行目标检测,包含数据准备、模型训练、评估指标计算和可视化

下面是一个完整的实现方案,使用Python和PyTorch框架,基于RetinaNet模型进行目标检测,包含数据准备、模型训练、评估指标计算和可视化。 import os import numpy as np import matplotlib.pyplot as plt import torch import torchvision from torchvision.models.detection…

springboot服务如何获取pod当前ip方案及示例

在 Kubernetes 集群中&#xff0c;Spring Boot 服务获取 Pod 当前 IP 的方案主要有两种&#xff1a;通过环境变量注入 或 通过 Java 代码动态获取网络接口 IP。以下是两种方案的详细说明及示例&#xff1a; 方案一&#xff1a;通过 Kubernetes Downward API 注入环境变量 原理…

1.MySQL三层结构

1.所谓安装的Mysql数据库&#xff0c;就是在电脑上安装了一个数据库管理系统&#xff08;【DBMS】database manage system&#xff09;&#xff0c;这个管理程序可以管理多个数据库。 2.一个数据库中可以创建多个表&#xff0c;以保存数据&#xff08;信息&#xff09;。【数据…

[深度学习]目标检测基础

目录 一、实验目的 二、实验环境 三、实验内容 3.1 LM_BoundBox 3.1.1 实验代码 3.1.2 实验结果 3.2 LM_Anchor 3.2.1 实验代码 3.2.2 实验结果 3.3 LM_Multiscale-object-detection 3.3.1 实验代码 3.3.2 实验结果 四、实验小结 一、实验目的 了解python语…

ALOHA机器人平台:低成本、高精度双臂操作及其进展深度解析

原创1从感知决策到具身智能的技术跃迁与挑战(基座模型与VLA模型)2ALOHA机器人平台&#xff1a;低成本、高精度双臂操作及其进展深度解析3(上)通用智能体与机器人Transformer&#xff1a;Gato和RT-1技术解析及与LLM Transformer的异同4(下)通用智能体与机器人Transformer&#x…

C++: 类 Class 的基础用法

&#x1f3f7;️ 标签&#xff1a;C、面向对象、类、构造函数、成员函数、封装、继承、多态 &#x1f4c5; 更新时间&#xff1a;2025年6月15日 &#x1f4ac; 欢迎在评论区留言交流你的理解与疑问&#xff01; 文章目录 前言一、什么是类&#xff1f;二、类的定义1.基本语法2.…

Java EE与Jakarta EE命名空间区别

在 Java 生态中&#xff0c;javax 和 jakarta 代表了 企业级 Java 规范&#xff08;Java EE/Jakarta EE&#xff09;的命名空间演进&#xff0c;核心区别在于归属权和管理组织的变更。以下是详细对比&#xff1a; 1. 历史背景 javax&#xff1a; 源自 Java EE&#xff08;Java …

2 Studying《Arm A715 Technical Reference Manual》

目录 2. The Cortex‑A715 core 2.1 Cortex‑A715 core features 2.2 Cortex‑A715 core confifiguration options 2.3 DSU-110 dependent features 2.4 Supported standards and specifications 2.6 Design tasks 3. Technical overview 3.1 Core components 3.2 Int…

使用Nodejs尝试小程序后端服务编写:简单的待办事项管理demo

文章目录 结构demo步骤demo运行效果API测试(1) 添加待办事项(2) 获取所有待办事项(3) 切换完成状态(4) 删除待办事项 API测试-RESTClient一些其他的高级功能环境变量管理不同环境配置授权认证 测试需要登录的接口保存响应测试脚本编写自动化测试 bug解决 结构 尝试写一个简单的…

CSS“多列布局”

多列布局是一种非常常见的布局方式&#xff0c;适用于内容丰富的页面&#xff0c;如新闻网站、杂志或博客。 一、CSS多列布局概述 CSS多列布局允许我们将内容分成多个垂直列&#xff0c;使页面布局更加灵活和多样化。多列布局的主要属性包括 ​​column-count​​、​​col…

Pump上狙击机制的功能优势和实战教学

加密世界的发展永远伴随着速度的革命。无论是新的 Token 上线&#xff0c;还是热点项目的第一波流动性注入&#xff0c;抢先一步往往意味着利润的几何级增长。在这个讲究「秒杀」与「先机」的赛道中&#xff0c;一项关键策略正悄然成为链上操作者的常规武器——狙击&#xff08…

条件收敛的级数中项必须趋于 0,正负项抵消,但趋于 0 的速度不需要“足够快”

条件收敛的级数中&#xff0c;项必须趋于 0&#xff0c;但趋于 0 的速度不需要“足够快”的原因可以从以下几个方面理解&#xff1a; 1. 收敛的必要条件&#xff1a;项趋于 0 对于任何收敛的级数&#xff08;无论是绝对收敛还是条件收敛&#xff09;&#xff0c;都必须满足 li…

Tomcat 和 Spring MVC

Tomcat 和 Spring MVC 是 Java Web 开发中两大核心组件&#xff0c;分别承担不同的角色&#xff1a; 一、Tomcat 定义 Apache Tomcat 是一个开源的 Servlet 容器&#xff08;也称为 Servlet 引擎&#xff09;&#xff0b; JSP 引擎&#xff0c;实现了 Java EE&#xff08;现称 …

【微服务】134:SpringCloud

今天是刘小爱自学Java的第134天。 感谢你的观看&#xff0c;谢谢你。 image 学习内容安排如下&#xff1a; SpringCloud的接触。利用SpringCloud搭建微服务架构&#xff0c;当然这个估计要3天时间才能完成&#xff0c;今天主要是注册中心Eureka的学习。 一、SpringCloud 微服务…