在上次代码的基础上我加一个窗口,友好的交互界面更具实用性,效果如图

 

代码:

package com.yang.Ichat.Ichat;

import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.Toolkit;

import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Font;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import java.util.TreeMap;


import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Color;

public class Index extends JFrame {
    
    //会话的属性
    private static String APP_ID = "*******";    //你自己的  app_id
    private static String API_INTERFACE = "https://api.ai.qq.com/fcgi-bin/nlp/nlp_textchat";
    private static String SESSION = "100001";
    private static String APP_KEY = "*******";//你自己的APP_key

    
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        
        Index frame = new Index();
        frame.setVisible(true);
    }

    
    /**
     * Create the frame.
     */
    public Index() {

        //窗口
        setIconImage(Toolkit.getDefaultToolkit().getImage("****\\**.png"));//设置图标
        setTitle("Ichat");//设置标题
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口时退出程序
        setBounds(600, 300, 580, 433);//窗口位置及大小
        
        //实例化一个容器
        JPanel contentPane = new JPanel();
        setContentPane(contentPane);//将容器添加到窗口
        contentPane.setLayout(null);//容器的布局类型
        
        //创建一个文本域
        final JTextArea textArea = new JTextArea();
        textArea.setForeground(Color.GREEN);//设置字体颜色
        textArea.setEditable(false);//使文本域不可编辑
        textArea.setWrapStyleWord(true);//单词边界换行
        textArea.setLineWrap(true);//内容超出时换行
        textArea.setFont(new Font("Monospaced", Font.PLAIN, 16));//设置字体大小
        textArea.setBounds(0, 26, 562, 311);//设置位置大小
        //contentPane.add(textArea);//添加到容器
        
        //创建一个标签
        JLabel label = new JLabel("聊天小助手");//显示内容
        label.setForeground(Color.RED);//字体颜色
        label.setFont(new Font("黑体", Font.PLAIN, 17));//字体样式
        label.setBounds(229, 7, 133, 18);//位置大小
        contentPane.add(label);//添加到容器
        
        //输入框
        final JTextField textField = new JTextField();
        //添加按键监听事件
        textField.addKeyListener(new KeyAdapter() {
            @Override
            //当按下回车键时执行
            public void keyPressed(KeyEvent e) {
                if(e.getExtendedKeyCode() == KeyEvent.VK_ENTER){
                    textArea.append("我:\n\t" + textField.getText()+"\n");//向文本域添加我输入的字符
                    textArea.append(get(textField.getText()));//将我输入的字符发送到服务器,并得到回应
                    textField.setText("");//清空文本框
                }
            }
        });
        textField.setBounds(0, 353, 496, 24);//位置大小
        contentPane.add(textField);//添加到容器
        
        //发送按钮
        JButton button = new JButton("发送");
        //按键监听
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                
                textArea.append("我:\n\t" + textField.getText()+"\n");//将内容添加到文本域
                textArea.append(get(textField.getText()));//得到回应并添加到浏览器
                textField.setText("");//清空文本框
            }
        });
        button.setBounds(491, 353, 71, 24);//位置大小
        contentPane.add(button);//添加到容器
        
        //创建一个带滚动条的容器
        JScrollPane scrollPane = new JScrollPane(textArea);//将文本域添加到该容器
        scrollPane.setBounds(0, 26, 562, 311);//容器大小的位置(和文本域控件一样)
        contentPane.add(scrollPane);//添加到容器
    }
    
    
    
        
        /***得到信息***/
        public static String get(String question){
            
            StringBuilder builder=new StringBuilder();//创建实例
            try{
                
                URL url=new URL(API_INTERFACE + "?" + post(question));//创建一个URL类的实例,并指定网址
                
                URLConnection connection=url.openConnection();//创建实例连接指定URL上的内容
                
                InputStream is=connection.getInputStream();//获取内容的字节流
                
                InputStreamReader isr=new InputStreamReader(is,"utf-8");//将字节流包装为字符串流,并制定编码格式为utf-8
                
                BufferedReader br=new BufferedReader(isr);//创建一个实例用来存放转换后的字符
                
                while (br.readLine() != null){//读取信息,并且当信息不为空时
                    
                        builder.append(br.readLine() + "\n");
                    }
                br.close();//关闭流
                isr.close();//关闭流
                is.close();//关闭流
                //System.out.println(builder);//输出读取的信息
                
                }catch (MalformedURLException e){//当try代码块有异常时转到catch代码块 
                    e.printStackTrace();//打印异常所在位置及原因
                }catch (IOException e){//当try代码块有异常时转到catch代码块
                    e.printStackTrace();//打印异常所在位置及原因
            }
            
            //返回截取后的内容
            return print(builder.toString());
            
        }


        
        /***打印信息*/
        public static String print(String str){
            
            String answer = null;
            String ret = null;
            
            //获得回话
            answer = str.substring(str.indexOf("answer")+10 , str.lastIndexOf("\""));
            
            //获得状态码
            ret = str.substring(str.indexOf("ret")+6 , str.indexOf(","));
            
            //判断状态码如果为16394说明回话为空
            return ("\n澜澜:\n\t" + (ret.equals("16394") ? "我不明白你在说什么呢!" : answer) + "\n\n");
            
        }

        
        /***请求信息***/
        public static String post(String question){
            
            //treemap是有序的默认降序排序,hashmap无序
            TreeMap<String , String> tm = new TreeMap<>();
            
            //将数据放入treemap
            tm.put("app_id", APP_ID);
            tm.put("time_stamp", System.currentTimeMillis()/1000 + "");//获得系统时间 秒
            tm.put("nonce_str", random(10));//随机字符串
            tm.put("session", SESSION);
            tm.put("question", question);
            tm.put("sign", sign(tm));//生成秘钥
            
            StringBuffer sb = new StringBuffer();
            
            //将treemap里的内容拼接成url格式
            for(String key: tm.keySet()){

                sb.append(key + "=" + (encode(tm.get(key))).toUpperCase() + "&");
                
            }
            sb.deleteCharAt(sb.length()-1);//去掉字符串结尾的 &
            
            return sb.toString();
            
        }
        
        
        /**
         * 将<key, value>请求参数对按key进行字典升序排序,得到有序的参数对列表N
            将列表N中的参数对按URL键值对的格式拼接成字符串,得到字符串T(如:key1=value1&key2=value2),URL键值拼接过程value部分需要URL编码,
            URL编码算法用大写字母,例如%E8,而不是小写%e8
            将应用密钥以app_key为键名,组成URL键值拼接到字符串T末尾,得到字符串S(如:key1=value1&key2=value2&app_key=密钥)
            对字符串S进行MD5运算,将得到的MD5值所有字符转换成大写,得到接口请求签名
         * 
         * 生成签名
         * 参考 https://blog.csdn.net/Java_Antelope/article/details/100015942
         * @throws IOException 
         */
        private static String sign(TreeMap<String, String> tm){
        
            StringBuffer sb = new StringBuffer();
            
            for(String key: tm.keySet()){

                sb.append(key + "=" + (encode(tm.get(key))).toUpperCase() + "&");
                
            }
            
            sb.append("app_key=" + APP_KEY);
            
            return md5(sb.toString());
        }

        
        
        /***URL加密 ***/
        public static String encode(String str){
            
            String s = null;
            //url加解密URLDecoder.decode( URL, "UTF-8" )
            try {
                s = java.net.URLEncoder.encode(str, "UTF-8").toUpperCase();
            } catch (UnsupportedEncodingException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
            return s;
        }    
        
        
        
        /***生成随机字符 ***/
        public static String random(Integer count){
            
            final char[] ARR = {'1','2','3','4','5','6','7','8','9','0',
                'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
                'x','y','z'};
            
            Random rand = new Random();
            StringBuilder str = new StringBuilder();
            while (count != 0){
                str.append(ARR[rand.nextInt(ARR.length)]);
                count--;
            }
            return str.toString();
        }
        
        
        /***md5算法***/
        public static String md5(String plainText) {
            
            byte[] secretBytes = null;
            try {
                secretBytes = MessageDigest.getInstance("md5").digest(
                        plainText.getBytes());
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException("没有这个md5算法!");
            }
            String md5code = new BigInteger(1, secretBytes).toString(16);
            for (int i = 0; i < 32 - md5code.length(); i++) {
                md5code = "0" + md5code;
            }
            return md5code;
        }
}

 

posted on 2021-06-03 10:04  讨厌鬼  阅读(200)  评论(0)    收藏  举报