使用HttpClient连接,实现JAVA简单调用chatGPT的chat—API进行连读对话

注意:这是未设置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提交
  1. submit方法用于接收用户输入问题,并向ChatGPT API提交问题,然后解析并打印回答。

  2. 首先,创建一个Scanner对象,以便从控制台读取用户输入的问题。

  3. 然后,通过一个无限循环,反复询问用户问题,并向API提交。

  4. StringEntity是Apache HTTP Client库中的一个类,用于将字符串数据作为请求实体发送给API。这里通过getRequestJson方法(具体见下一条)将用户的问题封装成JSON格式。

  5. StringEntity设置为HttpPost请求的实体。

  6. 使用CloseableHttpClient对象httpClient执行POST请求,并得到响应CloseableHttpResponse

  7. 如果请求成功,将响应传递给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());
    }
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JakeyRoiy丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值