注意:这是未设置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": "pletion","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;@Datapublic 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;@Datapublic class Choices {private Integer index;private List<Message> message;private String finish_reason;}
3 Usage
package org.example.ai;import lombok.Data;@Datapublic class Usage {private Integer prompt_tokens;private Integer completion_tokens;private Integer total_tokens;}
4 Message
package org.example.ai;import lombok.Data;@Datapublic 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("/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的形式传给submitreturn 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,第二个是contentList<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 .ssl.SSLContext;import java.io.IOException;import .SocketException;import .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("/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());}}
如果觉得《使用HttpClient连接 实现JAVA简单调用chatGPT的chat—API进行连读对话》对你有帮助,请点赞、收藏,并留下你的观点哦!