SpringBoot + 九天大模型(文生图接口)

目录

[1、先到九天大模型的官网(LLM Studio)上订阅模型的推理服务,得到APIKey,后期需要使用它生成token才能调用模型的推理服务。](#1、先到九天大模型的官网(LLM Studio)上订阅模型的推理服务,得到APIKey,后期需要使用它生成token才能调用模型的推理服务。)

2、在SpringBoot项目里面的pom.xml文件中添加九天大模型的相关依赖,后面会使用到其中的一些函数。

[3、 在项目中的实体类里面新建一个JiuTian.java文件,用于存储调用模型功能时必须要设置的参数。](#3、 在项目中的实体类里面新建一个JiuTian.java文件,用于存储调用模型功能时必须要设置的参数。)

[4、 在项目的控制层中新建一个JiuTianController.java文件,编写项目的功能接口。九天大模型文生图功能有两类接口,所以我也写了两个接口。](#4、 在项目的控制层中新建一个JiuTianController.java文件,编写项目的功能接口。九天大模型文生图功能有两类接口,所以我也写了两个接口。)

[5、 在服务层新建JiuTianService.interface文件,两个项目接口对应的两个服务接口。](#5、 在服务层新建JiuTianService.interface文件,两个项目接口对应的两个服务接口。)

6、在工具层新建JiuTianUtil.java文件,里面编写一些功能函数。

7、在服务层中的实现层中新建JiuTianServiceImpl.java文件,把上述两个接口给实现。这里参考了九天大模型官网的调用示例。

8、在apifox接口软件中调用项目接口测试。

9、查看图片保存结果。图片挺好看的


1、先到九天大模型的官网(LLM Studio)上订阅模型的推理服务,得到APIKey,后期需要使用它生成token才能调用模型的推理服务。

2、在SpringBoot项目里面的pom.xml文件中添加九天大模型的相关依赖,后面会使用到其中的一些函数。

XML 复制代码
        <!-- 九天大模型的依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>com.nimbusds</groupId>
            <artifactId>nimbus-jose-jwt</artifactId>
            <version>8.16</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.26</version>
        </dependency>

3、 在项目中的实体类里面新建一个JiuTian.java文件,用于存储调用模型功能时必须要设置的参数。

java 复制代码
public class JiuTian {
    
    //调用文生图功能时,给模型的提示语:画一条鱼
    private String genImgMessage;

    调用文生图功能时,图像保存的地址
    private String genImgSavePath;

    public String getGenImgMessage() {
        return genImgMessage;
    }

    public void setGenImgMessage(String genImgMessage) {
        this.genImgMessage = genImgMessage;
    }

    public String getGenImgSavePath() {
        return genImgSavePath;
    }

    public void setGenImgSavePath(String genImgSavePath) {
        this.genImgSavePath = genImgSavePath;
    }
}

4、 在项目的控制层中新建一个JiuTianController.java文件,编写项目的功能接口。九天大模型文生图功能有两类接口,所以我也写了两个接口。

java 复制代码
import com.knowledgeBase.entity.JiuTian;
import com.knowledgeBase.permission.PassToken;
import com.knowledgeBase.service.JiuTianService;
import com.nimbusds.jose.JOSEException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/JiuTian")
public class JiuTianController {

    @Autowired
    JiuTianService jiuTianService;

    @PassToken
    @RequestMapping(value = "/gen_img_cha", method = RequestMethod.POST)
    public String generate_img_Chat(@RequestBody JiuTian jiuTian) throws JOSEException {
        return jiuTianService.generate_img_Chat(jiuTian);
    }

    @PassToken
    @RequestMapping(value = "/gen_img_com", method = RequestMethod.POST)
    public String generate_img_Completions(@RequestBody JiuTian jiuTian) throws JOSEException {
        return jiuTianService.generate_img_Completions(jiuTian);
    }
}

5、 在服务层新建JiuTianService.interface文件,两个项目接口对应的两个服务接口。

java 复制代码
import com.knowledgeBase.entity.JiuTian;
import com.nimbusds.jose.JOSEException;

public interface JiuTianService {

    String generate_img_Chat(JiuTian jiuTian) throws JOSEException;

    String generate_img_Completions(JiuTian jiuTian) throws JOSEException;
}

6、在工具层新建JiuTianUtil.java文件,里面编写一些功能函数。

java 复制代码
import com.alibaba.fastjson2.JSONObject;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;

import java.time.LocalDateTime;
import java.util.Date;

public class JiuTianUtils {

    //获取九天大模型的token
    public static String generateToken(String apikey,long expSeconds) throws JOSEException {
        String[] apikeyArr=apikey.split("\\.",2);//kid.secret
        Date now=new Date();

        JSONObject payload=new JSONObject();
        payload.put("api_key",apikeyArr[0]);
        payload.put("exp",now.getTime()/1000+expSeconds);
        payload.put("timestamp",now.getTime()/1000);

        //创建JWS对象
        JWSObject jwsObject = new JWSObject(
                new JWSHeader.Builder(JWSAlgorithm.HS256).type(JOSEObjectType.JWT).build(),
                new Payload(payload.toJSONString()));
        //签名
        jwsObject.sign(new MACSigner(apikeyArr[1]));
        return jwsObject.serialize();
    }

    //获取当前时间设置成字符串
    public static String getNowTime(){
        LocalDateTime now = LocalDateTime.now();
        int year = now.getYear();
        int month = now.getMonthValue();
        int day = now.getDayOfMonth();
        int hour = now.getHour();
        int minute = now.getMinute();
        int second = now.getSecond();

        return year + "-" + month + "-" + day + "-" + hour + "-" + minute + "-" + second;
    }
}

7、在服务层中的实现层中新建JiuTianServiceImpl.java文件,把上述两个接口给实现。这里参考了九天大模型官网的调用示例。

java 复制代码
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.knowledgeBase.entity.JiuTian;
import com.knowledgeBase.service.JiuTianService;
import com.knowledgeBase.utils.JiuTianUtils;
import com.nimbusds.jose.JOSEException;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class JiuTianServiceImpl implements JiuTianService {
    // 九天大模型的apikey
    private static String apiKey = "到九天大模型官网订阅服务里面复制apikey";

    // 九天大模型的token,有效期需要设置为项目用户登录token一样的有效期
    private static String jwt_token = null;

    // 相关工具类
    private static JiuTianUtils jiuTianUtils = new JiuTianUtils();

    // 九天大模型token有效期,两天
    private static Integer token_time = 60 * 60 * 24 * 2;

    @Override
    public String generate_img_Completions(JiuTian jiuTian) throws JOSEException {
        if(jwt_token == null){
            jwt_token = "Bearer " + jiuTianUtils.generateToken(apiKey, token_time);
            System.out.println("九天大模型的token已生成: " + jwt_token);
        }
        if(jiuTian.getGenImgMessage().isEmpty()){
            System.out.println("提示语为空!");
            return "提示语为空!";
        }
        if(jiuTian.getGenImgSavePath().isEmpty()){
            System.out.println("图片存储路径为空!");
            return "图片存储路径为空!";
        }

        // 构建请求体数据
        JSONObject obj = new JSONObject();
        obj.put("model", "StableDiffusion");
        obj.put("prompt", jiuTian.getGenImgMessage());
        obj.put("returnImageUrl", false);

        // 格式转换器
        ObjectMapper objectMapper = new ObjectMapper();

        //处理结果
        AtomicReference<String> dealResult = new AtomicReference<>();

        // 构造线程池
        ExecutorService nonBlockingService = Executors.newCachedThreadPool();
        nonBlockingService.execute(() -> {
            try {
                // 设置WebClient处理数据时的内存限制
                ExchangeStrategies strategies = ExchangeStrategies.builder()
                        .codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(Integer.MAX_VALUE))
                        .build();

                Mono<String> mono = WebClient.builder()
                        .baseUrl("https://jiutian.10086.cn/largemodel/api/v2/completions")
                        .defaultHeader("Authorization", jwt_token)
                        .defaultHeader("Content-Type", "application/json")
                        .exchangeStrategies(strategies)
                        .build()
                        .post()
                        .bodyValue(obj)//请求体数据
                        .retrieve()//获取响应体
                        .bodyToMono(String.class);//响应数据类型转换

                mono.subscribe(
                        result -> {
                            System.out.println("响应报文已转成字符串!下面开始解析:");
                            try {
                                JsonNode responseJson = objectMapper.readTree(result);//字符串转Josn
                                String base64_img = responseJson.get("choices").get(0).get("text").asText();//取图像base64字符串
                                byte[] imageBytes = Base64.getDecoder().decode(base64_img);//解码
                                InputStream in = new ByteArrayInputStream(imageBytes);//把字符数组转换成BufferedImage
                                BufferedImage image = ImageIO.read(in);
                                File outputfile = new File(jiuTian.getGenImgSavePath() + "\\output_img_Completions_" + jiuTianUtils.getNowTime() + ".png");//保存图像
                                ImageIO.write(image, "PNG", outputfile);
                                System.out.println("解析完成,生成的图像存储在" + outputfile.getAbsolutePath());
                                dealResult.set("解析完成,生成的图像存储在" + outputfile.getAbsolutePath());
                            } catch (JsonProcessingException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        },
                        error -> {
                            System.out.println("Error: "+ error);
                            dealResult.set("Error: "+ error);
                        },
                        () -> {
                            System.out.println("Completed!");
                            dealResult.set("Completed!");
                        });
            } catch (Exception e) {
                throw new RuntimeException(e);
            };
        });

        return dealResult.get();
    }

    @Override
    public String generate_img_Chat(JiuTian jiuTian) throws JOSEException {
        if (jwt_token == null) {
            jwt_token = jiuTianUtils.generateToken(apiKey, token_time);
            System.out.println("九天大模型的token已生成: " + jwt_token);
        }
        if(jiuTian.getGenImgMessage().isEmpty()){
            System.out.println("提示语为空!");
            return "提示语为空!";
        }
        if(jiuTian.getGenImgSavePath().isEmpty()){
            System.out.println("图片存储路径为空!");
            return "图片存储路径为空!";
        }

        // 构建请求体数据
        JSONObject obj = new JSONObject();
        obj.put("model", "StableDiffusion");
        JSONObject params1 = new JSONObject();
        params1.put("role", "system");
        params1.put("content", "你是一位漫画家");
        JSONObject params2 = new JSONObject();
        params2.put("role", "user");
        params2.put("content", jiuTian.getGenImgMessage());
        List<JSONObject> messages = new ArrayList<>();
        messages.add(params1);
        messages.add(params2);
        obj.put("messages", messages);
        obj.put("returnImageUrl", false);

        // 格式转换器
        ObjectMapper objectMapper = new ObjectMapper();

        // 处理结果
        AtomicReference<String> dealResult = new AtomicReference<>();

        // 构造线程池
        ExecutorService nonBlockingService = Executors.newCachedThreadPool();
        nonBlockingService.execute(() -> {
            try {
                // 设置WebClient处理数据时的内存限制
                ExchangeStrategies strategies = ExchangeStrategies.builder()
                        .codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(Integer.MAX_VALUE))
                        .build();

                Mono<String> mono = WebClient.builder()
                        .baseUrl("https://jiutian.10086.cn/largemodel/api/v2/chat/completions")
                        .defaultHeader("Authorization", "Bearer " + jwt_token)
                        .defaultHeader("Content-Type", "application/json")
                        .exchangeStrategies(strategies)
                        .build()
                        .post()
                        .bodyValue(obj)//请求体数据
                        .retrieve()//获取响应体
                        .bodyToMono(String.class);//响应数据类型转换

                mono.subscribe(
                        result -> {
                            System.out.println("响应报文已转成字符串!下面开始解析:");
                            try {
                                JsonNode responseJson = objectMapper.readTree(result);//字符串转Josn
                                String base64_img = responseJson.get("choices").get(0).get("message").get("content").asText();//取图像base64字符串
                                byte[] imageBytes = Base64.getDecoder().decode(base64_img);//解码
                                InputStream in = new ByteArrayInputStream(imageBytes);//把字符数组转换成BufferedImage
                                BufferedImage image = ImageIO.read(in);
                                File outputfile = new File(jiuTian.getGenImgSavePath() + "\\output_img_Completions_" + jiuTianUtils.getNowTime() + ".png");//保存图像
                                ImageIO.write(image, "PNG", outputfile);
                                System.out.println("解析完成,生成的图像存储在" + outputfile.getAbsolutePath());
                                dealResult.set("解析完成,生成的图像存储在" + outputfile.getAbsolutePath());
                            } catch (JsonProcessingException e) {
                                throw new RuntimeException(e);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        },
                        error -> {
                            System.out.println("Error: "+ error);
                            dealResult.set("Error: "+ error);
                        },
                        () -> {
                            System.out.println("Completed!");
                            dealResult.set("Completed!");
                        });
            } catch (Exception e) {
                throw new RuntimeException(e);
            };
        });

        return dealResult.get();
    }
}

8、在apifox接口软件中调用项目接口测试。

9、查看图片保存结果。图片挺好看的。

相关推荐
一只叫煤球的猫8 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9658 小时前
tcp/ip 中的多路复用
后端
bobz9658 小时前
tls ingress 简单记录
后端
皮皮林5519 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友10 小时前
什么是OpenSSL
后端·安全·程序员
bobz96510 小时前
mcp 直接操作浏览器
后端
前端小张同学12 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook12 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康13 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在13 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net