復習提綱
一 Servlet及web服務器相關概念(了解)
tomcat配置(能熟練操作)
二 Servlet基礎(重點,必須熟記于心)
a.Servlet的調用過程
b.Servlet接口
c.servlet的生命周期
d.MVC框架
e.Servlet的控制流轉
f.Servlet的url-pattern
三 Session(會話)和Cookie(熟記于心)
四 Servlet過濾器和監聽器(熟練使用)
五數據庫連接池(了解)
一、Servlet及web服務器相關概念
Servlet,服務器端的小程序,它是相對于Applet而言的,Applet是客戶端小程序。
Servlet,能接受來自網絡的請求(form表單,以及其他的請求),并對不同請求作出不同的響應
servlet是運行在web容器中, web容器可以控制Servlet對象的生命周期,控制請求由Servlet對象處理。
web服務器,這里的服務器不是硬件概念,而是軟件,常用的web服務器有 Tomcat,Jboss等,我們所用到的Tomcat是一個開源的服務器,Tomcat是一個用java語言編寫的web服務器,所以需要有相應的java運行環境,也就是JVM,還要配置tomcat的具體路徑。
Tomcat的配置
JAVA_HOME=/XXX/XXX/(JDK路徑,bin的上一層目錄)
CATALINA_HOME=/XXXX/XXX
(tomcat的絕對路徑 windows中 X:\xxx\xxx linux /home/tarena/tomcat5)
Tomcat啟動:$ CATALINA_HOME/bin/startup.sh 或 startup.bat
Tomcat關閉:$ CATALINA_HOME/bin/shutdown.sh 或 shutdown.bat
Tomcat測試啟動是否成功:http://localhost:8080/或http://127.0.0.1:8080/可以訪問到tomcat的主頁就是啟動成功了。(這里建議使用127.0.0.1)
tomcat可以識別的資源只有在webapps文件夾下,webapps也就是web應用文件夾,webapps下的文件夾這些文件夾中存放的就是web應用,web應用是有格式規范的:
XXX應用
|- *.jsp *.html *.js *.css *.jpg
|- WEB-INF (受保護資源)
|- classes *.class
|- lib *.jar
|- web.xml
在tomcat服務器中,訪問應用下的資源可以在端口號后加上web應用文件夾的名字就可以看到資源
http://localhost:8080/xxx應用/xxxx.html,靜態頁面只能放在web應用的文件夾下,不能夠放在WEB-INF文件夾下,WEB-INF文件夾中的資源是受保護的,不能夠通過網絡訪問到。
Servlet基礎
Servlet,可以實現動態的輸出頁面,可以針對不同的請求作出不同的響應,可以實現頁面的跳轉,Servlet可以充當MVC模式中的控制層,而且servlet的優點也在于此。
web服務器會在web應用/WEB-INF/classes文件夾搜索要加載的class文件,所以我們寫的class文件要放在web應用/WEB-IN/classes文件夾下。
設置servlet的類和訪問的方式
web.xml文件的配置,一個web.xml中可以配置多個Servlet
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>servlet的名字</servlet-name>
<servlet-class>servlet包名類名</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet的名字(要和servlet標簽中的相同)</servlet-name>
<url-pattern>指定servlet相對于應用目錄的路徑</url-pattern>
</servlet-mapping>
</web-app>
catalina.sh run 帶控制臺啟動tomcat服務器。
a.Servlet的調用過程
1,用戶通過瀏覽器向web服務器發送請求
http://serverip:port/apppath
2,服務器為用戶定位資源
靜態資源:/a.html /a/b.html (這里的路徑是針對web應用文件夾目錄)讀文件并把內容發送到客戶端
動態資源:解析web.xml定位Servlet類的名字
裝載類(WEB-INF/classes|WEB-INF/lib/*.jar)
創建該對象的實例
Servlet ser=(Servlet)(Class.forName("servle的類名")).newInstance();
//我們寫的Servlet一定要實現Servlet接口或者繼承實現了Servlet接口的類
ser.service(request,response);
<servlet-mapping>
<servlet-name>servlet的名字(要和servlet標簽中的相同)</servlet-name>
<url-pattern>指定servlet相對于應用目錄的路徑</url-pattern>
</servlet-mapping>
url-parttern的配置,這個url就是Servlet的虛擬路徑,可以使用相對路徑或者是絕對路徑。
/xxx/xxx(絕對路徑) ,xxx(相對路徑),盡量使用絕對路徑。
訪問servlet的方法
http://serverip:port/應用文件夾名/url-pattern
http的請求
get請求,post請求。
get請求在發出請求時會把參數寫在地址欄上,而post請求不會把要發送的參數顯示在地址欄上。
<form method="get" action="/應用名/url-pattern">
......
</form>
b.Servlet接口
servlet接口的實現類中的service()方法,在繼承HttpServlet類時,如果沒有覆蓋父類的service()方法,那么父類的service()方法會根據請求類型不同的會分別調用覆蓋的doGet(),doPost()方法,如果響應兩種請求的動作相同,那么可以直接覆蓋service()方法。如果覆蓋了
doGet(),doPost()方法之一,那么就會只對一種請求作出響應。在瀏覽器的地址欄操作按回車鍵,或者是熱連接,都是get請求,form的method屬性如果不指定,默認為get請求。
我們可以通過ServletRequest對象或HttpServletRequest對象的方法來獲取請求中傳送的參數。
getParameter(String name)方法,可以獲得form表單中指定名字的參數,多參數同名時,只取一個。
getParameterNames(),可以獲得一個迭代器Enumeration,通過這個迭代器,來獲得form表單中參數的名字。
getParameterValues(String name)獲得指定的所有同名參數的值。
get請求,會將參數顯示在瀏覽器的地址欄上,其顯示格式,在地址之后會以問號開始,以'&'分隔參數,可以通過HttpServletRequest對象的getQueryString()方法來獲得get請求的參數值。
ServletRequest對象的getInputStream()方法可以獲得一個由Socket得來的輸入流,可以使用這個流來實現文件的上傳。getReader()方法可以直接獲取post請求的參數。
ServletContext對象是Servlet的上下文對象,這個對象是在服務器啟動時創建的,他可以看作是
一個應用的對象,他可以看作是包含Servlet,管理Servlet的對象。
c.servlet的生命周期
遵守servlet規范的類,就可以通過服務器產生對象(反射機制),并處理請求。
servlet接口中的方法
實現Servlet接口
public class TestServlet implements Servlet {
ServletConfig config;
public void init(ServletConfig config) throws ServletException {
this.config=config;
//這個ServletConfig對象是由服務器生成,也就是由系統提供的,
通過他可以獲得啟動信息。ServletConfig對象和Servlet是一一對應的。
//這個方法是在Servlet創建后調用的。如果要是用到ServletConfig對象是一 定要為對象賦值。
}
public ServletConfig getServletConfig() {
return this.config;
}
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
...;//這個方法是用來處理請求的核心方法
}
public String getServletInfo() {
return "....";//這個是用來寫Servlet信息的,用來寫作者,以及版本信息
}
public void destroy() {
...;//這個方法是用來銷毀Servlet對象的
}
}
HttpServlet和GenericServlet都實現了Servlet接口。
HttpServlet中的service(HttpServletRequest request,HttpServletResponse response)方法是通過service(ServletRequest request,ServletResponse response)方法的調用來實現對請求的處理。
HttpServletRequest對象中的方法setAttribute(String name,Object o),可以使用HttpServletRequest對象來攜帶信息,并且可以通過getAttribute(String name)方法來獲得攜帶的信息,這兩個方法類似于map中的存取方法,setAttribute方法給數據加上標識,getAttribute方法則是通過這個標識來獲取數據,可以使用這一對方法的前提就是要保證是同一個請求對象(HttpServletRequest)
HttpServletResponse類
HttpServletResponse是用來回應用戶的操作的,它可以實現頁面的重定向。
sendRedirect(String location),是用這個方法指定要訪問的servlet,其參數是Servlet的url-pattern
如果使用了重定向,就不會保留原有的request對象。
Servlet的生命周期分為四個階段
1,創建Servlet對象,通過服務器反射機制創建Servlet對象,第一次請求時才會創建。(默認)
2,調用Servlet對象的init()方法,初始化Servlet的信息,init()方法只會在創建后被調用一次
3,響應請求,調用service()或者是doGet(),doPost()方法來處理請求,這些方法是運行的在多線程狀態下的。
4,在長時間沒有被調用或者是服務器關閉時,會調用destroy()方法來銷毀Servlet對象。
可以通過web.xml文件可以配置Servlet對象的創建時間,
<load-on-startup>數字</load-on-startup>,表示服務器啟動時創建,并依照數字大小按順序創建,只有重要的Servlet才會是用這個設置。
可以通過<init-param>標簽來配置初始化參數,可以用ServletConfig對象的
getInitParameter(String name)方法來得到參數。
<init-param>
<param-name>...</param-name>
<param-value>...</param-value>
</init-param>
多線程下所操作的變量,如果操作的是一個變量,且兼有讀寫操作,就要考慮加上同步,但同步不能亂加,否則會造成死鎖問題。
init()和destroy()方法都是運行在單線程下的。
GenericServlet類中的有參和無參的init方法。
public void init(ServletConfig config)throws ServletException
{
this.config = config;
init();
}
public void init()throws ServletException
{
.....;//覆蓋了的無參的init()方法,會在Servlet創建時調用有參的init方法時
也會被調用。
}
HttpServlet類中參數不同的service方法的調用關系。
public void service(HttpServletRequest req,HttpServletResponse res){
.......;
.......;
}
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
try
{
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
}
catch(ClassCastException e)
{
throw new ServletException("non-HTTP request or response");
}
service(request, response);
}
Servlet的資源訪問
如果在Servlet中要使用到其他的資源,例如連接數據庫的驅動,可以放在tomcat服務器的文件夾下的common/lib下,這個目錄中存放的是一些在服務器啟動時就會加載的公共資源,一般在需要在應用中使用特定的資源,也就是jar文件,那么不要放在common/lib下,如果common/lib下的jar文件過多會導致服務器啟動緩慢,應用中使用到的jar文件要放在WEB-INF/lib下,就可以被服務器找到了。
如果要在Servlet中是用Hibernate的訪問數據庫的方法,那么就需要把hibernate需要的jar文件,放到WEB-INF/lib下就可以了,Xxxxxx.hbm.xml還是和實體類放在一起。hibernate.cgf.xml文件,要放在WEB-INF/classes下就可以了。
d.MVC框架
Model,模型層,這一層一般是進行數據庫訪問,并且封裝對象,這一層中也存放對業務處理的代碼(業務層)、 與數據庫交互的代碼(DAO層)和實體類的信息,可以使用JavaBean來完成業務層,使用JDBC、 Hibernate或jpa完成DAO層的功能。
Ctrl,控制層,用來處理請求和調用模型層中相應的方法,這一層是用來控制請求的響應的,現在我們是使用Servlet來實現這一層,不過一般是會用開源的MVC框架來實現這層,例如struts、webwork或者是Spring的MVC框架。
View,表現層,他只用來顯示數據和收集必要數據,收集數據的一般是form表單,不過要保證數據的正確性要是用JavaScript做前臺驗證,而且后臺驗證也是必不可少的,html、 JSP就是用來表現、顯示數據的。
e.Servlet的控制流轉
ServletContext,Servlet上下文對象,在每個Servlet中都會有一個ServletContext的引用,這個ServletContext是一個全局的對象,每個應用中只有一個ServletContext對象。
HttpServlet中的getServletContext()方法,獲得ServletContext對象。
ServletContext類的getRequestDispatcher(String path)方法獲得一個RequestDispatcher對象,并且跳轉到指定的Servlet,getRequestDispatcher(String path)方法中的參數就是path,就是指定跳轉的Servlet的url-pattern。
RequestDispatcher類的forward(ServletRequest request, ServletResponse response) 方法,可以把請求對象轉發給其他的Servlet。
f.Servlet的url-pattern
url-pattern可以使用以下三種方式
1,確切路徑匹配,也就是給出確定的路徑 xxx/xxxx
2,模糊路徑匹配,也就是指給出一部分路徑,xxxx/*,他會匹配確定路徑,也就是xxxx/a 或者是xxxx/b都是可以匹配的
3,擴展名匹配,也就是會匹配擴展名,只要是擴展名相同就匹配,xxx.xxx *.xx
注意:擴展名匹配和確切路徑匹配不能放在一起使用,也就是不能寫成 xxxx/xxxx/xxx.xx,但是可以用
*.xxx。
ServletRequest對象的三個返回路徑的方法
getContextPath()獲得應用的路徑,用動態獲取應用路徑
getServletPath()獲得Servlet路徑,也就是form中的action,如果使用確切路徑那么就會是這個Servlet配置的url-pattern。
getPathInfo()使用模糊路徑匹配時會返回匹配模糊部分。
注意:在html的form表單的action中,如果使用了擴展名匹配,一定要寫明/xxxxx/xxx.xx,不要寫成/xxxx/*.xx,在form的action中要盡量使用絕對路徑,也就是要用 應用名/xxx.xx或者應用名/xxx。
三、Session(會話)和Cookie
Session對象用來解決客戶端發送多個請求時用戶請求信息的存儲問題,但是他和ServletRequest對象是不同的,他會在有需要時創建,但是他的生命周期會比請求對象要長。Session對象的生命周期也是有限制的,如果長時間的沒有訪問,就會銷毀掉Session對象,可以通過Session對象的
setAttribute(String name, Object o) 和getAttribute(String name)來存取數據信息。Session是用戶級的對象。
public void service(ServletRequest request,ServletResponse response){
String user = request.getParameter("user");
String pass = request.getParameter("pass");
HttpSession session = request.getSession(true);//使用請求對象來創建Session
session.setAttribute("username", user);
session.setAttribute("passwd", pass);
}
getSession(true)就表示如果Session不存在就創建一個新的Session,并把Session的標識SessionID寫到Cookie中,如果存在就是用這個Session。getSession(false)就是在Session不存在時不會創建新Session而是返回null。如果使用getSession()方法,就等同于getSession(true)。
注意:ServletRequest對象適用于傳輸大量的數據,因為其生命周期比較短,可以有效的節省內存資源。
大數據量的傳輸或保存不適合使用Session空間。
Cookie,是記錄用戶的Session信息,也可以記錄用戶的請求信息,也就是SessionID,來分辨哪一個用戶是否登陸過。在每次登陸時,還會將Cookie發送回服務器端,Cookie是用來跟蹤Session的。
public void service(ServletRequest request,ServletResponse response){
String user = request.getParameter("user");
String pass = request.getParameter("pass");
Cookie userCookie = new Cookie("user", user);
userCookie.setMaxAge(60 * 60 * 24 * 365);//設置Cookie的最大有效期,秒為單位
Cookie passCookie = new Cookie("pass", pass);
passCookie.setMaxAge(60 * 60 * 24 * 365);
response.addCookie(userCookie);
response.addCookie(passCookie);
}
面試題:描述Cookie和Session的作用,區別和各自的應用范圍,Session工作原理。
cookie機制采用的是在客戶端保持狀態的方案
session機制采用的是在服務器端保持狀態的方案。
失效不同:
session
A.程序調用HttpSession.invalidate()
B.距離上一次收到客戶端發送的sessionid時間間隔超過了session的最大有效時間
C.服務器進程被停止
Cookie 會一直存放在客戶端機器上,除非超出Cookie 的生命期限。
Session是由應用服務器維持的一個服務器端的存儲空間,用戶在連接服務器時,會由服務器生成一個唯一的SessionID,用該SessionID 為標識符來存取服務器端的Session存儲空間。而SessionID這一數據則是保存到客戶端,用Cookie保存的,用戶提交頁面時,會將這一 SessionID提交到服務器端,來存取Session數據。這一過程,是不用開發人員干預的。所以一旦客戶端禁用Cookie,那么Session也會失效。
四、Servlet過濾器和監聽器
Servlet過濾器(Filter)
過濾器是用于過濾Servlet的請求和響應,過濾器是存在于請求和被請求資源之間的。
過濾器就像當于一個中間件,請求要經過過濾器,然后過濾器才去掉用Servlet,Servlet的響應也會被過濾器截獲并作相應的處理。
Filter是一個接口,要寫一個自己的Filter就只能實現Filter接口。
Filter也有自己的生命周期,他的生命周期和Servlet比較相似,也是會先調用init()方法,然后再調用核心的處理過濾的方法doFilter(),這個方法中可定義了過濾規則,然后是destory()方法銷毀Filter對象。
dofilter(ServletRequest request,ServletResponse response,FilterChain chain)
這個是過濾的核心方法,FilterChain的方法doFilter(ServletRequest request, ServletResponse response)也就是用過濾后的請求調用資源的方法,如果不寫這個方法,也就算不會去調用相應的資源。
Filter的配置
Filter的配置和Servlet相似。
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>alan.filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/protected/*</url-pattern>
<!--這里的url-pattern就是要過濾的Servlet的url-pattern-->
<dispatcher>request</dispatcher>
<dispatcher>forward</dispatcher>
<dispatcher>include</dispatcher>
<!--上面的三個是過濾的范圍-->
</filter-mapping>
Servlet監聽器
以下是3個Listener接口。
ServletRequestListener
HttpSessionListener
ServletContextListener
這三個監聽器接口,分別監聽Servlet中3種比較重要的對象的創建和銷毀。這三個接口中分別有監聽該對象創建和銷毀事件的方法,服務器本身就是事件源。
listener的配置
<listener>
<listener-class>alan.servlet.listener.AlanContextListener</listener-class>
<!--listener-class也就是實現Listener接口的類-->
</listener>
Servlet中的重要對象(只針對應用)
數量 生命周期 是否線程安全
ServletContext 1 全局的 不安全
只有在應用關閉時才銷毀 需要加同步訪問
HttpSession 和用戶的 局部的 不安全
數量相同 只在有效時間內存在 需要加同步訪問
ServletRequest 多個 局部的 線程安全
(HttpServletRequest) 只在service()和doGet()
doPost()中存在
五、數據庫連接池(了解)
數據庫連接池,也就是在沒有程序取連接時,可以事先創建好連接,連接池是一個運行在多線程環境下,提供數據庫連接的程序,在程序使用完數據庫連接后關閉數據庫連接的動作不再是關閉連接的操作,而是把數據庫連接放回連接池,也就是這個數據庫連接已經是空閑狀態,就可以供其他的程序取用了。
配置Tomcat服務器的數據源
在tomcat下的conf目錄中的tomcat-users.xml文件中配置的是tomcat的用戶
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="manager" description=""/>
<role rolename="admin"/><!--配置管理員-->
<user username="manager" password="123" fullName="" roles="manager"/>
<user username="admin" password="123" roles="admin"/>
<!--配置管理員的用戶名和密碼,并且標明是管理員roles="admin"-->
</tomcat-users>
<Resource
name="jdbc/oracle" 配置JDNI的名字
type="javax.sql.DataSource" 綁定資源的類型
password="sd0605"
driverClassName="oracle.jdbc.driver.OracleDriver" 驅動名
maxIdle="1"最大連接數
maxWait="-1"等待時間,配置為-1就是無限等待,只到有空閑連接為止
username="sd0605"
url="jdbc:oracle:thin:@192.168.0.39:1521:TARENADB"
maxActive="3" 最大活動連接數/>
以下的就是從連接池去取數據庫連接的代碼
public static Connection getConnection(String JNDIName)
{
Connection conn = null;
try
{
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
//這個是在tomcat下默認綁定Context的JNDIname
DataSource ds = (DataSource) envCtx.lookup(JNDIName);
conn = ds.getConnection();
} catch (NamingException ne)
{
ne.printStackTrace();
} catch (SQLException se)
{
se.printStackTrace();
}
return conn;
}
posted on 2009-03-31 19:42
faye 閱讀(572)
評論(0) 編輯 收藏