Java web開發,在一個jsp里放太多java代碼的後果,摘自 java web輕量級開發麵試教程

来源:http://www.cnblogs.com/JavaArchitect/archive/2017/08/29/7448865.html
-Advertisement-
Play Games

現要做一個簡單的登錄頁面,如果用戶通過驗證,會顯示Welcome用戶名的歡迎詞,反之則返回登錄頁面讓用戶再次輸入 這部分的完整代碼是JSPDemo項目里的login.jsp,下麵來分析一下關鍵代碼。 代碼位置 視頻位置 code/第3章/JSPDemo 視頻/第3章/JSP案例的講解 代碼位置 視頻 ...


 

現要做一個簡單的登錄頁面,如果用戶通過驗證,會顯示Welcome用戶名的歡迎詞,反之則返回登錄頁面讓用戶再次輸入

這部分的完整代碼是JSPDemo項目里的login.jsp,下麵來分析一下關鍵代碼。

代碼位置

視頻位置

code/第3章/JSPDemo

視頻/第3章/JSP案例的講解

根據JSP的語法,可以通過@import來導入需要的jar包。這裡需要導入支持MySQL的庫文件,這部分的代碼如下所示。

1     <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>

2   <%@ page import="java.sql.*"%>

3   <%@ page import="com.mysql.jdbc.Driver" %>

JSP相當於在HTML頁面加上Java代碼,一般在<body>標簽里放入主要代碼。

首先來分析一下業務,當進入這個頁面的時候,需要判斷是否有用戶名和密碼信息輸入,以此來做不同的動作,所以在開始部分,需要用一個內嵌對象request來完成這個功能,主要代碼如下。

4     <body>

5   <%

6        if(request.getParameter("username") == null)

7        {

8    %>

9   <form method="post" action="login.jsp" name="userInfo" id="userInfo">

10  <table>

11       <tr>

12           <td>User Name</td>

13           <td><input type="text" name="username" id="username" /></td>

14       </tr>

15       <tr>

16           <td>Password </td>

17           <td><input type="password" name="password" id="password" /></td>

18       </tr>

19       <tr>

20           <td colospan="2" align="center">

21  <input type="submit" name="logon" value="Login" />&nbsp;&nbsp;

22       <input type="reset" name="reset" value="Reset" />

23           </td>

24       </tr>

25  </table>

26  </form>

我們看到,在JSP里是用<%...%>把Java代碼包含起來的,這裡用request.getParameter來讀取是否有username這個信息。request是個內嵌對象,可以不用定義就能直接使用,這裡用到它的獲取參數的方法。

在JSP里有不少內嵌對象,在項目里經常用到的是request、response、Session、out等,關於內嵌對象的知識大家不用硬記,可以在用到的時候查現成的API。

一旦發現沒有用戶名的信息輸入,那麼就需要用一個HTML的form來顯示供用戶輸入的視窗。

如果request.getParameter("username")不是null,即用戶已經輸入了用戶名,那麼就需要獲取用戶名和密碼信息,併到資料庫進行驗證,代碼如下所示。

27   <%

28      }

29      else

30      {

31          String username = request.getParameter("username").toString();

32          String pwd = "";

33          if(request.getParameter("password") != null)

34          {

35              pwd = request.getParameter("password").toString();

36          }       

37          //connect to DB

38          Class.forName("com.mysql.jdbc.Driver");       

39       Connection connection = null;

40       connection = DriverManager.getConnection(

41                   "jdbc:mysql://localhost:3306/book", "root", "123456");

42          String sql = "select username from users where UserName = ?and Pwd = ?";

43       PreparedStatement pst = connection.prepareStatement(sql);

44       pst.setString(1, username);

45       pst.setString(2, pwd);

46           ResultSet rs=pst.executeQuery();

47       //can login

48       if(rs.next())

49       {

50  %>

51          Welcome,<%= rs.getString("username") %>

從上述代碼中的第31和35行得到了用戶名和密碼之後,用第38行的Class.forName載入了JDBC的驅動程式,然後在第43行定義了一個PreparedStatement來執行SQL語句,併在第46行用一個ResultSet來接收運行結果。

請大家註意,這裡用到的PreparedStatement是為了避免SQL註入,這部分的知識點大家可以看本書的資料庫相關的內容。

一旦通過第48行的if語句判斷rs.next()有返回對象,那麼就需要先在第50行用%>結束Java部分的JDBC訪問資料庫的代碼,隨後在第51行顯示Welcome的字樣。這裡能看到JSP的另外一個語法,用<%=%>來顯示變數的結果。

如果第48行里rs.next沒有返回,也就是說,在資料庫里找不到匹配的用戶信息,那麼就需要返回到登錄頁面,讓用戶再次輸入登錄信息,這部分的代碼如下。

52   <%     

53       }

54       else

55       {

56  %>

57  <form method="post" action="login.jsp" name="userInfo" id="userInfo">

58  <table>

59       <tr>

60           <td>User Name</td>

61           <td><input type="text" name="username" id="username" /></td>

62       </tr>

63       <tr>

64           <td>Password </td>

65           <td><input type="password" name="password" id="password" /></td>

66       </tr>

67       <tr>

68           <td colospan="2" align="center">

69  <input type="submit" name="logon" value="Login" />&nbsp;&nbsp;

70           <input type="reset" name="reset" value="Reset" />

71           </td>

72       </tr>

73  </table>

74  </form>

75  <%      

76       }

77      }  

