Java課設中的問題以及解決方案(三)

前言

這次進行Java的大作業,雖然是一拖三,不過還是準備做得漂亮一點.Java還是很有趣的,並且可能以後工作室項目能用得到.

嗯,如果做得好了,就請自己去搓一頓!

思路

  • 需求分析
  • 架構
  • 界面設計

需求分析

這是一個項目的開始,課程設計(非遊戲類)應該是要去解決一個實際的問題,而不是單純的應付差事.
這一次的項目需求與暑假項目相同,所以就不做贅述.

架構

項目架構是衡量一個項目的質量的重要指標.邏輯清晰的項目結構可以省去開發過程中的很多煩惱,同時,也能夠極大地增加協同開發的效率.

我這次使用的是比較傳統的mvc架構.

  • 最上面的一層,是直接面向最終用戶的"視圖層"(View)。它是提供給用戶的操作界面,是程序的外殼。
  • 最底下的一層,是核心的"數據層"(Model),也就是程序需要操作的數據或信息。
  • 中間的一層,就是"控制層"(Controller),它負責根據用戶從"視圖層"輸入的指令,選取"數據層"中的數據,然後對其進行相應的操作,產生最終結果。

當然也可以將mvc混淆,都合併在少數的文件當中,事實上我在完成C#的課程設計的時候就是這麼做的,這樣的後果也很明顯,我現在已經看不懂我的C#課設了…

當然,便於閱讀維護只是 MVC模式下思路清晰 的一個小小的伴生好處.
隨着項目的膨脹,越來越多的功能涌入,mvc甚至還需要再次進行劃分.這個時候,你是選擇憑藉自己的記憶去記錄各個接口之間的關係,還是寄託於MVC架構,簡單明瞭地管理自己的項目呢?

再說一說協作開發的效率.
協作開發這個詞估計不會存在於我四年大學生活之中了.不過我還是可以憧憬一下的.
mvc模式下,各個模塊功能明確,責任關係清晰,任務可以以極低的耦合度準確地分配到每個人的頭上,如果,我是說如果,一羣水平相當的開發者在這種模式下齊頭並進,開發效率無疑是十分可怕的.

推而廣之,這種模式的變體可以應用到社會的很多合作模式中…emmmm,好吧,這只是一篇講技術的文章,就這樣吧.

現在回頭看看暑期的項目,一個人能開發到這個地步,我還是有點小小的得意的.

界面設計

每一個直男的噩夢,唉…暫且先掛起來吧…

數據庫二三事

Java課設中的問題以及解決方案(二)
Java課設中的問題以及解決方案(一)
中,都有對數據庫連接的一些敘述.不過都是一些比較粗淺的嘗試.

在進行登錄&註冊模塊的開發時,我對數據庫進行了比較深入的瞭解和操作.

prepareStatement 和 createStatement

prepareStatement會先初始化SQL,先把這個SQL提交到數據庫中進行預處理,多次使用可提高效率.

createStatement不會初始化,沒有預處理,每次都是從0開始執行SQL.
兩者這代碼上有顯著的區別.

e.g.

// prepareStatement
ResultSet rs = null;
String sql = "select * from users where  username=? and userpwd=?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1,username); 
pstmt.setString(2, userpwd);
//prepareStatement.setString() 給sql中的"?"賦值,這裏將第一個?設置爲username,第二個?設置爲userpwd

// createStatement
ResultSet rs = null;
String sql = "select * from users where  username= '"+username+"' and userpwd='"+userpwd+"'";
createStatement ps = con.prepareStatement(sql);
rs = stmt.executeQuery(sql);
// createStatement沒有?形式的格式化,直接使用

格式化的方法讓我們在編寫代碼時思路更加清楚,代碼的形式也更加的優雅.(試想一下,上述如果不是2個參數,而是十多個參數,那麼create方法將會有多少個+和")

同時,預編譯的方法還可以有效地抵禦sql注入攻擊.

e.g.

String sql = "select * from user where username= 'zxj' and userpwd='"+varpasswd+"'";

如果用戶在密碼欄中輸入 'or '1' = 1';drop table book; 那麼就構成了這樣一條查詢語句

select * from user where username= 'zxj' and userpwd='or '1' = 1';
drop table usr;

這樣的查詢語句毫無疑問是成立並且是可以通過執行的.
所以,用戶可以通過這種方法,在不獲取數據庫賬號密碼的情況下,刪除你的usr表!~

而如果你使用prepareStatement,用setString的方法傳遞參數,再進行一次預編譯,就可以有效地避免這種困擾.

所以說,無論從代碼的可讀性和可維護性,還是從提高性能方面,或者說避免攻擊方面,都應該使用prepareStatement.

hash加密

密碼的明文傳遞一直是爲業界所詬病的事情.
在進行暑假項目工作的時候,濤哥教我使用hash加密一次密碼.

牢騷話:本來嘛,課設沒必要做到這個地步,不過今天正好濤哥出國,這之後一年才能回來,所以傳承一下他嚴謹的工作態度,算是一個紀念吧

public static String getSHA(String input) {
    MessageDigest md = MessageDigest.getInstance("SHA-256"); 

    byte[] messageDigest = md.digest(input.getBytes()); 

    BigInteger no = new BigInteger(1, messageDigest); 

    String hashtext = no.toString(16); 

    while (hashtext.length() < 32) { 
        hashtext = "0" + hashtext; 
    } 

    return hashtext; 
}

datetime處理

數據庫的datetime數據是xxxx-xx-xx xx : xx : xx形式的,所以就用了一個比較土的辦法…

Date date=new Date();
String date = String.format("%tF%n", date)+" "+String.format("%tT%n",date)

另外,關於string的格式化,推薦一篇博客

後記

  • zxj - 等待,並心懷希望.
  • 濤哥 - 謝謝,再見.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章