一、有關Java Web與MVC設計模式
學習過基本Java Web開發的人都已經了解了如何編寫基本的Servlet,如何編寫jsp及如何更新瀏覽器中顯示的內容。但是我們之前自己編寫的應用一般存在無條理性,對於一個小型的網站這樣的編寫沒有任何問題,但是一但我們需要編寫大型的web工程的話,我們現有的編寫模式會造成web應用的可擴展性較差,而且一但出現問題不能准確的定位出問題出在哪里。
Java是一門應用設計模式比較廣泛的語言。目前主流提出的23種設計模式均可在Java語言編寫的程序中所應用。目前主流在Java Web應用中應用的最廣泛的設計模式便是MVC模式,目前的主流Web框架大多也是基於MVC設計模式所編寫的。
二、MVC在Java Web應用中的具體應用
所謂MVC,即Model-View-Controller。
(1)Model層:Model指模型部分,一般在應用中Model層包括業務處理層和數據訪問層。數據訪問層主要是對數據庫的一些操作的封裝。業務處理層應用JavaBean構建, JavaBean主要是用作將從View層獲取的數據和數據庫的數據進行橋接。除卻JavaBean以外,若想構建分布式應用系統,可以應用EJB組件進行業務邏輯層的構建。
(2)Controller層:Controller指控制部分,一般是對View層提交的請求為其設置對應的Servlet進行特定功能的處理,這里的進行特定功能的處理一般是編寫在Model中的業務處理層中的。Controller一般只是在Web應用中充當一個中介者的作用。
(3)View層:View指視圖部分,這一部分的內容是展示給用戶實際進行交互的,通常使用JSP和HTML進行構建(個人比較喜歡以HTML嵌入JSP的方式來構建網頁)。
綜上來說,一個小型完整的基於MVC設計模式的Web應用程序的處理流程應該如下:
由上面的圖中我們可以看出,用戶在客戶端(Web應用的客戶端即為瀏覽器)中發出請求的時候,請求首先由View層的JSP/HTML將HTTP請求傳給控制器中對應的Servlet,然后由Servlet負責調用Model層中的業務邏輯處理部分進行要求的處理,處理期間如果設計數據庫的操作,則與數據庫進行操作,最后全部操作結束之后,由業務邏輯層將結果發給控制層,控制層以HTTP響應的形式將結果發送回客戶端。
三、一個MVC設計模式的小例子
我們的這個例子是運用MVC技術和基本的Java Web技術進行一個用戶注冊和信息查詢的Web應用的制作。項目工程文件夾目錄如下:
1.View層的編寫
在這里我們模仿制作一個用戶進行的注冊界面,並在表單中指定接受請求並處理該頁面的Servlet。View層主要是由jsp、HTML編寫而成。
其中的一個jsp示例文件如下:
1 <%@ page language="java" import="java.util.*" contentType="text/html"; charset="utf-8" pageEncoding="utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>用戶注冊界面</title> 13 14 <meta http-equiv="pragma" content="no-cache"> 15 <meta http-equiv="cache-control" content="no-cache"> 16 <meta http-equiv="expires" content="0"> 17 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 18 <meta http-equiv="description" content="This is my page"> 19 <!-- 20 <link rel="stylesheet" type="text/css" href="styles.css"> 21 --> 22 23 </head> 24 <body style="text-align=:center"> 25 <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post"> 26 <table width="60%" border="1"> 27 <tr> 28 <td>用戶名</td> 29 <td> 30 31 <input type="text" name="userName"> 32 </td> 33 </tr> 34 <tr> 35 <td>密碼</td> 36 <td> 37 <input type="password" name="passWord"> 38 </td> 39 </tr> 40 41 <tr> 42 <td>你出生的城市是哪里</td> 43 <td> 44 <input type="text" name="answer"> 45 </td> 46 </tr> 47 <tr> 48 <td> 49 <input type="reset" value="清空"> 50 </td> 51 <td> 52 <input type="submit" value="注冊"> 53 </td> 54 </tr> 55 </table> 56 </form> 57 </body> 58 </html>
在jsp文件中我們指定了接受該頁面並進行處理的表單。表單在Web應用中是十分重要的,目前Web應用的前后端傳輸數據的時候多數都要用到表單。
2.Controller層的編寫
Controller層主要編寫接受View層請求的Servlet。示例Servlet如下:
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.gaodongyan.bean.UserBean; import com.gaodongyan.service.ResigerInfo; @WebServlet("/ResigerServlet") public class ResigerServlet extends HttpServlet { private static final long serialVersionUID = 1L; public ResigerServlet() { super(); } /*UserBean:userName,passWord,answer * 在doGet()方法中,我們利用HttpServletRequest類中封裝的方法進行對頁面元素的調用 */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { UserBean user = new UserBean(); user.set_userName(request.getParameter("userName")); user.set_passWord(request.getParameter("passWord")); user.set_answer(request.getParameter("answer")); String sql = "INSERT INTO USERINFO ([username],[password],[answer]) values (" + user.get_userName() + "," + user.get_passWord() + "," +user.get_answer() + ")"; ResigerInfo resigerInfo = new ResigerInfo(); resigerInfo.interToDb(sql); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
3.Model層的編寫
Model層在具體的編寫中包括dao層和bean層還有service層。
(1)bean層:bean層中編寫數據模型類。
示例Bean如下:
1 public class UserBean { 2 private String userName; 3 private String passWord; 4 private String answer; 5 public void set_userName(String userName) { 6 this.userName = userName; 7 } 8 public void set_passWord(String passWord) { 9 this.passWord = passWord; 10 } 11 public void set_answer(String answer) { 12 this.answer = answer; 13 } 14 public String get_userName() { 15 return userName; 16 } 17 public String get_passWord() { 18 return passWord; 19 } 20 public String get_answer() { 21 return answer; 22 } 23 }
(2)dao層負責與數據庫進行交互。
示例dao層如下:其中GetConnection類返回一個數據庫連接,UpdateDb類負責通過調用GetConnection來獲得一個連接對象,再進行具體的數據庫操作。
1 class GetConnection { 2 3 private String url; 4 private String userName; 5 private String password; 6 Connection conn ; 7 public Connection getConnection() { 8 try { 9 Class.forName("com.mysql.jdbc.Driver"); 10 }catch(ClassNotFoundException e) { 11 12 } 13 try { 14 conn = DriverManager.getConnection(url, userName, password); 15 } catch (SQLException e) { 16 // TODO Auto-generated catch block 17 e.printStackTrace(); 18 } 19 return conn; 20 21 } 22 }
注:在此處略去了數據庫連接所需要的url、username、password。在具體操作的時候則需要指定這三項。
1 public class UpdateDb { 2 Connection conn; 3 Statement stmt; 4 ResultSet result; 5 public void doUpdate(String sql) { 6 GetConnection getedConnection = new GetConnection(); 7 conn = getedConnection.getConnection(); 8 try { 9 stmt = conn.createStatement(); 10 stmt.executeQuery(sql); 11 12 } catch (SQLException e) { 13 e.printStackTrace(); 14 } 15 16 } 17 }
(3)service層:service層負責編寫具體的業務邏輯,由於我們的示例中的業務邏輯比較簡單,故此處編寫的代碼較少。對於大型項目來說,業務邏輯層一般需要進行很多的業務處理。
示例如下:
1 public class ResigerInfo { 2 //We can set a unique sql in this place. 3 public void interToDb(String sql) { 4 UpdateDb updateDb = new UpdateDb(); 5 updateDb.doUpdate(sql); 6 } 7 }
4.Demo總結
博文中貼出的代碼是用戶注冊時需要的步驟。由於多個類和層間存在調用關系,所以大家在看貼出的源碼時可能會有理解的問題。所有類都已經在最開始的項目結構圖中體現了,相信對比着項目結構圖大家都會很容易明白MVC設計模式的基本調用歷程。
四、總結
由於時間倉促,導致示例Demo沒有全部完成,待這幾天完成后會上傳到github並共享。相信有了這篇博文,大家應該對MVC設計模式在Java Web中的基本應用有了簡單的了解。后期博主還會對目前主流的Java Web框架進行介紹。本博客純屬個人學習總結,如有不足請各位批評指正。