從IO 到框架(4)-Servlet + JDBC (Idea Maven)

動態Web 應用的基礎代碼。

關於IDE:最開始入門用Eclipse,但一用Idea 就立刻棄了Eclipse。Idea 相比來說更加智能,除了佔內存多點以外,用Idea 體驗超好,遠超Eclipse。

關於Maven:學Maven 之前做項目都需要導Jar 包,比較麻煩而且可能有包版本衝突。有Maven 之後就爽多了!回不去了!它不僅用幾行代碼配置代替了導包的步驟,還會自動地導入很可能會用到的關聯包,可節省不少時間。

1)上篇博文寫的是靜態頁面,以下兩圖展示的是動態頁面相關技術和基本流程。




2)Web Server - Tomcat: 是由 Apache 組織開發的一個 Servlet/JSP 容器(也就是負責解析和運行JSP),由純 Java 開發完成的,若系統的負荷壓力不是太大的話也可以兼作 Web 服務器(輕量級)。

Servlet 的Java 的、用來實現動態頁面的 規範,由應用服務器(如Tomcat) 中的容器(Container) 來控制。

Tomcat 只支持J2EE 中的JSP以及Servlet規範,有的服務器支持更多規範,如WebLogic 和WebSphere 都支持J2EE 13種規範(EJB )。

當訪問Tomcat 服務器的某個靜態資源時,實際上在訪問Tomcat 配置的缺省Servlet,url-pattern 爲"/";

Tomcat 訪問順序:先找servlet, 沒有的話執行缺省servlet 找靜態資源,還沒有的話返回404 等錯誤頁面

(預告:Struts2 框架就是一個大大的Servlet,會<load-on-startup>,提前初始化,1的優先級最高。)

訪問tomcat出現java.lang.IllegalStateException No output folder錯誤解決方法
問題:tomcat分爲安裝版和解壓縮版,解壓縮版如果解壓到安裝盤,在瀏覽器中訪問http://localhost:8080,可能會出現500錯誤,錯誤提示如下: 
localhost:8080 java.lang.IllegalStateException: No output folder 
原因如下:tomcat目錄沒有被讀寫的權限,導致文件不能被編譯到指定的工作目錄中。 
解決辦法: 

找到tomcat目錄,右鍵“屬性--->安全--->編輯”,找到Users,將“完全控制”選項“允許”打鉤,應用。


配置Tomcat (第5步項目創建後):菜單Run - Edit configurations - 左側欄Defaults - Tomcat Server - Local, 設置Application Server 和Open browser,Apply,如下圖;然後不用關此對話框,點左上角加號,添加Tomcat Server - Local - 設置Deployment,OK。




3)Servlet (Server Applet) 是Java Servlet的簡稱,稱爲小服務程序或服務連接器,用Java編寫的服務器端程序,主要功能在於交互式地瀏覽和修改數據,生成動態Web內容。狹義的Servlet是指Java語言實現的一個接口,廣義的Servlet是指任何實現了這個Servlet接口的類。Servlet運行於支持Java的應用服務器中。從原理上講,Servlet可以響應任何類型的請求,但絕大多數情況下Servlet只用來擴展基於HTTP協議的Web服務器。

4)開始用Idea 創建Maven 項目:File - New - Project... - Maven - Create from archetype (勾選上) - webapp - Next。如下圖(第3步還有一個webapp 可選::org.apache.maven.archetypes:maven-archetype-webapp,這個模板更簡單,需要新建java 和resources 文件夾;2.3版的web.xml 裏很乾淨但2.4版之前是不支持EL表達式的,要換高版本或在jsp 頁面加上"<%@page isELIgnored="false" %>";pom自帶了junit dependency 依賴):


5)填寫GroupId 和 ArtifactId,一路Next(其間可修改項目名稱等),直到Finish,需等待Idea Run "Import change",完成後佈局如下圖(沒有java 文件夾的話,新建一個,然後在其上右鍵 - Mark Directory As - Sources Root);

點擊"Enable Auto-Import",這樣每次修改Maven 的配置文件pom.xml,如添加依賴等,就會自動執行導入。

自動生成的web.xml 是2.4 版本,而且裏面有些至少暫時用不到的servlet, listen 等配置,需要刪掉。此模板應該可以修改的,尚未深究。



6)在pom.xml <plugins> 節點內添加以下插件代碼,新建的選項就會出現Servlet、Filter、Listener 這三個。如果沒有的話刪除這段代碼再貼上即可。添加servlet, mysql-connector, jstl 等依賴。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <source>1.7</source>
    <target>1.7</target>
  </configuration>
</plugin>


<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
</dependency>

另外Idea 不自動編譯發佈java 文件夾內的資源文件,在pom 配置中的build 標籤內添加以下代碼填上此坑

