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、查看图片保存结果。图片挺好看的。

相关推荐
終不似少年遊*5 分钟前
通过一个算法的设计来了解栈的一些应用
java·前端·数据库
三天不学习8 分钟前
【Delete 删除数据语法合集】.NET开源ORM框架 SqlSugar 系列
后端·开源·.net·orm·微软技术·sqlsugar
军训猫猫头9 分钟前
43.Textbox的数据绑定 C#例子 WPF例子
java·c#·wpf
多多*2 小时前
线程池相关 FutureTask介绍 处理阻塞 Future改进->CompletableFuture
java·开发语言·后端·python·spring
画船听雨眠aa2 小时前
Spring框架(三)ioc注解与junit单元测试整合
java·spring
Quantum&Coder3 小时前
Swift语言的软件工程
开发语言·后端·golang
兩尛4 小时前
项目概述、开发环境搭建(day01)
java·spring boot·web
吴代庄4 小时前
复盘成长——2024年终总结
后端
CyberScriptor4 小时前
CSS语言的语法糖
开发语言·后端·golang
我想学LINUX5 小时前
【2024年华为OD机试】(C卷,100分)- 攀登者1 (Java & JS & Python&C/C++)
java·c语言·javascript·c++·python·游戏·华为od