電信采集子項目2(具體實現)


1.項目所用到jar包:

  woss-interface.jar:規范項目的各個模塊

    

      各個接口的功能在我的上一篇文章中有介紹,感興趣的去找一下。

  demo4j-1.6.1.jar:解析xml文件

  log4j-1.2.15:提供日志記錄

  ojdbc14.jar:jdbc的jar包

 

3.流程圖

     

  畫的不好別見怪,嘿嘿。

 

 

2.項目的各個模塊的具體實現

   2.1客戶端采集模塊

      假如我們需要采集的數據的結構如下:

        #briup1660|037:wKgB1660A|7|1239110900|44.211.221.247

        #briup4418|037:wKgB4418A|7|1239138480|251.196.223.191

        #|037:wKgB1660A|8|1239203860|44.211.221.247

      

      問題:
        1.怎么獲得文件路徑
        2.了解每一行數據的意思
          2.1 數據中使用的是|進行分割
          2.2 數據一共分為倆種
              遵循7上8下的規則
              包含 7 的數據 表示用戶上線
              包含 8 的數據 表示用戶下線
          2.3 包含7的數據
              數據分為五個部分
                第一部分:登錄的用戶名字(去掉#號)
                第二部分:NAS服務器的名稱
                第三部分:一定是7
                第四部分:上線的時間(單位是秒)
                第五部分:登錄時的IP
          2.4 包含8的數據
              數據分為五個部分
                第一部分:一定是個符合 #
                第二部分:NAS服務器的名稱
                第三部分:一定是8
                第四部分:下線的時間(單位是秒)
                第五部分:登錄時的IP

         3.如何讀寫數據
         4.如何封裝數據
         5.采集的數據分倆種情況
           第一種情況數據:
              用戶上線了同時也下線了
           第二種情況數據:
              用戶上線了但是還沒有下線
         6.倆種數據情況怎么處理
           上面描述的第一種數據:
              封裝好對象之后就准備傳給服務器端
           上面描述的第二種數據:
              進行數據的備份,在一下次采集中,需要把這個備份的數據重新讀出來使用,因為用戶可能在一下次采集中下線了
         7.第二次讀取數據的時候,如何從第一次讀完數據的下一行開始讀
              可以記錄一下本次總共讀取了多少個字節,下一次可以直接跳過這么多個字節,接着讀就可以了
         8.在讀取過程中或者處理過程中,如果出現了異常,需要把數據進行備份
         9.注意重要信息的日志記錄

         以下是實現代碼:

          

 1 package com.briup.woss.client;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.FileInputStream;
 5 import java.io.InputStream;
 6 import java.io.InputStreamReader;
 7 import java.sql.Timestamp;
 8 import java.util.ArrayList;
 9 import java.util.Collection;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Properties;
14 
15 import org.junit.Test;
16 
17 import com.briup.util.BIDR;
18 import com.briup.util.Configuration;
19 import com.briup.woss.ConfigurationAWare;
20 
21 public class GatherImpl implements Gather{
22 
23     private static String file;
24     private InputStream fis;
25     private InputStreamReader isr;
26     private BufferedReader br;
27     public Map<String, BIDR> map1;
28     private List<BIDR> date;
29 
30     // 讀取數據/解析/封裝成BIDR對象/對象存放在集合
31     // #briup4418|037:wKgB4418A|7|1239138480|251.196.223.191
32     // #|037:wKgB1660A|8|1239203860|44.211.221.247
33     @Override
34     public void init(Properties p) {
35         file = p.getProperty("filePath");//將配置文件注入到該模塊中
36     }
37     
38         //接收數據,將數據進行處理,並保存到collection集合中,並返回。
39     @Override
40     @Test
41     public Collection<BIDR> gather() throws Exception {
42         // 獲取文件內容
43         BIDR bidr = null;
44         map1 = new HashMap<String, BIDR>();
45         date = new ArrayList<>();
46         fis = new FileInputStream(file);
47         isr = new InputStreamReader(fis);
48         br = new BufferedReader(isr);
49         String str = null;
50         while ((str = br.readLine()) != null) {
51             bidr = new BIDR();
52                         //通過|分割字符串,由於|號比較特殊,要加[]號
53             String[] arrStr = str.split("[|]");
54             if ("7".equals(arrStr[2])) {
55                 bidr.setAAA_login_name(arrStr[0]);
56                 bidr.setNAS_ip(arrStr[1]);
57                                 //由於bidr中時間是Timestamp類型的所以這里轉換的時候要注意下
58                 bidr.setLogin_date(new Timestamp(
59                         Long.parseLong(arrStr[3]) * 1000));
60                 bidr.setLogin_ip(arrStr[4]);
61                 map1.put(arrStr[4], bidr);
62             } else {
63 
64                 BIDR b = map1.remove(arrStr[4]);
65                 b.setLogin_ip(arrStr[1]);
66                 b.setLogout_date(new Timestamp(Long.parseLong(arrStr[3]) * 1000));
67                 long l = (b.getLogout_date().getTime() - b.getLogin_date()
68                         .getTime());
69                 b.setTime_deration((int) l);
70                 date.add(b);
71             }
72         }
73 
74         return date;
75     }
76 
77 }                  

 

 

  2.2備份模塊

     負責備份一些沒有處理完的數據

     需要實現的方法:
      void store(String filePath, Object obj,
      boolean append)
      Object load(String filePath, boolean del)
    問題:
      1.如何獲得備份文件存放的目錄信息
      2.如何把數據備份到文件
      3.如何讀取文件中的備份數據
      4.如何實現備份數據時候的追加或者是覆蓋
      5.如何控制讀取備份數據后文件是否需要刪除

    以下是實現代碼:

    

package com.briup.woss.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Properties;

import com.briup.util.BackUP;

public class BackUpImpl implements BackUP{

    static String fName;
    @Override
    public void init(Properties p) {
        fName = p.getProperty("bakFilePath");
    }
        //通過對象輸出流將需要備份的數據進行備份
    @Override
    public void store(String fileName, Object obj,
            boolean paramBoolean) throws Exception {
        File file = new File(fName+fileName);
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file,paramBoolean));
        out.writeObject(obj);
    }

    @Override
    public Object load(String fileName, boolean paramBoolean)
            throws Exception {
        File file = new File(fName+fileName);
        if(!file.exists()){
            return null;
        }
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
        Object object = in.readObject();
        return object;
    }

}

 

  

  2.3網絡模塊

    負責把采集好的數據發給服務器

    需要實現的方法:
      void send(Collection<BIDR> c)
      問題:
        1.如何得到連接服務器的相關信息
        2.如何得到采集好的數據
        3.如何把數據發送給服務器
        4.如果發送數據失敗怎么處理
        5.注意重要信息的日志記錄

    以下是實現代碼

      

