第一部分
介紹及配置
J2EE說白了其實就是一些規範的集合,其中包括JDBC、Servlet、JSP、EJBs、JavaMail、XML等。這裏主要介紹一下JDBC-Servlet-JSP這三項技術,它們主要用於開發一些WEB應用。
1.JDBC是一組Java連接數據庫的標準API,使用它們能夠簡單方便地實現純Java的數據庫訪問操作。
一個普通數據庫的連接過程爲:
1.加載驅動程序
2.通過DriverManager到得一個與數據庫連接的句柄
3.通過連接句柄綁定要執行的語句
4.接收執行結果
5.對結果進行必要的處理以提取自己想要的數據
6.關閉數據庫的連接
無論實現本地數據庫開發或者Web數據庫開發,JDBC連接數據庫的基本步驟都和上面的過程類似。
2.Servlet是一個專門用於編寫網絡服務器應用程序的Java組件。所有基於Java服務器編程都是基於Servlet的。如後面要介紹的JSP最後是也要通過JSP引擎轉換爲Servlet的。Servlet適用於多種網絡協議,如Http、Ftp、Smtp等等。目前只有Http服務形成了標準組件,也就是我們要用到的javax.servlet.http這個包。作爲一種服務器端的應用,當被請求時開始執行,這和CGI Perl腳本很相似。Servlets和CGI腳本的一個很大的區別是:每一個CGI在開始的時候都要求開始一個新的進程,而servlets是在servlet引擎中以分離的線程來運行的。
3.JSP則相對於ASP是用來開發動態網頁的,JSP頁面由HTML代碼和嵌入其中的Java代碼所組成。服務器在頁面被客戶端所請求以後對這些Java代碼進行處理,然後將生成的HTML頁面返回給客戶端的瀏覽器。一般爲了使網站更易於開發和維護,都採用簡單的JSP頁面+JavaBean。
JSP一般的運行方式爲:當服務器啓動後,當Web瀏覽器端發送過來一個頁面請求時,Web服務器先判斷是否是JSP頁面請求。如果該頁面只是一般的HTML/XML頁面請求,則直接將HTML/XML頁面代碼傳給Web瀏覽器端。如果請求的頁面是JSP頁面,則由JSP引擎檢查該JSP頁面,如果該頁面是第一次被請求、或不是第一次被請求但已被修改,則JSP引擎將此JSP頁面代碼轉換成Servlet代碼,然後JSP引擎調用服務器端的Java編譯器javac.exe對Servlet代碼進行編譯,把它變成字節碼(.class)文件,然後再調用JAVA虛擬機執行該字節碼文件,然後將執行結果傳給Web瀏覽器端。如果該JSP頁面不是第一次被請求,且沒有被修改過,則直接由JSP引擎調用JAVA虛擬機執行已編譯過的字節碼.class文件,然後將結果傳送Web瀏覽器端。
一般JSP開發Web應用的主要框架如下:
Web應用(如網站等)
JSP引擎
Web服務器
操作系統
由於JSP是基於Java的一個J2EE協議,所以也能夠write one,run everywhere。所以底層的操作系統既可以使用Windows,也可以使用Unix、Solaris。Web服務器目前比較流行的有WebLogic、WebSphere、JBoss等,還有一些是免費的如Tomcat、Resin等。至於JSP引擎,一般的Web服務器都自帶,如Tomcat,引擎主要是將JSP的代碼轉換位Servlet代碼的。
一般學習使用這三項技術實現Web應用可以先採用較爲簡單易用的服務器,如Tomcat,然後再逐步深入使用其它一些複雜的商業性服務器。本篇主要使用Tomcat來展開學習。至於數據庫則採用Mysql,原因主要是它開源免費而且好用,Yahoo的數據庫用的好像也是它。
開發Web應用的第一步就是進行開發環境的搭建,對於入門來說這真的是一件讓人很頭疼的事,不知以後會不會出現那種自動幫助我們配置的工具。
我們選擇的開發環境是Eclipse+Tomcat+Mysql,下面介紹配置步驟:
1.下載Eclipse(綠色軟件免安裝,Java的開發環境)
2.下載jdk1.5.0_01並安裝,啓動Eclipse,選擇 Window > Preferences > Java,選擇或者新添jre地址,ok,現在試着建一個project,寫寫HelloWorld看是否配置成功。
3.下載Tomcat安裝、下載Eclipse的Tomcat插件tomcatPluginV3.zip將其解壓到Eclipse的plugins目錄下,啓動Eclipse,選擇 Window > Preferences > Tomcat,選擇對應的Tomcat,並填入Tomcat的安裝路徑。
4.下載Lomboz和EMF runtime並將它們解壓放到plugins目錄下,啓動Eclipse,選擇Window > Preferences >Lomboz,對Lomboz進行配置包括jre和Tomcat,注意須在Library中加入Tomcat的common的lib目錄下的一些jar文件,ok,現在來試試看Tomcat是否配置成功,
41.建一個Lomboz J2EE project,填入name爲TestJsp;
42.下一步,再下一步;
43.添加WebModules的name爲test,Targeted Servers選擇Tomcat,注意選擇已安裝的Tomcat版本,ok完成;
44.找到Lomboz J2EE View,這裏頭有剛纔建的test的WebModules,單擊右鍵對這個Modules進行deploy(這一步粉重要)後再Start Tomcat;
45.在左邊的workspace裏找到剛建的test目錄,單擊右鍵選擇Lomboz J2EE>Show in Browser,如果出現Welcome的網頁就表示配置ok了。
5.下載Mysql安裝、下載Java-Mysql的connector並取其中的xxxbin.jar將其複製到Tomcat的common的lib目錄下。
建一個本地數據庫訪問程序:
51.在Mysql中建一個數據庫,添加表,插入數據。
52.建一個Java project,在Library中添加Add Extended Library中添入Mysql的Connector。
53.根據數據庫的編寫步驟,寫一個訪問數據庫的程序。先寫一個訪問本地數據庫的程序調試一下是否配置成功,再寫Web的,Web數據庫的操作與本地數據庫類似,只不過是在JSP頁面或JavaBean中實現的。
第二部分
深入協議
1.JDBC
簡要介紹
1)Class.forName
Class.forName("xxxxxxxxxxxxxxxxxxxxxxx"); 用於加載驅動程序
2)DriverManager
DriverManager類是 JDBC 的管理層,作用於用戶和驅動程序之間。通常通過DriverManager.getConnection建立與數據庫的連接。
3)statement(Statement、PreparedStatement、CallableStatement)
Statement 對象用於將 SQL 語句發送到數據庫中。實際上有三種 Statement 對象,它們都作爲在給定連接上執行 SQL 語句的包容器:Statement、PreparedStatement(它從 Statement 繼承而來)和 CallableStatement(它從 PreparedStatement 繼承而來)。它們都專用於發送特定類型的 SQL 語句: Statement 對象用於執行不帶參數的簡單 SQL 語句;PreparedStatement 對象用於執行帶或不帶 IN 參數的預編譯 SQL 語句;CallableStatement 對象用於執行對數據庫已存儲過程的調用。
Statement 接口提供了執行語句和獲取結果的基本方法。PreparedStatement 接口添加了處理 IN 參數的方法;而 CallableStatement 添加了處理 OUT 參數的方法。
Statement 接口提供了三種執行 SQL 語句的方法:executeQuery、executeUpdate 和 execute。使用哪一個方法由 SQL 語句所產生的內容決定。
方法 executeQuery 用於產生單個結果集的語句,例如 SELECT 語句。
方法 executeUpdate 用於執行 INSERT、UPDATE 或 DELETE 語句以及 SQL DDL(數據定義語言)語句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE 語句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一個整數,指示受影響的行數(即更新計數)。對於 CREATE TABLE 或 DROP TABLE 等不操作行的語句,executeUpdate 的返回值總爲零。
方法 execute 用於執行返回多個結果集、多個更新計數或二者組合的語句。
4)ResultSet
結果集一般是一個表,其中有查詢所返回的列標題及相應的值。它包含符合 SQL 語句中條件的所有行。
ResultSet.next 方法用於移動到 ResultSet 中的下一行,使下一行成爲當前行。
方法 getXXX 提供了獲取當前行中某列值的途徑。
要確定給定結果值是否是 JDBC NULL,必須先讀取該列,然後使用 ResultSet.wasNull 方法檢查該次讀取是否返回 JDBC NULL。
實現及示例
再簡述一遍連接數據庫過程 :
1.加載驅動程序
2.通過DriverManager到得一個與數據庫連接的句柄
3.通過連接句柄綁定要執行的語句
4.接收執行結果
5.對結果進行必要的處理以提取自己想要的數據
6.關閉數據庫的連接
下面是連接mysql的實例,可以對照看一下
import java.sql.*;
public class ConMySQL {
public static void main(String arg[]) {
String dbName = "test";
String Login = "root";
String Password = "pluto";
String ConnStr = "jdbc:MySQL://localhost/" + dbName + "?user=" + Login
+ "&password=" + Password;
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(ConnStr);
Statement stmt = conn.createStatement();
ResultSet results = stmt.executeQuery("select * from stuinfo");
while (results.next()) {
String name = results.getString("name");
String sex = results.getString("sex");
System.out.println(name + " " + sex);
}
conn.close();
} catch (Exception exc) {
exc.printStackTrace();
}
}
}
對於插入的操作,一般使用PreparedStatement,請看下面實例
PreparedStatement stm;
stm=con.prepareStatement("insert into Indent(IndentID,UserName,TPrice)values(?,?,?);");
stm.setInt(1, id);
String user = (String)session.getAttribute("username");
stm.setString(2, user);
stm.setInt(3, 100);
stm.executeUpdate();
2.Servlet
要理解Servlet可以先將Servlet和Applet、CGI、JSP等進行比較。
Servlet主要包括兩個包:
1)javax.servlet
interface RequestDispatcher
//定義一種對象,用於從客戶接受請求,並將請求發送到服務器上任何指定的資源,如一個Servlet 、JSP 或 HTML 文件。
interface Servlet
//定義了所有 Servlet 必須實現的方法。
interface ServletConfig
//定義Servlet config 對象,由Servlet 引擎用在 Servlet 初始化時,向 Servlet 傳遞信息。
interface ServletContext
//定義了一系列方法,以便Servlet與其運行的環境通信。
interface ServletRequest
//定義了用於向Servlet傳遞客戶請求信息的對象。
interface ServletResponse
//定義了一個對象,由Servlet用於向客戶發送響應。
interface SingleThreadModel
//用於保證Servlet在任一時刻,只處理一個請求。
class GenericServlet
//繼承Servlet接口,定義了一個通用的,與協議無關的Servlet。
class ServletInputStream
//定義了一個輸入流,用於由Servlet從中讀取客戶請求的二進制數據。
class ServletOutputStream
//定義了一個輸出流,用於由Servlet向客戶發送二進制數據。
class ServletException
//定義了一個當Servlet遇到問題時可以拋出的異常。
class UnavailableException
//定義了一種異常,用於由Servlet指明它永遠或暫時不可用。
其中一個最重要的類是GenericServlet,它繼承Servlet接口,定義了一個通用的,與協議無關的Servlet,通過它繼承它,可以進行一些處理客戶請求的操作。
一個Servlet的工作過程包括(與Applet類似):
1.創建並初始化(init())
2.處理客戶端的請求(service(ServletRequest req,ServletResponse res))
3.刪除Servlet,回收資源,終止Servlet運行(destroy())
示例:
import java.io.*;
import java.util.*;
import javax.servlet.*;
public class TestGenericServlet extends GenericServlet {
public void init(ServletConfig config)throws ServletException {
super.init(config);
//調用父類的初始化方法;也可以加入自己需要的初始化代碼。
}
public void destroy() {
//destroy方法中加入一些做最後清理工作的代碼;
}
public String getServletInfo() {
return "This servlet is a simple Servlet's example.";
//返回此servlet的信息 ;
}
public void service(ServletRequest req,ServletResponse res)
throws ServletException,IOException {
//service是最主要的方法,提供服務
//獲得服務器當前時間。
Date today=new Date();
ServletOutputStream out=res.getOutputStream();
//通過輸出流向客戶端寫回了一個HTML文件;
out.println("<html><head><title>HelloServlet.java</title></head><body>");
out.println("Hello,this is my first test.+<BR>");
out.println("Today is "+today.toString()+"<BR>");
out.println(getServletInfo()+"<BR>");
}
}
2)javax.servlet.http
interface HttpServletRequest
//繼承了ServletRequest 接口,爲HTTPServlet 提供請求信息。
interface HttpServletResponse
//繼承了ServletResponse 接口,爲HTTPServlet 輸出響應信息提供支持。
interface HttpSession
//爲維護 HTTP 用戶的會話狀態提供支持。
interface HttpSessionBindingListener
//使得某對象在加入一個會話或從會話中刪除時能夠得到通知。
interface HttpSessionContext
//由Servlet 2.1 定義,該對象在新版本已不被支持。
class Cookie
//用在Servlet 中使用Cookie 技術
class HttpServlet
//定義了一個抽象類,繼承 GenericServlet 抽象類,應被 HTTPServlet 繼承。
class HttpSessionBindingEvent
//定義了一種對象,當某一個實現了HttpSessionBindingListener接口的對象被加入會話或從會//話中刪除時,會收到該類對象的一個句柄
class HttpUtils
//提供了一系列便於編寫HTTPServlet 的方法。
其中一個最重要的類是HttpServlet,它從GenericServlet 繼承而來,因此它具有GenericServlet 類似的方法和對象,一般的Servlet編程都用這個類,而少用GenericServlet類。
HttpServlet類中包括幾個常用的方法(幾乎對應於Http1.1)
如:doGet();doPost();doDelete();doPut();doOptions();doTrace()等。
雖然HttpServlet在響應客戶請求時沒有顯示的調用service而只是調用doGet等方法,但是Servlet內部還是會進行轉化的,service與doGet等方法是一致的。Service是處理客戶請求的核心。
示例:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class TestHttpServlet extends HttpServlet {
public void doGet(HttpServletRequest req,HttpServletResponse res)
throws ServletException,IOException {
res.setContentType("text/html");
ServletOutputStream out=res.getOutputStream();
out.println("<html>");
out.println("<head><title>testHttpServlet.java</title></head>");
out.println("<body>");
out.println("<h3>Hello,this is a HttpServlet's test!</h3>");
out.println("</body></html>");
}
}
3.JSP
JSP的語法
1)HTML註釋
語法:<!-- comment [ <%= expression %> ] -->
2)隱藏註釋
語法:<%-- comment --%>
3)聲明
語法:<%! declaration; [ declaration; ]+ ... %>
4)表達式
語法:<%= expression %>
5)程序段
語法:<% code fragment %>
6)Include 指令
語法:<%@ include file="relativeURL" %>
7)Page 指令
語法:
<%@ page
[ language="java" ]
聲明腳本語言的種類,暫時只能用"java"
[ extends="package.class" ]
標明JSP編譯時需要加入的Java Class的全名,但是得慎重的使用它,它會限制JSP的編譯能力.
[ import="{package.class | package.*}, ..." ]
需要導入的Java包的列表,這些包就作用於程序段,表達式,以及聲明。
[ session="true | false" ]
設定客戶是否需要HTTP Session.(學過ASP的人,應該對它不陌生)如果它爲true,那麼Session是有用的。
[ buffer="none | 8kb | sizekb" ]
buffer的大小被out對象用於處理執行後的JSP對客戶瀏覽器的輸出。缺省值是8kb
[ autoFlush="true | false" ]
設置如果buffer溢出,是否需要強制輸出,如果其值被定義爲true(缺省值),輸出正常,如果它被設置爲false,如果這個buffer溢出,就會導致一個意外錯誤的發生.如果你把buffer設置爲none,那麼你就不能把autoFlush設置爲false.
[ isThreadSafe="true | false" ]
設置Jsp文件是否能多線程使用。缺省值是true,也就是說,JSP能夠同時處理多個用戶的請求,如果設置爲false,一個jsp只能一次處理一個請求
[ info="text" ]
一個文本在執行JSP將會被逐字加入JSP中,你能夠使用Servlet.getServletInfo方法取回。
[ errorPage="relativeURL" ]
設置處理異常事件的JSP文件。
[contentType="mimeType[;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ]
設置MIME類型 。缺省MIME 類型是: text/html, 缺省字符集爲 ISO-8859-1.
[ isErrorPage="true | false" ]
設置此頁是否爲出錯頁,如果被設置爲true,你就能使用exception對象.
%>
8)<jsp:forward>
語法:
用法⒈<jsp:forward page={"relativeURL" | "<%= expression %>"} />
用法⒉<jsp:forward page={"relativeURL" | "<%= expression %>"} >
<jsp:param name="parameterName"
value="{parameterValue | <%= expression %>}" />+
</jsp:forward>
<jsp:forward>常用頁面跳轉,並可在頁面之間傳遞參數。
9)<jsp:include>
語法:
1.jsp:include page="{relativeURL | <%= expression%>}" flush="true" />
2. <jsp:include page="{relativeURL | <%= expression %>}" flush="true" >
<jsp:param name="parameterName" value="{parameterValue|<%=expression%>}"/>
</jsp:include>
<jsp:include>元素允許你包含動態文件和靜態,這兩種包含文件的結果是不同的。如果文件僅是靜態文件,那麼這種包含僅僅是把包含文件的內容加到jsp文件中去,而如果這個文件動態的,那麼這個被包含文件也會被Jsp編譯器執行。如果這個包含文件是動態的,那麼你還可以用<jsp:param>還傳遞參數名和參數值。
10)<jsp:plugin>
<jsp:plugin>元素用於在瀏覽器中播放或顯示一個對象(典型的就是applet和Bean),而這種顯示需要在瀏覽器的java插件。
11)<jsp:useBean>
語法:
<jsp:useBean
id="beanInstanceName"
scope="page | request | session | application"
{
class="package.class" |
type="package.class" |
class="package.class" type="package.class" |
beanName="{package.class | <%= expression %>}" type="package.class"
}
{
/> |
> other elements </jsp:useBean>
<jsp:useBean>用於定位或示例一個JavaBeans組件。<jsp:useBean>首先會試圖定位一個Bean實例,如果這個Bean不存在,那麼<jsp:useBean>就會從一個class或模版中進行示例。
12)<jsp:setProperty>
與<jsp:useBean>元素連用,用於設置Bean的屬性值。
13)<jsp:getProperty>
語法:
<jsp:getProperty name="beanInstanceName" property="propertyName" />
這個<jsp:getProperty>元素將獲得Bean的屬性值,並可以將其使用或顯示在JSP頁面中.在你使用<jsp:getProperty>之前,必須用<jsp:useBean>創建它。name="beanInstanceName" ,bean的名字,由<jsp:useBean>指定;property="propertyName" ,所指定的Bean的屬性名。
14)在設計JSP網頁時還有幾點是常用的:
(1)連接數據庫
連接數據庫可以直接嵌入JSP頁面中,也可以做成Bean方式,再通過useBean在頁面中使用,個人感覺後者結構比較清晰,推薦後者。
(2)登陸驗證
主要是先獲得用戶填入的username和password,再將它們和數據庫中的信息表相比較如果符合,則通過session來設置用戶的訪問權限,否則轉至error頁面。在用戶訪問其它頁面時也都要先判斷用戶的session來驗證用戶是否有權訪問該頁面。
(3)頁面跳轉
主要是通過forword來實現頁面之間的跳轉並通過param傳遞參數值。也可通過網頁中的herf來實現跳轉。