在上次代码的基础上我加一个窗口,友好的交互界面更具实用性,效果如图
代码:
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; } }