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

目录

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

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

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

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

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

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

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

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

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


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

2、在SpringBoot项目里面的pom.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文件,用于存储调用模型功能时必须要设置的参数。

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文件,编写项目的功能接口。九天大模型文生图功能有两类接口,所以我也写了两个接口。

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文件,两个项目接口对应的两个服务接口。

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文件,里面编写一些功能函数。

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文件,把上述两个接口给实现。这里参考了九天大模型官网的调用示例。

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

### 使用 Spring Boot 实现文学一言的文生接口 为了实现基于Spring Boot 的文学一言文生(Text-to-Image)以及(Image-to-Image)功能,通常会涉及到调用第三方AI服务提供商所提供的API。这里以百度云平台上的文心一言为例来说明如何集成这些特性。 #### 准备工作 首先,在开始编码之前,需要完成如下准备工作: - 注册并登录到百度智能云控制台。 - 创建应用获取 `AK` 和 `SK` (Access Key 和 Secret Key),这是访问API所必需的身份验证凭证[^2]。 - 添加所需的依赖项至项目的pom.xml文件中以便能够方便地发起HTTP请求并与JSON数据交互。 对于Maven项目来说,可以在`pom.xml`里加入以下内容: ```xml <dependency> <groupId>com.baidu.aip</groupId> <artifactId>java-sdk</artifactId> <version>5.0.1</version> </dependency> <!-- JSON处理 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> ``` #### 构建Service层逻辑 接下来定义一个名为`AIService.java`的服务类用来封装与AI服务器通信的具体细节。此部分代码负责构建URL、设置参数、发送POST请求并将响应解析成Java对象等形式的工作。 ```java @Service public class AIService { private static final String HOST = "https://aip.baidubce.com/rpc/2.0/ernievilg/v1/txt2img"; @Value("${baidu.api.key}") private String apiKey; @Value("${baidu.secret.key}") private String secretKey; public byte[] generateImageByText(String text){ try { AipRequest request = new AipRequest(); Map<String, Object> params = new HashMap<>(); params.put("text", text); // 获取token String accessToken = AuthService.getAuth(apiKey,secretKey); URL url = new URL(HOST+"?access_token="+accessToken); HttpURLConnection connection = (HttpURLConnection)url.openConnection(); ObjectMapper mapper = new ObjectMapper(); String jsonInputString=mapper.writeValueAsString(params); // 设置请求方法为 POST 并写入输入流 connection.setRequestMethod("POST"); connection.setDoOutput(true); DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); wr.writeBytes(jsonInputString); wr.flush(); wr.close(); int responseCode = connection.getResponseCode(); InputStream inputStream; if(responseCode >= 400){ inputStream=connection.getErrorStream(); }else{ inputStream=connection.getInputStream(); } return IOUtils.toByteArray(inputStream); } catch (Exception e) { throw new RuntimeException(e.getMessage(),e); } } } ``` 上述代码片段展示了通过给定的文字描述向百度ERNIE-ViLG v1 API发出请求的过程,并返回由该文字生成的片字节数组形式的结果。 请注意实际开发过程中还需要考虑错误处理机制和服务端限流等问题;此外,针对不同的应用场景可能也需要调整具体的业务流程设计。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值