78  %>

79  </body>

80  </html>

這裡其實是代碼複製,又寫了一遍提供用戶名和密碼輸入的form。

JSP的語法不算簡單,但大家可以有選擇性地瞭解,從而把學習時間用到更重要的知識點(比如框架思想、優化思想)的學習上。

 

在上述代碼給出的例子中,能看到如下的缺陷:

①出現了代碼複製,把供用戶輸入的form複製了兩次。

②頻繁地切換JSP和HTML的邏輯,導致閱讀上和開發上的困擾,日後如果別人來維護這部分代碼,會很困難。

剛開始開發的時候這種缺陷還不明顯,當深入開發的時候,這種缺陷就會爆發。

①修改點一:我們需要調整供用戶驗證身份的Form代碼,加入驗證碼的輸入框。

我們不得不修改兩個重覆且相同的代碼,這樣不僅會增加工作量,而且一個疏忽就會導致忘記修改其中一個,增加代碼維護的難度。

②修改點二:要改成Oracle資料庫,而且數據表名和欄位都變了。

我們不僅需要修改JDBC的代碼,而且還要修改Welcome xxx這部分的顯示代碼,也就是說,資料庫方面的修改會直接牽涉其他類型的業務代碼。

③修改點三:需要實現“三次驗證不過就要鎖用戶”功能。

我們需要在JDBC部分的代碼計數,如果登錄次數小於3,那麼就需要重覆性地複製Form的代碼。如果超過三次,則還需要在Java代碼里夾雜一個“提示鎖屏”的顯示頁面,這會導致JSP更加混亂。

不是危言聳聽,我們見過不少頁面數量小於10的小項目,開發人員為了省事,直接在JSP里放入所有的功能,就像前面給出的例子一樣,交貨兩三個月後,當完成用戶提出若幹改進意見後,這些個JSP代碼就變得像天書一樣,閱讀性很差。

在提面試問題的時候,如果發現候選人使用“大而全”的開發方式,我們會讓面試者說出理由,如果理由類似“項目緊,缺人手,權衡下來寧可犧牲代碼的質量”,那麼說明面試者至少和MVC開發模式比較過,可以接受。如果面試者直接不知道MVC的開發模式,甚至不知道“大而全”的缺點,那麼我們的評價至少是“沒架構意識”。

如何改進?分解業務,用分層的方式來分解不同類型的業務。

具體來說,在JSP頁面里,剝離與顯示無關的代碼,一個好的JSP頁面里,應該少見甚至不用<%%>包含起來的Java代碼。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 直接用dotnet命令來運行你的程式,(dotnet的啟動真的很快)。在你的項目文件夾下加一個批處理,如:Run.cmd ...
  • 錄音工具,推薦使用Win7操作系統自帶錄音機。 修改錄音機輸出開始→所有程式→附件→右擊錄音機→屬性,在目標欄路徑有添加 空格/file outputfile.wav。 使用錄音機錄製相關音頻XXX.wav 具體代碼如下 ...
  • 在常見的ORM框架中,大都提供了使用註解方式來實現entity與資料庫的映射,這裡簡單地使用自定義註解與反射來生成可執行的sql語句。 這是整體的目錄結構,本來是為複習註解建立的項目^.^ 好的,首先我們來確定思路。 1. 自定義@Table @Column註解, 我們稍微模仿hibernate,讓 ...
  • 我們伺服器內用leveldb存一些不是很重要的, 但是又需要(半)持久化的東西. 可是自從2016到現在, 碰見好幾次不同類型的死鎖. 直到今天, 才發現真正的原因, 那就是leveldb不支持fork. 所以在你使用leveldb的時候, 一定需要註意初始化順序: fork init leveld ...
  • virtualenv virtualenv用於創建獨立的Python環境,多個Python相互獨立,互不影響,它能夠:1. 在沒有許可權的情況下安裝新套件2. 不同應用可以使用不同的套件版本3. 套件升級不影響其他應用 安裝 使用方法 如,創建**ENV**的虛擬環境 預設情況下,虛擬環境會依賴系統環 ...
  • 使用 PoolingHttpClientConnectionManager 鏈接池管理類 ...
  • 以下函數列出某個目錄下(包括子目錄)所有文件,本隨筆重點不在於遞歸函數的實現,這是一個很簡單的遞歸,重點在於熟悉Python 庫os以及os.path一些函數的功能和用法 1. os.listdir(path):列出path下所有內容(包括文件和目錄,不包括.和..) 2. os.path.join ...
  • 最近在研究百度網盤的視頻解析,目的是找出網盤視頻的真實源地址。百度網盤對於超過1G的文件需要通過網盤客戶端下載,通過抓包研究,可下載源視頻有以下4個渠道: 一、https://pan.baidu.com/s/視頻地址 這是分享後的視頻地址 找到視頻源解析地址: 介面地址:https://pan.ba ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...