想要實現一個servlet必須繼承這個類,其實一個servlet就是一個java文件,可是這個類必須是繼承HttpServlet。html
servlet的生命週期是從建立到毀滅的一個過程,具體的過程以下:java
- Servlet 經過調用
init ()
方法進行初始化。- Servlet 調用
service()
方法來處理客戶端的請求,可是在這一步仍是要用到具體的實現的兩個方法,分別是doPost(),doGet()- Servlet 經過調用
destroy()
方法終止(結束)。- 最後,Servlet 是由 JVM 的垃圾回收器進行垃圾回收的。
init()
初試化方法
doGet(HttpServletRequest request,HttpServletResponse response)
處理get請求的方法
doPost(HttpServletRequest request,HttpServletResponse response)
處理post請求的方法
destroy()
最後銷燬
Enumeration<E> getInitParameterNames()
該方法從 servlet 的 ServletConfig 對象獲取全部的參數名稱
public String getInitParameter(String name)
該方法從 servlet 的ServletConfig
對象獲取指定參數的值 name是指定的param-name
的值,返回的param-value
的值,具體的使用以下:
<servlet> <display-name>ServletConfigDemo</display-name> <servlet-name>ServletConfigDemo</servlet-name> <servlet-class>com.ServletConfigDemo</servlet-class> <init-param> <param-name>username</param-name> //定義的name <param-value>陳加兵</param-value> //定義的value </init-param> <init-param> <param-name>password</param-name> <param-value>123456</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ServletConfigDemo</servlet-name> <url-pattern>/ServletConfigDemo</url-pattern> </servlet-mapping> //下面只是一個servlet類中的init()方法,通常否是在init()方法中獲取 public void init() throws ServletException { username=this.getInitParameter("username"); //根據指定的名稱獲取參數的值 enumeration=this.getInitParameterNames(); //獲取枚舉對象 while(enumeration.hasMoreElements()){ //經過枚舉的方法獲取其中的全部的值 System.out.println(this.getInitParameter((String) enumeration.nextElement())); } }
ServletConfig getServletConfig()
返回一個ServletConfig對象,這個方法在後面講到ServletConfig類的時候回詳細的說到
ServletContext getServletContext()
返回一個ServletContext對象,這個和ServletConfig類同樣重要,在後面會詳細講解
這是servlet容器中用來處理請求的類,而且該對象做爲一個參數傳給doGet,doPost方法中web
getParameter(String name)
獲取表單中的值,name是input中定義的name值,若是不存在返回null,不然返回的字符串 String[]
getParameterValues(String name)
獲取表單中有多個name相同的值,例如多選列表,複選框
Enumeration getParameterNames()
返回全部請求中的參數,返回的是一個枚舉對象,能夠經過對應的方法進行列出全部的參數
//下面將會詳細講解上面三個方法的使用法,這三個參數是針對表單的,所以須要結合表單講解,咱們將會在index.jsp文件中定義表單 //index.jsp文件的內容以下: <form action="ServletDemo" method="post"> //servletDemo是要處理該請求的servlet的url,使用的是相對路徑 username: <input type="text" name="username"> <br>Password: <input type="password" name="pw"> <br> <input type="submit" value="提交"> <br> <label>hobby:</label> <input type="checkbox" name="hobby" value="1">swing <input type="checkbox" name="hobby" value="2">dancing <input type="checkbox" name="hobby" value="3">song </form> //下面是ServletDemo中的部分代碼 String username = request.getParameter("username"); //獲取username的值 String pw = request.getParameter("pw"); //獲取password的值 //獲取全部複選框的值 String[] hobbies=request.getParameterValues("hobby"); for(String hobby:hobbies){ System.out.println(hobby); } //得到全部的元素的name屬性的名稱,返回的是一個枚舉的對象 Enumeration enumeration = request.getParameterNames(); while (enumeration.hasMoreElements()) { String paramsString = (String) enumeration.nextElement(); //獲取其中的每一名稱 System.out.println(request.getParameter(request.getParameter)); //根據名稱獲取其中的值 }
Enumeration getHeaderNames()
獲取全部請求頭中的參數的名稱,返回的是一個枚舉對象String getHeader(String name)
根據請求頭中的名稱獲取對應名稱的請求內容
//獲取全部請求頭的名稱,返回的是一個枚舉對象 Enumeration enumeration=request.getHeaderNames(); while (enumeration.hasMoreElements()) { String name=(String) enumeration.nextElement(); String value=request.getHeader(name); //根據名稱返回對應的值 System.out.println(name+":"+value); }
String getContextPath()
獲取應用程序的環境路徑,就是上一級目錄String getMethod()
返回請求的方式 Get PostString getQueryString()
返回請求行中的參數部分StringBuffer getRequestURL()
返回完整的URLString getRequestURI()
返回請求行中的資源名部分getRemoteAddr
方法返回發出請求的客戶機的IP地址。getRemoteHost
方法返回發出請求的客戶機的完整主機名。getRemotePort
方法返回客戶機所使用的網絡端口號。getLocalAddr
方法返回WEB服務器的IP地址。getLocalName
方法返回WEB服務器的主機名。
請求轉發至關於一個重定向,可是這個又和重定向不一樣的是:請求轉發是在web容器中進行的,所以瀏覽器的地址欄並不會改變,可是重定向是要求瀏覽器從新請求另外一個url,所以能夠在地址欄清楚的看到地址的變化瀏覽器
請求轉發使用的是
HttpServletRequest
中的getRequestDispatcher
方法,下面將會詳細介紹服務器
RequestDispatcher getRequestDispatcher(String path)
返回的是一個RequestDispatcher
對象,path是指定轉發的url,能夠是絕對url或者是相對urlcookie
定義接收來自客戶端的請求並將它們發送到服務器上的任何資源(好比 servlet、HTML 文件或 JSP 文件)的對象。servlet 容器可建立 RequestDispatcher 對象,該對象被用做包裝位於特定路徑上的服務器資源或經過特定名稱給定的服務器資源的包裝器。網絡
void forward(ServletRequest request, ServletResponse response)
執行轉發請求,由於繼承關係,所以其中的參數也是能夠是HttpServletRequest
和HttpServletResponse
對象app
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); //獲取表單中的值 String name=request.getParameter("username"); String password=request.getParameter("password"); //上面雖然獲取了其中的值,可是不能夠此時對瀏覽器進行響應 RequestDispatcher dispatcher=request.getRequestDispatcher("Demo2"); dispatcher.forward(request, response); }
注意: 在轉發先後不能夠對瀏覽器進行響應,不然會出現錯誤,其中forward傳入的參數是當前的request和response,也就是說在轉發以後的文件之中仍是能夠獲取信息的(請求頭,表單)scrapy
void include(ServletRequest request, ServletResponse response)
包含轉發jsp
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); //獲取表單中的值 String name=request.getParameter("username"); String password=request.getParameter("password"); Cookie cookie=new Cookie("age", "22"); response.addCookie(cookie); PrintWriter pw=response.getWriter(); pw.println("在轉發以前先對瀏覽器進行響應"); //上面能夠看出這裏對瀏覽器進行了響應,使用include能夠在轉發以前或者以後對瀏覽器進行響應 RequestDispatcher dispatcher=request.getRequestDispatcher("Demo2"); dispatcher.include(request, response); }
forward
在轉發以前和以後是不能夠對瀏覽器進行響應的,可是include
能夠。使用include
時,若是同時進行了響應,那麼會同時響應在同一網頁中,會出如今同一個頁面中
- 請求轉發後地址欄都不會出現改變
- 請求轉發事後會從新回到當前的servlet容器中,所以若是想要在當前的servlet容器中處理一些東西是能夠實現的,下面來看一個例子
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); //獲取表單中的值 String name=request.getParameter("username"); String password=request.getParameter("password"); //上面雖然獲取了其中的值,可是不能夠此時對瀏覽器進行響應 RequestDispatcher dispatcher=request.getRequestDispatcher("Demo2"); dispatcher.forward(request, response); System.out.println(username); //這個語句當轉發請求處理完成以後會返回到這裏執行這句話 }
就像寫到
scrapy
爬蟲的時候,有時候一個數據會傳入到下一個函數中使用,所以須要一個機制攜帶過去。這裏可使用HttpServletRequest
中的setAttribute
方法,詳細使用以下:
public void setAttribute(String name, Object o)
這裏其實至關於傳入的是一個鍵值對,name是key,o是value
public void removeAttribute(String name)
根據鍵值的name移除數據
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 設置編碼,這個是經過瀏覽器訪問時可以實現中文顯示的功能 response.setContentType("text/html;charset=UTF-8"); //設置和瀏覽器相應的編碼方式,以便在控制檯上輸出中文,不然將會亂碼顯示 request.setCharacterEncoding("UTF-8"); String data="你們好,我是陳加兵"; request.setAttribute("data",data); //向請求中傳入數據,這個是以鍵值對存在的,前面的是key,後面的參數是value //將請求轉發給HttpServletDemo的servlet文件處理 RequestDispatcher dispatcher=request.getRequestDispatcher("HttpServletResponseDemo"); //若是轉發成功,注意這裏的轉發,地址欄的網址並不會改變 if(dispatcher!=null){ dispatcher.forward(request, response); } } //下面是HttpServletResponseDemo的處理代碼 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); //設置響應內容 request.setCharacterEncoding("UTF-8"); //設置接受的編碼 //接收請求轉發傳遞的data數據 String data=(String) request.getAttribute("data"); PrintWriter pWriter=response.getWriter(); pWriter.println(data+"<br/>"); //移除這個鍵值對 ,下面在訪問這個數據就會顯示不存在了 request.removeAttribute("data"); pWriter.close(); }
這個類是用於對瀏覽器進行響應的
PrintWriter getWriter()
返回一個PrintWriter對象,能夠將字符串發送到客戶端addCookie(Cookie cookie)
將指定的cookie添加到響應中,這個是直接添加到set-cookie中,用於存儲一些信息
Cookie cookie=new Cookie("age", "22"); cookie.setMaxAge(7*24*60*60); //設置cookie的失效時間(秒爲單位) response.addCookie(cookie); //添加cookie
sendError(int src)
將指定的錯誤信息發送到客戶端 好比401,302....sendError(int sec,String message)
發送錯誤信息的同時,還發送提醒的信息messagesendRedirect(String url)
網頁重定向,url是重定向的網址,可是也能夠是相對的urlServletOutputStream getOutputStream()
返回適用於在響應中編寫二進制數據的 ServletOutputStream。
在
web.xml
中對於每個Servlet的設置web容器會爲其生成一個ServletConfig
做爲表明對象,你能夠從該對象中取得設置在web.xml中的Servlet初始參數
String getInitParameter(String name)
根據屬性的名稱獲取指定的值
Enumeration getInitParameterNames()
獲取該servlet中設置的全部的屬性的名稱(並非設置的初始值)
ServletContext getServletContext()
獲取ServletContext對象
ServletConfig
至關於web.xml中個別Servlet設置表明對象,這意味着能夠從ServletConfig中取得Servlet設置信息。ServletConfig定義了getInitParameter()
、getInitParameterNames()
方法,能夠取得設置的Servlet的初始參數
直接在web.xml中定義以下:
<servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>Demo3</servlet-name> <servlet-class>com.Demo3</servlet-class> <init-param> //定義標籤 <param-name>username</param-name> //定義的name <param-value>陳加兵</param-value> //定義的value </init-param> <init-param> <param-name>password</param-name> <param-value>123456</param-value> </init-param> </servlet>
第一種方法:直接使用帶有ServletConfig對象爲參數的init直接獲取
public void init(ServletConfig config) throws ServletException { // username=config.getInitParameter("username"); //單獨的獲取每個值 // password=config.getInitParameter("password"); //首先獲取全部的初始參數的名稱 Enumeration enumeration=config.getInitParameterNames(); while(enumeration.hasMoreElements()){ String name=(String)enumeration.nextElement(); //獲取每個值 if(name.equals("username")){ username=config.getInitParameter(name); }else if (name.equals("password")) { password=config.getInitParameter(name); } } }
第二種:使用
HttpServlet
的getServletConfig()
方法直接獲取ServletConfig對象,而後再獲取參數
public void init() throws ServletException { ServletConfig config=this.getServletConfig(); //獲取ServletConfig對象 username=config.getInitParameter("username"); //獲取參數的值 password=config.getInitParameter("password"); }
ServletContext
是整個web應用程序運行以後的表明對象,這是一個全局的對象,一個web項目中的全部Servlet文件都是能夠共享這個數據的,所以這個有着很大的做用。
- 有人說這個不是和
ServletConfig
同樣的用法嗎,其實否則,ServletConfig
並非這個web程序的全局變量,它所設置的值只是對當前的servlet共享,並不能對web項目中的全部的servlet文件共享
String getInitParameter(String name)
獲取指定名稱的屬性值
Enumeration getInitParameterNames()
獲取全部已經設置的屬性的名稱
void setAttribute(String name, Object object)
將對象綁定到此 servlet 上下文中的給定屬性名稱。若是已將指定名稱用於某個屬性,則此方法將使用新屬性替換具備該名稱的屬性。
Object getAttribute(String name)
根據指定的屬性名稱獲取綁定的值(須要進行強轉)
void removeAttribute(String name)
解除綁定的數據
這個和
ServletConfig
是同樣的,都是在web.xml中設置的,可是這個是設置在<servlet></servlet>
的外面的,並非針對單獨的一個servlet
來設置的,所以是全局共享的
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>web2</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!--全局變量,對工程中的全部的Servlet都是共享的--> <context-param> <param-name>context_name</param-name> <param-value>context_value</param-value> <!--在每一對context-param中只能定義一個變量的值--> </context-param> <context-param> <param-name>username</param-name> <param-value>陳加兵</param-value> </context-param> <servlet> <servlet-name>Demo1</servlet-name> <servlet-class>com.Demo1</servlet-class> </servlet> <servlet> <servlet-name>Demo2</servlet-name> <servlet-class>com.Demo2</servlet-class> </servlet> <servlet-mapping> <servlet-name>Demo1</servlet-name> <url-pattern>/Demo1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Demo2</servlet-name> <url-pattern>/Demo2</url-pattern> </servlet-mapping> </web-app>
- 第一種方法:使用無參初始化的方法
init()
,結合父類HttpServlet
的getServletContext()
的方法獲取ServletContext
對象
//使用無參構造函數 public void init() throws ServletException { ServletContext context=this.getServletContext(); //根據屬性的名稱獲取指定的值 String value=context.getInitParameter("username"); System.out.println(value); //獲取全部的屬性的名稱的枚舉對象 Enumeration enumeration=context.getInitParameterNames(); while(enumeration.hasMoreElements()){ //獲取屬性的每個名稱 String name=(String) enumeration.nextElement(); //根據名稱獲取全部的值 System.out.println(name+" = "+context.getInitParameter(name)); } }
- 第二種方法:使用有參初始化方法
init(ServletConfig config)
,結合ServletConfig
的getServletContext()
方法獲取對象
//使用有參構造方法 public void Init(ServletConfig config){ //調用ServletConfig中的方法獲取對象 ServletContext context=config.getServletContext(); //獲取屬性的值 String value=context.getInitParameter("username"); System.out.println(value); }
有人可能會說若是想用共享數據在web.xml設置有點繁瑣,這裏能夠直接綁定屬性,而後就能夠在整個web項目中共享這個綁定的屬性了
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); //獲取對象(這是父類HttpServlet中的一個方法) ServletContext context=this.getServletContext(); //count表示訪問頁面的次數,在這裏設置了屬性能夠全局共享該數據,意思就是在一個項目中的全部的servlet都是能夠訪問到該數據的 Integer count=(Integer) context.getAttribute("count"); //獲取設置的屬性值 //若是爲空,表示該屬性尚未被設置,所以這是第一次訪問該頁面 if(count==null){ count=1; context.setAttribute("count", 1); //初始值爲1,表示訪問網頁1次 }else { //不然表示已經不是第一次訪問網頁了,所以須要++1 context.setAttribute("count", ++count); } PrintWriter pWriter=response.getWriter(); pWriter.println("該頁面已經被訪問了"+count+"次了......"); }