package com.briup.woss.client;

import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Collection;
import java.util.Properties;

import com.briup.util.BIDR;

public class ClientImpl implements Client{

    static String ip;
    static int port;
    @Override
    public void init(Properties p) {    //通過依賴注入的方式將配置信息注入到該模塊中
        ip = p.getProperty("ip");
        port = Integer.parseInt(p.getProperty("port"));
    }
        //通過socket以及對象流將數據傳輸到客戶端
    @Override
    public void send(Collection<BIDR> c) throws Exception {
        Socket s = new Socket(ip, port);
        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
        oos.writeObject(c);
    }
}

 

  

  2.4服務器端網絡模塊

    負責接收客戶端傳過來的數據

    需要實現的方法:
      Collection<BIDR> revicer();
      void shutdown();
    問題:
      1.如何獲得服務器啟動時候用的相關信息
      2.如何關閉關閉服務器
      3.如何接收客戶端傳過來的信息
      4.如何處理客戶端並發的問題
      5.接收到數據之后一下步怎么做
      6.數據的接收或者處理過程備份的問題
      7.注意重要信息的日志記錄

    以下是實現代碼

     

package com.briup.woss.server;

import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Properties;

import com.briup.util.BIDR;
import com.briup.util.Configuration;
import com.briup.woss.ConfigurationAWare;

public class ServerImpl implements Server,ConfigurationAWare{

