Visual chat interface developed based on Swing and iFlytek Spark model

Recently, I was honored to apply for the internal testing qualification of iFlytek Spark model (the web version has been opened and can be used directly, similar to chatgpt). I was given a 4 million free token, valid for one year, including version 1.5 and version 2.0. 2 million each, so I thought about writing a simple chat interface based on the Spark model. At first, I built a web version based on springboot, but the page layout was too ugly. After adjusting it for a long time, it just looked like that. Finally, I came up with It’s better to use swing to do it. Without further ado, here’s the practical information.

First of all, the first step is to go to the official website of iFlytek to apply for internal beta qualification. After passing the test, a unique appId will be generated. All developers should know this. Generally, access to third-party open platforms is like this. How to play, I won’t go into details about how to apply. Official website link: iFlytek Open Platform - an artificial intelligence open platform with voice interaction as the core

The second part is to use Java's swing to write a simple chat interface. Here is the final effect (it's ugly, don't comment):

The code goes directly below:

The first is the chat interface:

package com.tianjun.chat;

import com.google.gson.Gson;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.net.URI;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class ChatBox extends JFrame {

    public static final Gson gson = new Gson();

    private static int mode_gen = 1;

    private JTextArea chatArea;
    private JTextField messageField;
    private WebSocketClient client;

    public ChatBox() {
        setTitle("科大讯飞星火大模型");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1200, 900);

        chatArea = new JTextArea();
        chatArea.setLineWrap(true); // 自动换行
        chatArea.setWrapStyleWord(true); // 按单词边界换行
        chatArea.setEditable(false);
        chatArea.setMargin(new Insets(10, 10, 10, 10)); // 设置边距,使文本不贴边
        chatArea.setBackground(Color.WHITE); // 设置背景色,使文本区域更清晰可见
        chatArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // 设置边框,使文本区域更美观
        JScrollPane scrollPane = new JScrollPane(chatArea);

        messageField = new JTextField();
        messageField.setPreferredSize(new Dimension(300, 50));
        messageField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    doConnectAndSendMessage();
                }
            }
        });
        JButton sendButton = new JButton("Send");
        sendButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                doConnectAndSendMessage();
            }
        });
        Container container = getContentPane();
        container.setLayout(new BorderLayout());
        container.add(scrollPane, BorderLayout.CENTER);
        container.add(messageField, BorderLayout.SOUTH);
        container.add(sendButton, BorderLayout.EAST);
        setExtendedState(JFrame.MAXIMIZED_BOTH); // 最大化窗口
        setResizable(true); // 禁止调整窗口大小
        chatArea.setFont(new Font("微软雅黑", Font.PLAIN, 20));
        messageField.setFont(new Font("微软雅黑", Font.PLAIN, 20));
        chatArea.getDocument().putProperty("charset", "GBK");// 指定字符编码为 UTF-8
        messageField.getDocument().putProperty("charset", "GBK"); // 指定字符编码为 UTF-8
    }

    public void doConnectAndSendMessage() {
        mode_gen++;
        chatArea.setText("");
        String message = messageField.getText();
        if (!message.isEmpty()) {
            try {
                client = getClient();
                String myQuestion = mode_gen % 2 == 0 ? BigModelNewV2.getQuestion(message) : BigModelNewV1.getQuestion(message);
                client.send(myQuestion);
                messageField.setText("");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    private WebSocketClient getClient() throws Exception {
        String url = mode_gen % 2 == 0 ? BigModelNewV2.getAuthUrl().toString().replace("http://", "ws://").replace("https://", "wss://")
                : BigModelNewV1.getAuthUrl().toString().replace("http://", "ws://").replace("https://", "wss://");
        URI serverUri = new URI(url);
        WebSocketClient client = new WebSocketClient(serverUri) {
            @Override
            public void onOpen(ServerHandshake handshakedata) {
                String modelGen = mode_gen % 2 == 0 ? "第二代模型" : "第一代模型";
                chatArea.append(modelGen + "\n" + messageField.getText() + "\n");
            }

            @Override
            public void onMessage(String message) {
                ChatBox.JsonParse myJsonParse = gson.fromJson(message, ChatBox.JsonParse.class);
                if (myJsonParse.header.code != 0) {
                    System.out.println("发生错误,错误码为:" + myJsonParse.header.code);
                    System.out.println("本次请求的sid为:" + myJsonParse.header.sid);
                }
                List<Text> textList = myJsonParse.payload.choices.text;
                for (ChatBox.Text temp : textList) {
                    System.out.print(temp.content);
                    chatArea.append(temp.content);
                }
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                chatArea.append("\nConnection closed\n");
            }

            @Override
            public void onError(Exception ex) {
                chatArea.append("Error: " + ex.getMessage() + "\n");
            }
        };
        client.connect();
        while (true) {
            TimeUnit.MILLISECONDS.sleep(100);
            if (client.isOpen()) {
                break;
            }
        }
        return client;
    }

    public void start() throws Exception {
        getClient();
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                ChatBox chatBox = new ChatBox();
                try {
                    chatBox.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    class JsonParse {
        Header header;
        Payload payload;
    }

    class Header {
        int code;
        int status;
        String sid;
    }

    class Payload {
        Choices choices;
    }

    class Choices {
        List<Text> text;
    }

    class Text {
        String role;
        String content;
    }
}

The main function of this class is to build a chat interface, send messages and receive echo messages. The next two classes, one is a large model corresponding to version 1.5, and the other is a large model corresponding to version 2.0. The codes of these two classes are in You can download the sample from iFlytek's official website directly. You just need to replace several key appids and keys with your own.

package com.tianjun.chat;

import com.google.gson.Gson;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

public class BigModelNewV1 extends WebSocketListener {
    // 地址与鉴权信息
    public static final String hostUrl = "https://spark-api.xf-yun.com/v1.1/chat";
    public static final String appid = "";
    public static final String apiSecret = "";
    public static final String apiKey = "";

    // 环境治理的重要性  环保  人口老龄化  我爱我的祖国

    public static final Gson gson = new Gson();

    // 个性化参数
    private String userId;
    private Boolean wsCloseFlag;

    private static String requestJson = "{\n" +
            "  \"header\": {\n" +
            "    \"app_id\": \"" + appid + "\",\n" +
            "    \"uid\": \"" + UUID.randomUUID().toString().substring(0, 10) + "\"\n" +
            "  },\n" +
            "  \"parameter\": {\n" +
            "    \"chat\": {\n" +
            "      \"domain\": \"general\",\n" +
            "      \"temperature\": 0.5,\n" +
            "      \"max_tokens\": 1024\n" +
            "    }\n" +
            "  },\n" +
            "  \"payload\": {\n" +
            "    \"message\": {\n" +
            "      \"text\": [\n" +
            "        {\n" +
            "          \"role\": \"user\",\n" +
            "          \"content\": \"" + "${myQuestion}" + "\"\n" +
            "        }\n" +
            "      ]\n" +
            "    }\n" +
            "  }\n" +
            "}";

    public static String getQuestion(String myQuestion) {
        String question = requestJson.replace("${myQuestion}", myQuestion);
        System.err.println(question);
        return question;
    }

    // 构造函数
    public BigModelNewV1(String userId, Boolean wsCloseFlag) {
        this.userId = userId;
        this.wsCloseFlag = wsCloseFlag;
    }

    // 主函数
    public static void main(String[] args) throws Exception {
        Scanner reader = new Scanner(System.in);
        while (true) {
            String line = null;
            try {
                line = reader.nextLine();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (StringUtils.isBlank(line)) {
                continue;
            }
            WebSocket webSocket = webSocket();
            String myQuestion = getQuestion(line);
            System.err.println(webSocket.send(myQuestion));
            webSocket.close(1000, "");
            TimeUnit.SECONDS.sleep(2);
        }
    }

    public static String getAuthUrl() throws Exception {
        return getAuthUrl(hostUrl, apiKey, apiSecret);
    }

    public static WebSocket webSocket() throws Exception {
        // 构建鉴权url
        String authUrl = getAuthUrl(hostUrl, apiKey, apiSecret);
        OkHttpClient client = new OkHttpClient();
        String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");
        Request request = new Request.Builder().url(url).build();
        // 个性化参数入口,如果是并发使用,可以在这里模拟
        WebSocket webSocket = client.newWebSocket(request, new BigModelNewV1(1 + "",
                false));
        return webSocket;
    }


    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
//         System.out.println(userId + "用来区分那个用户的结果" + text);
        JsonParse myJsonParse = gson.fromJson(text, JsonParse.class);
        if (myJsonParse.header.code != 0) {
            System.out.println("发生错误,错误码为:" + myJsonParse.header.code);
            System.out.println("本次请求的sid为:" + myJsonParse.header.sid);
            webSocket.close(1000, "");
        }
        List<Text> textList = myJsonParse.payload.choices.text;
        for (Text temp : textList) {
            System.out.print(temp.content);
        }
        if (myJsonParse.header.status == 2) {
            // 可以关闭连接,释放资源
            wsCloseFlag = true;
        }
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        super.onFailure(webSocket, t, response);
        try {
            if (null != response) {
                int code = response.code();
                System.out.println("onFailure code:" + code);
                System.out.println("onFailure body:" + response.body().string());
                if (101 != code) {
                    System.out.println("connection failed");
                    System.exit(0);
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    // 鉴权方法
    public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
        URL url = new URL(hostUrl);
        // 时间
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());
        // 拼接
        String preStr = "host: " + url.getHost() + "\n" +
                "date: " + date + "\n" +
                "GET " + url.getPath() + " HTTP/1.1";
        // System.err.println(preStr);
        // SHA256加密
        Mac mac = Mac.getInstance("hmacsha256");
        SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
        mac.init(spec);

        byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
        // Base64加密
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        // System.err.println(sha);
        // 拼接
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);
        // 拼接地址
        HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//
                addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//
                addQueryParameter("date", date).//
                addQueryParameter("host", url.getHost()).//
                build();

        // System.err.println(httpUrl.toString());
        return httpUrl.toString();
    }

    //返回的json结果拆解
    class JsonParse {
        Header header;
        Payload payload;
    }

    class Header {
        int code;
        int status;
        String sid;
    }

    class Payload {
        Choices choices;
    }

    class Choices {
        List<Text> text;
    }

    class Text {
        String role;
        String content;
    }
}
package com.tianjun.chat;

import com.google.gson.Gson;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

public class BigModelNewV2 extends WebSocketListener {
    // 地址与鉴权信息
    public static final String hostUrl = "https://spark-api.xf-yun.com/v2.1/chat";
    public static final String appid = "";
    public static final String apiSecret = "";
    public static final String apiKey = "";

    // 环境治理的重要性  环保  人口老龄化  我爱我的祖国

    public static final Gson gson = new Gson();

    // 个性化参数
    private String userId;
    private Boolean wsCloseFlag;

    private static String requestJson = "{\n" +
            "  \"header\": {\n" +
            "    \"app_id\": \"" + appid + "\",\n" +
            "    \"uid\": \"" + UUID.randomUUID().toString().substring(0, 10) + "\"\n" +
            "  },\n" +
            "  \"parameter\": {\n" +
            "    \"chat\": {\n" +
            "      \"domain\": \"generalv2\",\n" +
            "      \"temperature\": 0.5,\n" +
            "      \"max_tokens\": 1024\n" +
            "    }\n" +
            "  },\n" +
            "  \"payload\": {\n" +
            "    \"message\": {\n" +
            "      \"text\": [\n" +
            "        {\n" +
            "          \"role\": \"user\",\n" +
            "          \"content\": \"" + "${myQuestion}" + "\"\n" +
            "        }\n" +
            "      ]\n" +
            "    }\n" +
            "  }\n" +
            "}";

    public static String getQuestion(String myQuestion) {
        String question = requestJson.replace("${myQuestion}", myQuestion);
        System.err.println(question);
        return question;
    }

    // 构造函数
    public BigModelNewV2(String userId, Boolean wsCloseFlag) {
        this.userId = userId;
        this.wsCloseFlag = wsCloseFlag;
    }

    // 主函数
    public static void main(String[] args) throws Exception {
        Scanner reader = new Scanner(System.in);
        while (true) {
            String line = null;
            try {
                line = reader.nextLine();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (StringUtils.isBlank(line)) {
                continue;
            }
            WebSocket webSocket = webSocket();
            String myQuestion = getQuestion(line);
            System.err.println(webSocket.send(myQuestion));
            webSocket.close(1000, "");
            TimeUnit.SECONDS.sleep(2);
        }
    }

    public static String getAuthUrl() throws Exception {
        return getAuthUrl(hostUrl, apiKey, apiSecret);
    }

    public static WebSocket webSocket() throws Exception {
        // 构建鉴权url
        String authUrl = getAuthUrl(hostUrl, apiKey, apiSecret);
        OkHttpClient client = new OkHttpClient();
        String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");
        Request request = new Request.Builder().url(url).build();
        // 个性化参数入口,如果是并发使用,可以在这里模拟
        WebSocket webSocket = client.newWebSocket(request, new BigModelNewV2(1 + "",
                false));
        return webSocket;
    }


    public static void send(WebSocket webSocket) {
        try {
            // 等待服务端返回完毕后关闭
            Scanner reader = new Scanner(System.in);
            while (true) {
                String line = null;
                try {
                    line = reader.nextLine();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 发送一行数据,并加上回车换行符
                // 将String类型的消息转换为ByteBuf类型的消息
                String myQuestion = getQuestion(line);
                System.err.println(webSocket.send(myQuestion));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
//         System.out.println(userId + "用来区分那个用户的结果" + text);
        JsonParse myJsonParse = gson.fromJson(text, JsonParse.class);
        if (myJsonParse.header.code != 0) {
            System.out.println("发生错误,错误码为:" + myJsonParse.header.code);
            System.out.println("本次请求的sid为:" + myJsonParse.header.sid);
            webSocket.close(1000, "");
        }
        List<Text> textList = myJsonParse.payload.choices.text;
        for (Text temp : textList) {
            System.out.print(temp.content);
        }
        if (myJsonParse.header.status == 2) {
            // 可以关闭连接,释放资源
            wsCloseFlag = true;
        }
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        super.onFailure(webSocket, t, response);
        try {
            if (null != response) {
                int code = response.code();
                System.out.println("onFailure code:" + code);
                System.out.println("onFailure body:" + response.body().string());
                if (101 != code) {
                    System.out.println("connection failed");
                    System.exit(0);
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    // 鉴权方法
    public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
        URL url = new URL(hostUrl);
        // 时间
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());
        // 拼接
        String preStr = "host: " + url.getHost() + "\n" +
                "date: " + date + "\n" +
                "GET " + url.getPath() + " HTTP/1.1";
        // System.err.println(preStr);
        // SHA256加密
        Mac mac = Mac.getInstance("hmacsha256");
        SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
        mac.init(spec);

        byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
        // Base64加密
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        // System.err.println(sha);
        // 拼接
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);
        // 拼接地址
        HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//
                addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//
                addQueryParameter("date", date).//
                addQueryParameter("host", url.getHost()).//
                build();

        // System.err.println(httpUrl.toString());
        return httpUrl.toString();
    }

    //返回的json结果拆解
    class JsonParse {
        Header header;
        Payload payload;
    }

    class Header {
        int code;
        int status;
        String sid;
    }

    class Payload {
        Choices choices;
    }

    class Choices {
        List<Text> text;
    }

    class Text {
        String role;
        String content;
    }
}

ps: The Spark model is connected through websocket, but the server will actively disconnect every time a question is sent, so the connection needs to be re-established every time a question is sent. This may be due to the pressure on the server. Let's do this. There is a problem with the pom dependency of the sample code downloaded from the official website. Then pay attention to the domain values ​​​​in the request parameter parts of 1.5 and 2.0 when sending the request. This is also explained on the official website. 2.0 The value is generalv2

, this is the pom file after I modified it (mainly look at the dependencies part):

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tianjun.chat</groupId>
    <artifactId>chat</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>chat</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.67</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket -->
        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.3.8</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.squareup.okio/okio -->
        <dependency>
            <groupId>com.squareup.okio</groupId>
            <artifactId>okio</artifactId>
            <version>2.10.0</version>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.42.Final</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>

        <dependency>
            <groupId>org.asynchttpclient</groupId>
            <artifactId>async-http-client</artifactId>
            <version>2.12.3</version>
        </dependency>

        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.5.3</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                    <transformers>
                        <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>com.tianjun.chat.ChatBox</mainClass> <!-- 修改为你的主类 -->
                        </transformer>
                    </transformers>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>  <!-- 可以根据实际需要选择合适的版本 -->
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>com.tianjun.chat.ChatBox</mainClass>  <!-- 将MainClass替换为你的主类名 -->
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Guess you like

Origin blog.csdn.net/qq_17805707/article/details/133034307
Recommended