使用HttpClient连接,实现JAVA简单调用chatGPT的chat—API进行连读对话
本文使用Java Maven框架,引用httpclient依赖,使用Httpclient实现HTTPS连接chatGPT官方的chat—API,实现了一个简单的chatGPT调用。
注意:这是未设置soket连接的模式,需要挂VPN并使用全局模式来实现,缺点:本地的应用可能无法联网。
一、项目结构
1、配置设置
在pom.xml文件里面引入如下依赖
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>compile</scope>
</dependency>
</dependencies>
2、项目类设置
需要4个基本类用于接受chatGPT返回的信息,以及1个主执行程序Main
首先,看看GPT返回的信息体,这里以”你在吗“为提问信息,具体结构如下:
{
"id": "chatcmpl-7gTE1xxH2kQzpj8ukg9xwmcveQGqC",
"object": "chat.completion",
"created": 1690356473,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "是的,我在。有什么我可以帮助你的吗?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 11,
"completion_tokens": 21,
"total_tokens": 32
}
}
因此,基本类设置如下
1 Answer
用于接收整个返回的对应json数据
package org.example.ai;
import lombok.Data;
import java.util.List;
@Data
public class Answer {
private String id;
private String object;
private String model;
private int created;
private List<Choices> choices;
private Usage usage;
}
2 Choices
package org.example.ai;
import lombok.Data;
import java.util.List;
@Data
public class Choices {
private Integer index;
private List<Message> message;
private String finish_reason;
}
3 Usage
package org.example.ai;
import lombok.Data;
@Data
public class Usage {
private Integer prompt_tokens;
private Integer completion_tokens;
private Integer total_tokens;
}
4 Message
package org.example.ai;
import lombok.Data;
@Data
public class Message {
private String role;
private String content;
}
二、HttpClient连接思路(Main中实现)
1、HttpClient对象设置
这里在main函数中定义一个http对象httpClient,通过这个对象实现请求
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create()
.setSSLSocketFactory(getSslConnectionSocketFactory())
.build()) {
submit(httpClient, getHttpPost());
}
}
2、设置http配置信息
private static HttpPost getHttpPost() throws IOException {
//设置配置信息
String openAiKey = "sk-xxxxxxxxxxxxxxxx"; //OpenAI——KEY (你自己申请一个)
int connectTimeout = 600000; //连接超时时间
int connectionRequestTimeout = 600000; //请求超时时间
int socketTimeout = 600000; //socket连接超时时间
//httppost请求对象定义
HttpPost post = new HttpPost("https://api.openai.com/v1/chat/completions");
//post请求头部定义
post.addHeader("Content-Type", "application/json");
post.addHeader("Authorization", "Bearer " + openAiKey);
//post请求日志定义
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout)
.setSocketTimeout(socketTimeout)
.build();
post.setConfig(requestConfig);
return post;
}
3、submit提交
-
submit
方法用于接收用户输入问题,并向ChatGPT API提交问题,然后解析并打印回答。 -
首先,创建一个
Scanner
对象,以便从控制台读取用户输入的问题。 -
然后,通过一个无限循环,反复询问用户问题,并向API提交。
-
StringEntity
是Apache HTTP Client库中的一个类,用于将字符串数据作为请求实体发送给API。这里通过getRequestJson
方法(具体见下一条)将用户的问题封装成JSON格式。 -
将
StringEntity
设置为HttpPost
请求的实体。 -
使用
CloseableHttpClient
对象httpClient
执行POST请求,并得到响应CloseableHttpResponse
。 -
如果请求成功,将响应传递给
printAnswer
方法进行处理。
private static void submit(CloseableHttpClient httpClient, HttpPost post) throws IOException {
Scanner scanner = new Scanner(System.in);
String question;
while (true) {
System.out.print("You: ");
question = scanner.nextLine(); //自定义输入问题,每轮进行清楚
System.out.print("AI: ");
StringEntity stringEntity = new StringEntity(getRequestJson(question), getContentType());
post.setEntity(stringEntity); //这里设置请求体(信息体)
CloseableHttpResponse response;
response = httpClient.execute(post); //这里发起请求并接受反馈信息
printAnswer(response);
}
}
4、JSON格式转换
在这里将上一步submit中输入的question进行json格式转换
private static ContentType getContentType() {
return ContentType.create("text/json", "UTF-8");
}
private static String getRequestJson(String question) {
// 构建消息内容
JSONObject messageContent = new JSONObject();
messageContent.put("role", "user");
messageContent.put("content", question);
// 构建消息列表
JSONArray messages = new JSONArray();
messages.add(messageContent);
// 构建最终的请求体
JSONObject requestBody = new JSONObject();
requestBody.put("model", "gpt-3.5-turbo");
requestBody.put("messages", messages);
requestBody.put("temperature", 0.7);
//最后又以String的形式传给submit
return JSONObject.toJSONString(requestBody,SerializerFeature.WriteMapNullValue);
}
5、SSL连接设置
这里使用了HTTPS连接,通过SSL加密来保护数据传输,本文的SSLConnectionSocketFactory既是用于设置HTTPS连接的类。
private static SSLConnectionSocketFactory getSslConnectionSocketFactory() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
}
6、内容打印
private static void printAnswer(CloseableHttpResponse response) throws IOException {
//将json数据转为string字符串
String responseJson = EntityUtils.toString(response.getEntity());
//将转化的字符串进一步转为Answer类的对象
Answer answer = JSON.parseObject(responseJson, Answer.class);
//进一步提取信息到answerinfo里面,第一个是role,第二个是content
List<String> answerinfo = new ArrayList<>();
List<Choices> choices = answer.getChoices();
for (Choices choice : choices) {
answerinfo.add(choice.getMessage().get(0).getRole());
answerinfo.add(choice.getMessage().get(0).getContent());
}
System.out.println("role:" + answerinfo.get(0) + "," + "content" + answerinfo.get(1)); //输出结果
}
三、主程序代码
package org.example;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.example.ai.Answer;
import org.example.ai.Choices;
import org.example.ai.Message;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.rmi.ServerException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create()
.setSSLSocketFactory(getSslConnectionSocketFactory())
.build()) {
submit(httpClient, getHttpPost());
}
}
private static void submit(CloseableHttpClient httpClient, HttpPost post) throws IOException {
Scanner scanner = new Scanner(System.in);
String question;
while (true) {
System.out.print("You: ");
question = scanner.nextLine();
System.out.print("AI: ");
StringEntity stringEntity = new StringEntity(getRequestJson(question), getContentType());
post.setEntity(stringEntity); //这里设置请求体(信息体)
CloseableHttpResponse response;
response = httpClient.execute(post); //这里发起请求并接受反馈信息
printAnswer(response);
}
}
private static void printAnswer(CloseableHttpResponse response) throws IOException {
String responseJson = EntityUtils.toString(response.getEntity());
Answer answer = JSON.parseObject(responseJson, Answer.class);
List<String> answerinfo = new ArrayList<>();
List<Choices> choices = answer.getChoices();
for (Choices choice : choices) {
answerinfo.add(choice.getMessage().get(0).getRole());
answerinfo.add(choice.getMessage().get(0).getContent());
}
System.out.println("role:" + answerinfo.get(0) + "," + "content" + answerinfo.get(1)); //输出结果
}
private static ContentType getContentType() {
return ContentType.create("text/json", "UTF-8");
}
private static String getRequestJson(String question) {
// 构建消息内容
JSONObject messageContent = new JSONObject();
messageContent.put("role", "user");
messageContent.put("content", question);
// 构建消息列表
JSONArray messages = new JSONArray();
messages.add(messageContent);
// 构建最终的请求体
JSONObject requestBody = new JSONObject();
requestBody.put("model", "gpt-3.5-turbo");
requestBody.put("messages", messages);
requestBody.put("temperature", 0.7);
return JSONObject.toJSONString(requestBody, SerializerFeature.WriteMapNullValue);
}
private static HttpPost getHttpPost() throws IOException {
//设置配置信息
String openAiKey = "sk-xxxxxxxxxxxxxxxxxxx"; //OpenAI——KEY(你自己申请一个)
int connectTimeout = 600000; //连接超时时间
int connectionRequestTimeout = 600000; //请求超时时间
int socketTimeout = 600000; //socket连接超时时间
HttpPost post = new HttpPost("https://api.openai.com/v1/chat/completions");
post.addHeader("Content-Type", "application/json");
post.addHeader("Authorization", "Bearer " + openAiKey);
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout)
.setSocketTimeout(socketTimeout)
.build();
post.setConfig(requestConfig);
return post;
}
private static SSLConnectionSocketFactory getSslConnectionSocketFactory() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
}
}
更多推荐
所有评论(0)