    static int port;
    private ObjectInputStream ois;
    private Object o;
    private static DBStoreImpl dbStore;
    @Override
    public void init(Properties p) {
        port = Integer.parseInt(p.getProperty("server_port"));
    }
        //這里通過多線程的方式接受數據,通過調用入庫模塊進行入庫
        //因為服務器端可能只有一個,但是客戶端應該有多個,同時接收來自多個客戶端發來的信息時便需要實現多線程
    @Override
    public Collection<BIDR> revicer() throws Exception {
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                ServerSocket ss;
                try {
                    ss = new ServerSocket(port);
                    Socket s = ss.accept();
                    ois = new ObjectInputStream(s.getInputStream());
                    Collection<BIDR> c = (Collection)ois.readObject();
                    dbStore.saveToDB(c);
                } catch (Exception e) {
                    e.printStackTrace();
                } 
            }
        }).start();
        
        return null;
    }

    @Override
    public void shutdown() {
        
    }

    @Override
    public void setConfiguration(Configuration p) {
        try {
            dbStore = (DBStoreImpl) p.getDBStore();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

  

  2.5服務器端入庫模塊

    負責接收到的數據插入到數據庫中

    需要實現的方法:
      void saveToDB(Collection<BIDR> c)
    問題:
      1.如何獲得連接數據庫的相關信息
      2.怎么把數據插入到數據庫中
      3.插入數據時候的效率問題
      4.什么樣的數據對應哪一種表

    

package com.briup.woss.server;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Properties;


import javax.swing.JTextArea;

import com.briup.util.BIDR;
import com.briup.woss.GUI.DisData;
import com.briup.woss.GUI.MyAppender;

public class DBStoreImpl implements DBStore{
    
    private static String driver;
    private static String url;
    private static String user;
    private static String password;
    private String aaa_login_name;
    private String login_ip;
    private java.sql.Date login_date;
    private java.sql.Date logout_date;
    private String nas_ip;
    private String time_duration;
    private Connection conn;
    private int i_date;
    private Properties p;
    
    public DBStoreImpl() {
        p = new Properties();
        init(p);
    }
    
    @Override
    public void init(Properties p) {
        driver = p.getProperty("driver");
        url = p.getProperty("url");
        user = p.getProperty("username");
        password = p.getProperty("password");
    }
    
    @Override
    public void saveToDB(Collection<BIDR> p) throws Exception {
                //通過jdbc與數據庫建立鏈接
        Class.forName(driver);
        conn = DriverManager.getConnection(url, user, password);
        for (BIDR bidr : p) {
            Timestamp login_d = bidr.getLogin_date();
            String s_date = login_d.toString();
            String[] str1 = s_date.split(" ");
            String[] str2 = str1[0].split("-");
            i_date = Integer.parseInt(str2[2]);
            
            aaa_login_name = bidr.getAAA_login_name();
            login_ip = bidr.getLogin_ip();
            login_date = new java.sql.Date(bidr.getLogin_date().getTime());
            logout_date = new java.sql.Date(bidr.getLogout_date().getTime());
            String sql = "insert into t_detail_"+i_date+"(aaa_login_name,login_ip,login_date,logout_date,nas_ip,time_duration) "
                    + "values(?,?,?,?,?,?)";
            //通過PreparedStatement將信息存儲到數據庫中
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, aaa_login_name);
            ps.setString(2, login_ip);
            ps.setDate(3, login_date);
            ps.setDate(4, logout_date);
            ps.setString(5, nas_ip);
            ps.setString(6, time_duration);
            ps.execute();
                        //將數據傳送到DisData這個類中,此類是用來將入庫信息顯示在GUI中的。
            new DisData(p);
        }
    }

    
}
    

  

  2.6公共配置模塊

    該模塊相當於一個工廠

    負責
    1.產生各個模塊對象
    2.讀取各個模塊所需的信息,並且把信息注入到每個模塊中
      注:這時候需要每個模塊都實現接口WossModule
    3.如果某個模塊A中需要用到配置模塊,那么就需要把自己(因為自己就是配置模塊)注入到這個模塊A中
      注:這時候需要模塊A實現接口ConfigurationAWare

    需要實現的方法:
      Logger getLogger();
      BackUP getBackup();
      Gather getGather();
      Client getClient();
      Server getServer();
      DBStore getDBStore();

    問題:
      1.怎么獲得每個模塊的相關信息
      2.如何創建每個模塊的對象
      3.怎么把每個模塊需要的數據注入到模塊中

      4.什么時候可以把自己(配置模塊本身)注入到需要的模塊中

    以下是實現代碼:

    

package com.briup.woss.util;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import com.briup.util.BackUP;
import com.briup.util.Configuration;
import com.briup.util.Logger;
import com.briup.woss.ConfigurationAWare;
import com.briup.woss.WossModule;
import com.briup.woss.client.Client;
import com.briup.woss.client.Gather;
import com.briup.woss.server.DBStore;
import com.briup.woss.server.Server;

public class ConfigurationImpl implements Configuration{

    Map<String, Object> objMap;
    
    Properties p1;
    Properties p2;
    
    public ConfigurationImpl() {
        this("src/conf/conf.xml");
    }
    
    public ConfigurationImpl(String filePath) {
        init(filePath);
    }

    public void init(String filePath){
        
        objMap = new HashMap<String, Object>();
        ParseXML p = new ParseXML();
        Map<String, Properties> map = p.parseXML(filePath);
        p1 = map.get("p1");
        p2 = map.get("p2");
        
        
        for(Object obj:p1.values()){
            try {
                Object instance = Class.forName((String)obj).newInstance();
                objMap.put((String)obj, instance);
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        for(Object obj:objMap.values()){
            if(obj instanceof WossModule){
                ((WossModule)obj).init(p2);
            }
            if(obj instanceof ConfigurationAWare){
                ((ConfigurationAWare) obj).setConfiguration(this);
            }
        }
        
    }
    @Override
    public Logger getLogger() throws Exception {
        return (Logger) objMap.get("com.briup.woss.util.LoggerImpl");
    }

    @Override
    public BackUP getBackup() throws Exception {
        return (BackUP) objMap.get("com.briup.woss.util.BackUpImpl");
    }

    @Override
    public Gather getGather() throws Exception {
        return (Gather) objMap.get("com.briup.woss.client.GatherImpl");
    }

    @Override
    public Client getClient() throws Exception {
        return (Client) objMap.get("com.briup.woss.client.ClientImpl");
    }

    @Override
    public Server getServer() throws Exception {
        return (Server) objMap.get("com.briup.woss.server.ServerImpl");
    }

    @Override
    public DBStore getDBStore() throws Exception {
        return (DBStore) objMap.get("com.briup.woss.server.DBStoreImpl");
    }

}

 

  

  2.7公共日志模塊

     負責記錄系統運行過程的一些重要信息

     需要實現的方法:
        void debug(String msg);
        void info(String msg);
        void warn(String msg);
        void error(String msg);
        void fatal(String msg);
    問題:
      1.怎么來實現日記記錄
      2.了解日志級別
      3.怎么設置日志的級別
      4.怎么獲得日志對象
      5.怎么控制日志的格式
      6.怎么控制日志輸出到控制台和指定文件中(重難點)

    一下是實現代碼:

    

package com.briup.woss.util;

import java.util.Properties;



import org.apache.log4j.PropertyConfigurator;

import com.briup.util.Logger;

public class LoggerImpl implements Logger{

    private static org.apache.log4j.Logger logger;
    
    @Override
    public void init(Properties p) {
        String configFilePath = p.getProperty("configFilePath");
        PropertyConfigurator.configure(configFilePath);
        logger = org.apache.log4j.Logger.getRootLogger();
    }

    @Override
    public void debug(String paramString) {
        logger.debug(paramString);
    }

    @Override
    public void info(String paramString) {
        logger.info(paramString);
    }
    
    @Override
    public void warn(String paramString) {
        logger.warn(paramString);
    }

    @Override
    public void error(String paramString) {
        logger.error(paramString);
    }

    @Override
    public void fatal(String paramString) {
        logger.fatal(paramString);
    }

}

 

 

3一些輔助類,以及GUI頁面實現

  解析XML文件類

    目的:所有的jdbc配置信息,以及woss-interface.jar中各個接口的信息都配置在xml文件中,所以要通過sax解析將配置信息獲取到。

    然后存入map集合中,在公共配置模塊獲取到。

    

package com.briup.woss.util;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


@SuppressWarnings("all")
public class ParseXML {
    
    Map<String, Properties> map;
    Properties p1;
    Properties p2;
    public Map<String, Properties> parseXML(String filePath){
        
        try {
            
            map = new HashMap<String, Properties>();
            
            p1 = new Properties();
            
            p2 = new Properties();
            
            SAXReader reader = new SAXReader();
            
            reader.setEntityResolver(new EntityResolver() {
                
                @Override
                public InputSource resolveEntity(String publicId, String systemId)
                        throws SAXException, IOException {
            
                    byte[] bytes = "".getBytes();
                    
                    return new InputSource(new ByteArrayInputStream(bytes));
                }
            });
            
            Document document = reader.read(new FileInputStream(filePath));
            
            Element rootElement = document.getRootElement();
            
            List<Element> elements = rootElement.elements();
            
            for(Element e:elements){
                
                String name = e.getName();
                String className = e.attributeValue("class");
                List<Element> elements2 = e.elements();
                p1.setProperty(name, className);
                
                for(Element e1:elements2){
                    String tagName = e1.getName();
                    String name1 = e1.getText();
                    p2.setProperty(tagName, name1);
                }
                
                map.put("p1",p1);
                map.put("p2",p2);
                
                
            //    System.out.println(className);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map; 
        
    }
}

 

 

  GUI類

  目的:通過圖形界面化的方式將功能顯示在界面上,有利於用戶交互。

  實現代碼:

    

package com.briup.woss.GUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import org.apache.log4j.Appender;
import org.junit.Test;

import com.briup.woss.server.DBStoreImpl;
import com.briup.woss.util.ConfigurationImpl;

@SuppressWarnings("all")
public class GUI extends JFrame implements ActionListener{
    
    private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getRootLogger();
    private JPanel northJPanel;
    private JPanel centerJPanel;
    private JButton start_client;
    private JButton start_server;
    private JButton dis_data;
    private static JTextArea area;
    private static JScrollPane scrollPane;
    private static Appender appender;
    
    public static void main(String[] args) {
        new GUI();
    }
    
    public GUI() {
        try {
            this.setSize(600, 400);
            this.setBackground(Color.BLACK);
            this.setLocationRelativeTo(null);
            this.setResizable(false);
            init();
            initLog1();
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            this.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void init(){
        Container container = getContentPane();
        container.setLayout(new BorderLayout());
        
        //設置北面的JPanel
        northJPanel = new JPanel();
        northJPanel.setBackground(Color.white);
        start_client = new JButton("啟動客戶端");
        start_server = new JButton("啟動服務器");
        dis_data = new JButton("顯示數據");
        dis_data.setBackground(Color.white);
        start_client.setBackground(Color.white);
        start_server.setBackground(Color.white);
        northJPanel.add(start_client);
        northJPanel.add(start_server);
        northJPanel.add(dis_data);
        
        //設置中間的JPanel
        centerJPanel = new JPanel();
        centerJPanel.setBackground(Color.white);
        centerJPanel.setLayout(new BorderLayout());
        area = new JTextArea();
        area.setLineWrap(true);
        area.setBackground(Color.white);
        area.setEditable(false);
        scrollPane = new JScrollPane(area);
        centerJPanel.add(scrollPane,BorderLayout.CENTER);
        
        container.add(northJPanel,BorderLayout.NORTH);
        container.add(centerJPanel,BorderLayout.CENTER);
        
        start_client.addActionListener(this);
        start_server.addActionListener(this);
        dis_data.addActionListener(this);
    }
        
        public static void initLog1(){
        
        try {
            appender = logger.getAppender("textArea");
            ((MyAppender)appender).setArea(area);
            ((MyAppender)appender).setPane(scrollPane);
        } catch (Exception e) {
            e.printStackTrace();
            }
        }
        
    @Override
    public void actionPerformed(ActionEvent e) {
        Object obj = e.getSource();
        if(obj == start_client){
            new Thread(new ClientThread()).start();
            logger.debug("客戶端啟動成功");
        }
        if(obj == start_server){
            new Thread(new ServerThread()).start();
            logger.info("服務器啟動成功");
        }
        
        if(obj == dis_data){
            DisData d = new DisData();
            d.setArea(area);
            d.dis_Data();
        }
    }
    
}

 

 

以上則是這次電信采集項目的大部分代碼,還有的沒貼出來,因為我要趕着吃飯了。有興趣的朋友們可以看一看,共同進步,共勉,加油!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM