Servlet接口:
- Servlet主要方法:
init()--ServletConfig
servlet實(shí)例化后,容器會(huì)先調(diào)用init方法,用于初始化對象,即在處理客戶需求前完成一些初始化工作。每一個(gè)Servlet實(shí)例,init只能被調(diào)用一次,相當(dāng)于java的static塊。
Servlet使用ServletConfig對象從web應(yīng)用程序的配置信息中獲取以 鍵值對形式提供的初始化參數(shù)。
Servlet使用ServletConfig對象獲取ServletContext對象,使用ServletContext可以使Servlet和Servlet容器進(jìn)行通信。
service()--ServletRequest ServletResponse
容器調(diào)用service()方法來處理客戶的請求,注意:在service方法前必須確保init方法正確完成。
容器會(huì)構(gòu)造一個(gè)請求對象ServletRequest和響應(yīng)對象ServletResponse作為參數(shù)傳遞給service().
destroy():
當(dāng)容器檢測到Servlet對象從服務(wù)中移除的時(shí)候會(huì)調(diào)用該方法。釋放資源給GC
getServletConfig()
返回Servletconfig對象
getServletInfo()
返回一個(gè)字符串,包含Servlet信息
- Servlet創(chuàng)建的三種方法
一是實(shí)現(xiàn)Servlet接口;二是繼承抽象類GenericServlet;三是繼承HttpServlet類
-- 實(shí)現(xiàn)Servlet接口,必須實(shí)現(xiàn)Servlet五個(gè)方法
public class TestServlet implements Servlet{
public void init(ServletConfig config) throws
ServletException{
System.out.println("init");
}
public ServletConfig getServletConfig(){
return null;
}
public void service(ServletRequest req, ServletResponse res) throws ServletException,IOException{
//這里可以實(shí)現(xiàn)請求后要做的內(nèi)容
PrintWriter out = response.getWriter();
out.println("Hello World!");
}
public String getServletInfo(){
return null;
}
public void destroy(){
System.out.println("destroy");
}
}
--繼承抽象類GenericServlet. GenericServlet類中只有一個(gè)抽象方法,即service(ServletRequest req, ServletResponse res)
public TestGenericServlet extends GenericServlet{
public abstract void service(ServletRequest req,ServletResponse res)
throws ServletException,IOException{
PrintWriter out = response.getWriter();
out.println("Hello World!");
}
}
--繼承HttpServlet類編寫Servlet應(yīng)該是最容易的,而且是最常見的,我們一般要編寫Servlet直接繼承這個(gè)類就行了,重寫doGet()或者doPost()方法即可
public TestHttpServlet extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
response.setContentType("text/html;charset = gb2312");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>HelloWorld</title>");
out.println("</head>");
out.println("<body bgcolor = \"white\">");
out.println(“<hr>”);
out.println("HelloWorld");
out.println("</body></html>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
doGet(request, response);
}
}
HttpServlet詳解
HttpServletRequest,HttpServletResponse詳解
HttpServletRequest:String getContextPath()返回請求URL中表示上下文的部分,如:/simple/test返回/simple
Cookie[] getCookies()返回本次請求所有的Cookie對象
String getHeader()返回請求報(bào)頭的值
String getMethod()返回本次請求使用的HTTP方法的名字,如post get Trace等
String getPathInfo()返回額外url信息,如/simple/test 返回test
String getPathTranslated()返回真實(shí)路徑信息 如
String getQueryString()返回請求的action 名稱 如
返回 logon
HttpSession getSession()返回和此次請求相關(guān)聯(lián)的session
HttpServletResponse:void addCookie(Cookie cookie)新增一個(gè)cookie到響應(yīng)中去,可以設(shè)置多個(gè)。
addheader(String name,String value)用給出的name and value增加一個(gè)響應(yīng)報(bào)頭到響應(yīng)中去
sendRedirect(String location)發(fā)送一個(gè)臨時(shí)的重定向到客戶端,讓客戶端訪問的url重新定位
ServletConfig
servlet容器使用ServletConfig對象在容器初始 化的時(shí)候向其傳遞配置信息四種主要方法:
String getInitParameter(String name)返回名字為name的初始化參數(shù)的值,初始化參數(shù)在配置文件web.xml中配置
Enumeration getInitParameterNames()返回Servlet所有初始化參數(shù)名字的枚舉集合
ServletContext getServletContext()返回Servlet上下文對象的引用
String getServletName()返回當(dāng)前Servlet的名稱
Servlet配置
web.xml:web應(yīng)用程序的配置和部署都是通過web.xml來完成的,其包含以下信息
ServletContext 的初始化參數(shù)
Session 的配置
Servlet/Jsp的定義
MIME類型映射
歡迎文件列表
錯(cuò)誤頁面
安全
地區(qū)和編碼映射
JSP配置
post和get方式
消息報(bào)頭
Servlet生命周期
Servlet上下文
運(yùn)行在java虛擬機(jī)中的每一個(gè)web程序都有一個(gè)與之相關(guān)的Servlet上下文,java servlet API提供了一個(gè)servletContext接口來表示上下文。
一個(gè)ServletContext對象表示了一個(gè)Web程序的上下文,Servlet容器在初始實(shí)例期間,向其傳遞servletConfig對象,通過其getServletContext()獲取上下文。
上下文例子:統(tǒng)計(jì)頁面訪問量:注意這里的上下文必須放在安全鎖里
public class CountDemo extends HttpServlet{
public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException,IOException{
ServletContext context = getServletContext();
//Enumeration<String>count = context.getAttributeNames();
Integer count = null;
synchronized(context){
count = (Integer)context.getAttribute("counter");
if(null == count){
count = new Integer(1);
}else{
count = new Integer(count.inValue()+1);
}
context.setAttribute("counter", count);
}
res.setContentType("text/html;charset=gb2312");
PrintWriter pw = res.getWriter();pw.println("<html><head>");
pw.println("<title>頁面訪問統(tǒng)計(jì)</title>");
pw.println("</head><body>");
pw.println("該頁面已經(jīng)被訪問了 :"+"<b>"+count+"</b>"+" 次");
pw.println("</body></html>");
pw.close();
}
}
Servlet請求轉(zhuǎn)發(fā)
好處:
- 提供了統(tǒng)一的訪問方式
- 控制器(controller)可以將不同的請求發(fā)送給不同的Servlet來進(jìn)行處理,本身不處理請求,縮短了響應(yīng)時(shí)間
RequestDispacher:servlet控制器
RequestDispacher對象由Servlet來創(chuàng)建,用于封裝一個(gè)由路徑所標(biāo)識(shí)的服務(wù)器資源。主要有以下兩種方法:
- forward(ServletRequest req, ServletResponse res):
該方法用于將請求從一個(gè)Servlet傳遞給服務(wù)器上的另外的Servlet jsp頁面,或者HTML文件
注意:這個(gè)方法必須在響應(yīng)被提交給客戶端之前使用,之后的話會(huì)爆出IllegastateException錯(cuò)誤,在forward()調(diào)用后原先在響應(yīng)緩存中未被提交的內(nèi)容將會(huì)自動(dòng)清除。 - include(ServletRequest req, ServletResponse res)該方法用于響應(yīng)中包含其他的資源信息(servlet jsp html)等內(nèi)容。
這兩個(gè)方法的區(qū)別是:include將請求轉(zhuǎn)發(fā)給其他對象后,被調(diào)用的Servlet做出的響應(yīng)將并入原來的響應(yīng)對象中,原來的Servlet對象還可以繼續(xù)輸出響應(yīng)數(shù)據(jù)。
forward將請求轉(zhuǎn)發(fā)給其他對象后,將由被調(diào)用的Servlet對象做出響應(yīng),原來的Servlet執(zhí)行將終止。
- RequestDispache對象的獲取
三種方法
--ServletRequest.getRequestDispacher(String path)--資源路徑名
--ServletContext.getNamedDispacher(String name)--jsp或servlet名稱
--ServletContext.getRequestDispacher(String path)--這里路徑必須從/開頭 相對于當(dāng)前上下文根的路徑 如/MyServlet
請求轉(zhuǎn)發(fā)的實(shí)例
package com.tide.servlet;import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
public class Login extends HttpServlet {
public void doPost(HttpServletRequest req,HttpServletResponse res)throws ServletException,IOException{
res.setContentType("text/html;charset=GB2312");
ServletContext context = getServletContext();
String name = req.getParameter("user");
String pass = req.getParameter("passwd");
System.out.println("獲取到的用戶名為 :"+name+" --密碼為 :"+pass);
if(StringUtils.isBlank(name) || StringUtils.isBlank(pass)){
System.out.println("用戶名或密碼為空");
RequestDispatcher dis = context.getRequestDispatcher("/register.jsp");
dis.forward(req, res);
}
else{
RequestDispatcher dis = context.getRequestDispatcher("/loginsuccess.jsp");
dis.forward(req, res);
}
}
}
底層分析:
請求轉(zhuǎn)發(fā)(RequestDispatcher)的過程:
客戶首先發(fā)送一個(gè)請求到服務(wù)端,服務(wù)端發(fā)現(xiàn)匹配的Servlet,并指定它去執(zhí)行,當(dāng)這個(gè)Servlet執(zhí)行完之后,它要調(diào)用getRequestDispatcher()方法,把請求轉(zhuǎn)發(fā)給指定的test.jsp,整個(gè)流程都是在服務(wù)端完成的,而且是在同一個(gè)請求里面完成的,因此Servlet和jsp共享的是同一個(gè)request,在Servlet里面放的所有東西,在jsp中都能取出來,因此,jsp能把結(jié)果getAttribute()出來,getAttribute()出來后執(zhí)行完把結(jié)果返回客戶端。整個(gè)過程是一個(gè)請求,一個(gè)響應(yīng)。
重定向(sendRedirect)的工作原理
客戶發(fā)送一個(gè)請求到服務(wù)器,服務(wù)器匹配Servlet,這都和請求轉(zhuǎn)發(fā)一樣,Servlet處理完之后調(diào)用了sendRedirect()這個(gè)方法,這個(gè)方法是response的方法,所以,當(dāng)這個(gè)Servlet處理完之后,看到response.sendRedirect()方法,立即向客戶端返回這個(gè)響應(yīng),響應(yīng)行告訴客戶端受到這個(gè)請求后,立刻發(fā)出一個(gè)新的請求,去請求test.jsp,這里兩個(gè)請求,這個(gè)兩個(gè)請求互不干擾,相互獨(dú)立,子啊前面request里面setAttribute()的任何東西,在后面的request里面都獲得不了??梢姡趕endRedirect()里面是兩個(gè)請求,兩個(gè)響應(yīng)。