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