1.版本背景

jdk17(jdk8也类似)
springboot3.2.0

2.项目集成

2.1 项目结构如下图

在这里插入图片描述

2.2 pom.xml 核心基础依赖配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jinyi</groupId>
    <artifactId>jinyi-ai</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>jinyi-ai app</name>

    <properties>
        <spring.boot.version>3.2.0</spring.boot.version>
        <lombok.version>1.18.22</lombok.version>
        <hutool-all.version>5.8.4</hutool-all.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 排除Tomcat依赖 -->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 使用undertow -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.undertow</groupId>
                    <artifactId>undertow-websockets-jsr</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool-all.version}</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
                <exclusions>
                    <exclusion>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

2.3 application.yml 核心基础依赖配置

spring:
  application:
    name: jinyi-ai-application
  ai:
    deepseek:
      apiKey: 在deepseek注册申请
      apiUrl: https://api.deepseek.com/v1/chat/completions
      model: deepseek-chat
      temperature: 0.7
      max-tokens: 1000

2.4 请求和响应对象

package com.jinyi.ai.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 *
 * @date 2025/2/7 15:36
 * @desc
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatRequest {
    private String model;
    private List<Message> messages;
    private double temperature;
    private int max_tokens;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Message {
        private String role;
        private String content;
    }
}
package com.jinyi.ai.vo;

import lombok.Data;

import java.util.List;

/**
 *
 * @date 2025/2/7 15:37
 * @desc  返回对象属性含义详见官方文档 https://api-docs.deepseek.com/zh-cn/api/deepseek-api
 */
@Data
public class ChatResponse {

    private String id;

    private String object;

    private int created;

    private String model;

    private List<Choices> choices;

    private Usage usage;

    private String system_fingerprint;

    @Data
    public static class Choices {

        private int index;

        private Message message;

        private String logprobs;

        private String finish_reason;

        @Data
        public static class Message {
            private String role;
            private String content;
        }
    }

    @Data
    public static class Usage {
        private int prompt_tokens;

        private int completion_tokens;

        private int total_tokens;

        private Prompt_tokens_details prompt_tokens_details;

        private int prompt_cache_hit_tokens;

        private int prompt_cache_miss_tokens;

        @Data
        public static class Prompt_tokens_details {
            private int cached_tokens;
        }
    }
}

2.5 项目启动main函数

package com.jinyi.ai;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

2.6 项目配置类

package com.jinyi.ai.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * deepseek 配置
 *
 * @date 2025/2/7 12:21
 * @desc 官方文档 https://api-docs.deepseek.com/zh-cn/api/deepseek-api
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.ai.deepseek")
public class DeepSeekConfig {
    private String apiKey;
    private String apiUrl;
    private String model;
    private Double temperature;
    private Integer maxTokens;
}

2.7 项目service类

/**
 *
 * @date 2025/2/7 16:43
 * @desc
 */
public interface DeepSeekService {
    /**
     * 提问生成回复
     * @param query 提问词
     * @return
     */
    String generateResponse(String query);
}

import cn.hutool.core.collection.ListUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import com.jinyi.ai.config.DeepSeekConfig;
import com.jinyi.ai.dto.ChatRequest;
import com.jinyi.ai.vo.ChatResponse;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

/**
 * @date 2025/2/7 15:39
 * @desc
 */
@Service
public class DeepSeekServiceImpl implements DeepSeekService {
    @Resource
    private DeepSeekConfig deepSeekConfig;

    /**
     * 提问生成回复
     *
     * @param query 提问词
     * @return 注: 官方文档 https://api-docs.deepseek.com/zh-cn/api/deepseek-api
     */
    @Override
    public String generateResponse(String query) {
        //构建deepseek请求对象
        ChatRequest request = buildRequest(query);
        HttpResponse execute = HttpUtil.createRequest(Method.POST, deepSeekConfig.getApiUrl())
                .body(JSONUtil.toJsonStr(request))
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + deepSeekConfig.getApiKey())
                .header("Accept", "application/json").execute();
        String resp = execute.body();
        ChatResponse chatResponse = JSONUtil.toBean(resp, ChatResponse.class);
        String answerContent = this.extractResponse(chatResponse);
        return answerContent;
    }

    /**
     * 构建deepseek请求对象
     *
     * @param query
     * @return
     */
    private ChatRequest buildRequest(String query) {
        return ChatRequest.builder()
                .model(deepSeekConfig.getModel())
                .temperature(deepSeekConfig.getTemperature())
                .max_tokens(deepSeekConfig.getMaxTokens())
                .messages(ListUtil.of(
                        new ChatRequest.Message("user", query)
                ))
                .build();
    }

    /**
     * 提取回复内容
     *
     * @param response
     * @return
     */
    private String extractResponse(ChatResponse response) {
        return response.getChoices().stream()
                .findFirst()
                .map(choice -> choice.getMessage().getContent())
                .orElseThrow(() -> new RuntimeException("Empty response"));
    }
}

2.8 项目controller类

package com.jinyi.ai.controller;

import com.jinyi.ai.service.impl.DeepSeekService;
import jakarta.annotation.Resource;
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;

/**
 *
 * @date 2025/2/7 15:50
 * @desc
 */
@RestController
@RequestMapping("/api")
public class SearchController {
    @Resource
    private DeepSeekService deepSeekService;
    @PostMapping("/searchV1")
    public String search(@RequestBody String query) {
        return deepSeekService.generateResponse(query);
    }
}

2.9 测试

在这里插入图片描述

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