<resources>
  <resource>
    <directory>src/main/java</directory>
    <includes>
      <include>**/*.xml</include>
    </includes>
  </resource>
</resources>

7)創建前端頁面;新建Servlet 實現類,Idea 會自動在web.xml 生成servlet 節點,但servlet-mapping(映射) 需要手動寫上。

此Servlet 類繼承了HttpServlet,重寫父類的doGet() 和doPost() 方法(或Service() 方法),即可處理來自頁面的Get 或Post 請求。注意它是沒有主函數的,由Tomcat 內的容器調用纔可運行。

<servlet>
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>cn.rock.framework.controller.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/UserServlet</url-pattern>
</servlet-mapping>

8)Servlet 的執行過程

  • Form 表單的action, a 標籤的href 等可直接指向servlet 映射地址(即URL;也可指向靜態頁面資源),可用問號傳參數,Form 表單input 標籤內的name - value 參數一起打包提交;
  • Tomcat Connector監聽到瀏覽器發來的請求,解析出請求指向某個Servlet,然後把該請求交給它所在的Service的Container (Engine),Container 就會創建兩個對象:1) HttpServletResponse 2) HttpServletRequest (存儲頁面提交過來的URL和參數);
  • Container 根據request 傳來的URL 找到正確匹配的servlet,爲此request 創建或指定一個servlet 線程,並將request 和response 對象作爲參數傳給此servlet 線程;
  • Container 調用此servlet 的servcie() 方法,service() 方法根據請求類型調用 doGet() 或 doPost() 方法;
  • doGet() 或doPost() 可通過request.getParameter("name") 獲取傳來的參數,根據參數可分發請求、處理參數,與數據庫交互,若有需要傳給頁面的信息,可用request.setAttribute("name", "value") 存到request. 
  • request 轉發(多數情況下)或重定向到jsp 頁面,jsp頁面可用jstl 和EL 表達式展示動態數據。
  • jsp 頁面被存在response 對象,servlet 線程結束,Container 將response 對象轉換爲一個Http Response,發送給瀏覽器,並刪除request 和response 對象。

9)創建數據庫連接:



10)接第8條第5點,servlet 與數據庫交互的具體過程:

  • doGet() 或doPost() 方法調用Service接口(其實現類爲ServiceImpl),ServiceImpl 調用Dao接口(其實現類爲DaoImpl);
  • JDBC(Java DataBase Connectivity):Java 操作數據庫的技術,是一套接口標準,很好實現了面向接口編程,多態應用;
    面向接口是面向對象的衍生。類似:電腦的USB 接口。
    編程最重要的是可讀性、可維護性、擴展性好,而不是功能。
    底層思想基本都是封裝、繼承、多態。
  • DaoImpl 直接與數據庫交互:
                String username = "root";
		String password = "root";
		String url = "jdbc:mysql://localhost:3306/mydb";//協議 ip 端口 數據庫
		String driver = "com.mysql.jdbc.Driver";//驅動
		
		//1、加載數據庫驅動 - 程序只要加載一次
		Class.forName(driver);
		
		//2、獲取數據庫的連接
		Connection conn = DriverManager.getConnection(url, username, password);
		
		//3、執行sql語句
		//準備一條sql語句
		String sql = "insert into student value(null, '小明', 20, 0, '1998-07-14', '計算機系', '北京市朝陽區')";
		//通過connection獲得Statement對象
		Statement statment = conn.createStatement();
		//statement對象傳輸sql語句
		//如果是增刪改  executeUpdate 返回值表示本次sql語句影響的行數
		//如果是查 executeQuery
		int result = statment.executeUpdate(sql);
		
		System.out.println("sql語句執行的結果:" + result);
		
		//4、關閉連接
		statment.close();
		conn.close();

11)至此,最基本的項目流程都過了一遍,之後就是在此基礎上不斷迭代升級。

12)升級1:提取數據庫配置文件,在方法內處理異常、關閉資源,預處理sql 以避免sql 注入問題,提取數據庫連接工具類

        配置文件(.properties .xml)作用:不需要編譯,可由維護人員直接在項目運行時修改;只修改配置文件的內容就能全部修改爲想要的數據。最主要的是不用修改代碼,所以工作中配置文件往往比java代碼還要多。

升級2:在ServiceImpl 層引入事務(即多條sql 作爲一個邏輯單元,要麼一起執行,要麼都不執行),以滿足現實需求。

升級3:使用 c3p0數據庫連接池,更高效使用數據庫連接。還有dbcp與druid 可選。

升級4:使用過濾器Filter,可過濾頁面、統一編碼等。(監聽器Listener 目前作用不大)

升級5:JavaScript 的Ajax 局部刷新技術,通過Ajax Engine 獲取xml 數據, 現在多用json;使用JQuery 比原生JS 要高效得多。

<script type="text/javascript" src="js/jquery-1.8.3.js"></script>
    <script>
        $(function () {
            $("input").blur(function () {
                var value = $(this).val();
                if ($.trim(value) == "") {
                    alert("Username can't be void");
                    return;
                }

                /*$.get("RegisterServlet", {"username": value}, function (data) {
                    if (data == 0) {
                        $("input").next().html("Yes");
                    } else {
                        $("input").next().html("No");
                    }
                });*/

                $.ajax({
                    url: "RegisterServlet",
                    data: {username: value},
                    success: function (data) {
                        if (data == 0) {
                            $("input").next().html("Yes");
                        } else {
                            $("input").next().html("No");
                        }
                    }
                })
            });

            //ajax to submit form
            $("button").click(function () {
                $.ajax({
                    type: "post",
                    url: $("form").attr("action"),
                    data: $("form").serialize(),
                    success: function () {

                    }
                });
            });
        });
        
    </script>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章