Java swing实现应用程序对数据库的访问

199 阅读3分钟

最近在完成软件体系结构上机实验时,遇到一个有点点小难度的选做题,题目信息如下:

利用套接字技术实现应用程序中对数据库的访问。应用程序只是利用套接字连接向服务器发送一个查询的条件,而服务器负责对数据库的查询,然后服务器再将查询的结果利用建立的套接字返回给客户端,如下图所示。

本来吧,选做题,不太想做的,但是考虑到以后工作的方向和后端相关,那还是做吧。

本次实验需要做一个GUI界面和一个连接查询功能,在论坛上借鉴了其他大佬获取网站内容的部分代码,然后自己做了一个及其简陋的swing界面,算是把这个实验完成了。

本次实验项目结构如下

 --socketProject
     |--Client.java
     |--GUI.java
     |--SearchInfo.java
     |--Server.java
     |--ServerThread.java

Client.java

客户端使用dis.readUTF()时,要注意再发送个字符或者空字符,这里发送end,表示关闭连接。不然会出现EOFException

 package socketProject;
 ​
 import java.io.*;
 import java.net.*;
 ​
 public class Client {
     String studentNum = null;
     String result = null;
 ​
     public void setStudentNum(String num) {
         this.studentNum = num;
         System.out.println("stu: " + studentNum);
     }
 ​
     public void run() throws IOException {
         Socket ss = new Socket("127.0.0.1", 8888);
         System.out.println("Socket: " + ss);
         try {
             DataInputStream dis = new DataInputStream(ss.getInputStream());
             DataOutputStream dos = new DataOutputStream(ss.getOutputStream());
             // the interaction
             dos.writeUTF(studentNum); // 向服务器发送学号
             dos.flush();
             result = dis.readUTF().toString(); // 获得客户端的json字符串
             System.out.println(result);
             dos.writeUTF("end"); // 不加这句会报错
             dos.flush();
             if (dos != null)
                 dos.close();
             if (dis != null)
                 dis.close();
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
             if (ss != null)
                 ss.close();
         }
     }
     // gui界面用于获取json结果
     public String getResult() {
         return result;
     }
 }

Server.java

 package socketProject;
 ​
 import java.io.*;
 import java.net.*;
 ​
 public class Server extends Thread {
     public static final int PORT = 8888;
 ​
     // public static void main(String[] args) throws IOException {
     public void run() {
         try (ServerSocket serverSocket = new ServerSocket(PORT)) {
             System.out.println("ServerSocket: " + serverSocket);
             try {
                 while (true) {
                     Socket socket = serverSocket.accept();
                     System.out.println("Socket accept: " + socket);
                     Thread thread = new Thread(new ServerThread(socket));
                     thread.start(); // 开启一个线程,使之支持接收多个客户端的请求
                 }
             } finally {
                 serverSocket.close();
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }

ServerThread.java

 package socketProject;
 ​
 import java.io.*;
 import java.net.*;
 ​
 public class ServerThread extends Thread {
     Socket socket = null;
 ​
     public ServerThread(Socket socket) {
         this.socket = socket;
     }
 ​
     public void run() {
         try {
             DataInputStream dis = new DataInputStream(socket.getInputStream());
             DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
             while (true) {
                 String str = dis.readUTF().toString();
                 String data = new SearchInfo().run(str);
                 if (str.equals("end"))
                     break;
 ​
                 dos.writeUTF(data);
             }
             dos.close();
             dis.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }

SearchInfo.java

 package socketProject;
 ​
 import java.io.*;
 import java.net.*;
 ​
 public class SearchInfo {
     public String run(String s) {
         String url = "your database interface";
         String param = s;
         String sendGET = GetUrl(url, param);
         return sendGET;
     }
     
     public static String GetUrl(String url, String param) {
         String result = ""; // define the result str
         BufferedReader read = null; // define the access result
         
         try {
             URL realUrl = new URL(url + param);
             URLConnection connection = realUrl.openConnection();
             
             connection.setRequestProperty("accept", "*/*");
             connection.setRequestProperty("connection", "Keep-Alive");
             connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
             // 这里补充通用的请求属性
             connection.connect(); // 建立实际的连接
             
             read = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
             String line;
             while ((line = read.readLine()) != null) {
                 result += line;
             }
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             if (read != null) {// 关闭流
                 try {
                     read.close();
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
         }
         return result;
     }
     
     public String getJSON(String param) {
         return param;
     }
 }

GUI.java

 package socketProject;
 ​
 import java.awt.*;
 import java.awt.event.*;
 import java.io.IOException;
 import javax.swing.*;
 ​
 public class GUI extends JFrame {
     private JButton connectDataBase;
     private JLabel entryStudentNum;
     private JTextField studentNum;
     private JButton sendRequest;
     private JLabel showResponseMsg;
     private JPanel northPanel;
     private JPanel southPanel;
 ​
     public GUI() {
         init();
     }
 ​
     public void init() {
         setTitle("没啥技术含量的东西");
         // define the component for the window
         connectDataBase = new JButton("连接数据库");
         entryStudentNum = new JLabel("输入学号");
         studentNum = new JTextField();
         sendRequest = new JButton("发送");
         showResponseMsg = new JLabel();
 ​
         // add the component to the panel
         this.setLayout(new GridLayout(2, 1));
 ​
         northPanel = new JPanel(new GridLayout(1, 4));
 ​
         northPanel.add(connectDataBase);
         northPanel.add(entryStudentNum);
         northPanel.add(studentNum);
         northPanel.add(sendRequest);
 ​
         southPanel = new JPanel(new GridLayout(1, 1));
 ​
         southPanel.add(showResponseMsg);
 ​
         setButtons();
 ​
         this.add(northPanel);
         this.add(southPanel);
         // initial the window
         setBounds(400, 200, 600, 120);
         setResizable(false);
         setDefaultCloseOperation(EXIT_ON_CLOSE);
         setVisible(true);
     }
 ​
     public void setButtons() {
         connectDataBase.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
                 // 这里初始化服务端
                 Server server1 = new Server();
                 Thread th1 = new Thread(server1);
                 th1.start();
                 // 这里一定要开启服务端线程,否则在点击此按钮后,整个界面会卡住,无法进行下一步操作
             }
         });
 ​
         sendRequest.addActionListener(new ActionListener() {
 ​
             @Override
             public void actionPerformed(ActionEvent e) {
                 Client client1 = new Client();
                 client1.setStudentNum(studentNum.getText());
                 // 获取文本框的文字,并赋给客户端的studentNum保存
                 try {
                     client1.run();
                 } catch (IOException e1) {
                     e1.printStackTrace();
                 }
                 showResponseMsg.setText(client1.getResult());
                 // 将得到的数据显示在界面上
             }
         });
     }
 ​
     public static void main(String[] args) {
         new GUI();
     }
 }

最终效果如下:

使用时,先点击连接数据库,然后根据学校提供的接口,输入自己的学号,点击发送,即可查询个人信息。

不过由于项目工作区非maven以及未来方向非Java的缘故,没有去深究如何提取json的值 (偷个懒)

参考链接

Java请求一个URL,获取返回的数据_杜岚特的博客-CSDN博客

java.io.datainputstream.readunsignedshort_socket编程报异常java.io.EOFException_窦月汐的博客-CSDN博客