動態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>