Java开发视角:大模型API调用实战(SpringBoot集成通义千问,附完整代码)

随着大模型技术的普及,越来越多的Java项目开始集成大模型能力——无论是智能客服、文本生成,还是代码辅助、数据解析,大模型都能显著提升开发效率和产品体验。作为Java开发工程师,掌握大模型API的调用方法,已经成为一项重要的技能。

今天就从Java开发的角度,分享SpringBoot集成通义千问大模型API的完整实战流程,涵盖环境准备、依赖配置、接口开发、异常处理等核心步骤,提供可直接复制运行的代码,新手也能快速上手,轻松实现大模型能力集成。

说明:本文以通义千问为例(阿里云旗下大模型,接口稳定、文档清晰,适合企业和开发者使用),核心调用逻辑适用于其他主流大模型(如GPT、文心一言),只需修改少量配置即可适配。

一、前期准备

广子:新用户可以免费使用或者用积分免费兑换云服务器!积分还可以用来换实物! 雨云专属注册通道

1. 大模型API密钥获取

要调用通义千问API,首先需要获取API密钥(ak、sk),步骤如下:

  1. 登录阿里云官网,搜索“通义千问”,进入通义千问控制台(需完成实名认证);

  2. 进入“API调用”模块,创建应用,获取AccessKey ID(ak)和AccessKey Secret(sk);

  3. 注意:ak和sk是调用API的核心凭证,请勿泄露,建议放在配置文件中,避免硬编码。

2. 开发环境准备

本次实战使用的开发环境,确保与日常Java开发环境一致即可,无需额外安装特殊工具:

  • JDK:1.8及以上(推荐1.8,兼容性最好);

  • 开发工具:IDEA(推荐2021及以上版本);

  • 框架:SpringBoot 2.7.x(稳定版本,避免使用过高版本导致依赖冲突);

  • 依赖管理:Maven(自动管理依赖,简化配置)。

二、SpringBoot项目搭建与配置

1. 创建SpringBoot项目

打开IDEA,创建一个新的SpringBoot项目,步骤如下:

  1. 选择“Spring Initializr”,填写项目基本信息(Group、Artifact、Package等);

  2. 选择依赖:仅需勾选“Spring Web”(用于开发接口,接收前端请求);

  3. 点击“Finish”,完成项目创建,等待Maven下载依赖,生成基础项目结构。

2. 配置依赖(pom.xml)

通义千问API调用需要依赖HTTP请求工具和JSON解析工具,在pom.xml中添加以下依赖,无需额外引入其他大模型相关依赖(直接通过HTTP调用API):

<!-- HTTP请求工具:OkHttp,比原生HttpURLConnection更简洁、高效 -->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.11.0</version>
</dependency>

<!-- JSON解析工具:FastJSON,用于解析请求参数和响应结果 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>

<!-- lombok:简化实体类编写,可选,若不使用可手动编写get/set方法 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

添加完成后,点击Maven刷新按钮,下载依赖包,确保无依赖冲突。

3. 配置文件(application.yml)

将通义千问API的ak、sk、请求地址等配置信息,写入application.yml文件,避免硬编码,方便后续修改:

server:
  port: 8082 # 项目端口,避免与其他项目冲突
tongyi:
  api:
    url: https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation # 通义千问文本生成API地址
    ak: 你的AccessKey ID # 替换为自己的ak
    sk: 你的AccessKey Secret # 替换为自己的sk
    model: qwen-turbo # 调用的模型版本,qwen-turbo为轻量版,适合测试和快速集成

三、核心代码开发

本次实战开发核心功能:接收前端传入的提问文本,调用通义千问API,获取大模型的响应结果,返回给前端。整体代码分为3个部分:实体类(请求/响应)、工具类(API调用)、控制层(接口暴露)。

1. 实体类(请求与响应)

创建实体类,用于接收前端请求参数和封装大模型响应结果,使用lombok简化代码:

package com.example.qwenapi.entity;

import lombok.Data;

/**
 * 前端请求实体:接收用户提问
 */
@Data
public class QwenRequest {
    // 用户提问文本
    private String question;
}

/**
 * 大模型响应实体:封装通义千问API返回结果
 */
@Data
public class QwenResponse {
    // 响应状态码(自定义:200成功,500失败)
    private Integer code;
    // 响应信息
    private String message;
    // 大模型返回的回答内容
    private String answer;
}

2. 工具类(通义千问API调用)

创建工具类,封装API调用逻辑,包括请求签名(通义千问API需要签名验证)、HTTP请求发送、响应结果解析,这是核心部分:

package com.example.qwenapi.util;

import com.alibaba.fastjson.JSONObject;
import com.example.qwenapi.entity.QwenResponse;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;

@Component
public class QwenApiUtil {

    // 从配置文件中读取通义千问API相关配置
    @Value("${tongyi.api.url}")
    private String apiUrl;
    @Value("${tongyi.api.ak}")
    private String ak;
    @Value("${tongyi.api.sk}")
    private String sk;
    @Value("${tongyi.api.model}")
    private String model;

    // OkHttp客户端,全局单例即可
    private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient();

    /**
     * 调用通义千问API,获取回答
     * @param question 用户提问文本
     * @return 封装后的响应结果
     */
    public QwenResponse getQwenAnswer(String question) {
        QwenResponse response = new QwenResponse();
        try {
            // 1. 构建请求参数(按照通义千问API文档要求构建)
            JSONObject requestBody = new JSONObject();
            requestBody.put("model", model);
            // 构建对话内容,支持多轮对话,这里简化为单轮对话
            JSONObject messages = new JSONObject();
            messages.put("role", "user"); // 角色:user(用户)、assistant(助手)
            messages.put("content", question);
            requestBody.put("messages", new JSONObject[]{messages});
            requestBody.put("temperature", 0.7); // 温度,0~1,值越大回答越随机

            // 2. 生成请求签名(通义千问API必须验证签名,否则会报错)
            String date = new Date().toGMTString();
            String signature = generateSignature(date, requestBody.toString());

            // 3. 发送POST请求
            Request request = new Request.Builder()
                    .url(apiUrl)
                    .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), requestBody.toString()))
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Date", date)
                    .addHeader("Authorization", "阿里云 " + ak + ":" + signature)
                    .build();

            // 4. 接收响应并解析
            Response okResponse = OK_HTTP_CLIENT.newCall(request).execute();
            if (okResponse.isSuccessful() && okResponse.body() != null) {
                String responseBody = okResponse.body().string();
                JSONObject jsonObject = JSONObject.parseObject(responseBody);
                // 解析大模型返回的回答内容
                String answer = jsonObject.getJSONObject("output").getJSONArray("choices").getJSONObject(0).getString("message");
                response.setCode(200);
                response.setMessage("调用成功");
                response.setAnswer(answer);
            } else {
                response.setCode(500);
                response.setMessage("API调用失败,响应状态:" + okResponse.code());
            }
        } catch (Exception e) {
            response.setCode(500);
            response.setMessage("API调用异常:" + e.getMessage());
            e.printStackTrace();
        }
        return response;
    }

    /**
     * 生成请求签名(通义千问API签名规则)
     * @param date 请求时间(GMT格式)
     * @param requestBody 请求体字符串
     * @return 签名后的字符串
     * @throws Exception 签名过程中可能出现的异常
     */
    private String generateSignature(String date, String requestBody) throws Exception {
        // 签名规则:StringToSign = HTTP方法 + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + 路径
        String contentMd5 = Base64.getEncoder().encodeToString(requestBody.getBytes(StandardCharsets.UTF_8));
        String path = apiUrl.substring(apiUrl.indexOf("/api"));
        String stringToSign = "POST" + "\n" + contentMd5 + "\n" + "application/json" + "\n" + date + "\n" + path;

        // 使用HmacSHA1算法生成签名
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(new SecretKeySpec(sk.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
        byte[] signatureBytes = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(signatureBytes);
    }
}

3. 控制层(暴露接口)

创建控制层,开发一个简单的POST接口,接收前端请求,调用工具类获取大模型回答,返回响应结果:

package com.example.qwenapi.controller;

import com.example.qwenapi.entity.QwenRequest;
import com.example.qwenapi.entity.QwenResponse;
import com.example.qwenapi.util.QwenApiUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 通义千问API调用接口
 */
@RestController
@RequestMapping("/qwen")
public class QwenApiController {

    @Autowired
    private QwenApiUtil qwenApiUtil;

    /**
     * 接收用户提问,返回大模型回答
     * @param request 前端请求(包含用户提问)
     * @return 大模型响应结果
     */
    @PostMapping("/ask")
    public QwenResponse askQwen(@RequestBody QwenRequest request) {
        // 校验请求参数
        if (request == null || request.getQuestion() == null || request.getQuestion().trim().isEmpty()) {
            QwenResponse response = new QwenResponse();
            response.setCode(400);
            response.setMessage("请输入有效的提问内容");
            return response;
        }
        // 调用工具类,获取大模型回答
        return qwenApiUtil.getQwenAnswer(request.getQuestion().trim());
    }
}

四、项目测试

代码开发完成后,启动SpringBoot项目,使用Postman或Apifox测试接口,步骤如下:

  1. 启动项目:运行SpringBoot启动类,确保项目启动成功(控制台无报错,显示“Started QwenApiApplication in xxx seconds”);

  2. 打开Postman,创建一个POST请求,请求地址:http://localhost:8082/qwen/ask;

  3. 设置请求头:Content-Type = application/json;

  4. 设置请求体(JSON格式):
    { "question": "SpringBoot如何集成大模型API?" }

  5. 点击“发送”,查看响应结果,若返回如下内容,说明API调用成功:
    { "code": 200, "message": "调用成功", "answer": "SpringBoot集成大模型API的核心步骤如下:1. 获取大模型API的ak、sk等凭证;2. 在SpringBoot项目中添加HTTP请求和JSON解析依赖;3. 封装API调用工具类,处理签名、请求发送和响应解析;4. 开发控制层接口,接收前端请求并调用工具类;5. 测试接口,验证集成效果..." }

五、常见问题排查(必看,避免踩坑)

  1. 问题1:API调用报错“Signature not match”(签名不匹配)?

    排查:① ak和sk是否填写正确;② 签名生成逻辑是否正确(重点检查stringToSign的拼接格式、编码方式);③ 请求时间是否为GMT格式(避免使用本地时间)。

  2. 问题2:响应报错“Invalid model”(模型无效)?

    解决:检查application.yml中model配置是否正确,通义千问常用模型:qwen-turbo(轻量版)、qwen-plus(标准版),请勿填写错误。

  3. 问题3:项目启动失败,提示“依赖冲突”?

    解决:检查pom.xml中依赖的版本,尤其是OkHttp和FastJSON,建议使用本文提供的版本,避免与SpringBoot默认依赖冲突。

  4. 问题4:接口返回“API调用失败,响应状态:403”?

    排查:ak和sk是否有权限调用通义千问API,登录阿里云控制台,检查应用的权限配置,确保已开通API调用权限。

六、扩展与优化(进阶内容)

本文实现的是单轮对话功能,实际开发中可根据需求进行扩展,提升体验:

  1. 多轮对话:修改请求参数,保存历史对话记录,每次请求携带历史消息,实现连续对话;

  2. 请求限流:添加接口限流逻辑(如使用Redis),避免频繁调用API导致额度耗尽;

  3. 异常重试:在工具类中添加异常重试机制(如使用Spring的Retry注解),应对网络波动导致的调用失败;

  4. 多模型适配:修改工具类,支持切换不同大模型(如文心一言、GPT),只需修改配置和请求参数格式。

七、总结

以上就是SpringBoot集成通义千问大模型API的完整实战,从前期准备、项目搭建,到核心代码开发、接口测试,每一步都有详细说明和完整代码,Java开发工程师可以直接复制使用,快速集成大模型能力。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