認識Servlet
Servlet在第一次被訪問的時候,加載,實例化,初始化,之後的每次訪問,僅僅做請求的處理
當服務器關閉的時候,會對所有的Servlet進行銷燬
在服務器運行的過程中,他只會維護一個Servlet的實例,用這個實例來處理所有用戶的請求
每一個用戶訪問服務器,服務器就會爲該用戶開闢一個新的線程,也就是說,所有的線程共享同一個Servlet,因此在Servlet裏不能去定義類的屬性,這樣會發生併發錯誤,如果非要在Servlet中定義屬性,需要手動控制線程同步
Servlet的生命週期
1.客戶端第一次請求一個Servlet時,web服務器(如tomcat)根據web.xml的配置信息找到此Servlet的類,並創建該Servlet的對象,並根據配置信息創建ServletConfig對象,然後調用Servlet對象的init(ServletConfig)方法進行初始化
2.服務器解析請求信息,創建HttpServletRequest對象,把請求信息封裝到HttpServletRequest對象中,然後創建空的HttpServletResponse對象
3.服務器調用Servlet對象的service方法,並把HttpServletRequest對象和HttpServletResponse對象傳遞給service方法的參數
4.service方法自動派遣運行與請求對應的doXXX方法(doGet,doPost)等
5.以後再收到此請求時直接調用service方法處理請求
HttpServletResponse與HttpServletRequest的相關方法
1.HttpServletResponse
response.setStatus(i); //設置響應碼
response.setHeader(name ,value) //設置響應頭
response.setContentType(s); //設置響應內容的mime類型
response.setContentLength(i) //設置響應體長度
response.setCharacterEncoding(s) //設置響應體編碼方式
response.getOutputStream() //獲得字節輸出流,向瀏覽器發送數據
response.getWriter() //獲得字符輸出流
2.HttpServletRequest
2.1獲取客戶端主機信息
request.getRemoteAddr()
request.getRemoteHost()
request.getRemotePort()
2.2獲取請求的url相關的信息
request.getScheme()
request.getServerName()
request.getServerPort()
request.getContextPath()
request.getServletPath()
request.getRequestURL()
2.3獲取請求行的相關信息
request.getMethod()
request.getRequestURI()
request.getProtocol()
request.getQueryString()
2.4獲取請求頭信息的相關方法
request.getHeader(headerName);
request.getHeaderNames();
request.getHeaders(headerName)
request.getContentLength();
request.getContentType();
2.5獲取請求參數或請求體的相關方法
request.getParameter(name);
request.getParameterMap();
request.getParameterNames();
request.getParameterValues(name)
request.getInputStream();
request.getReader();
Servlet配置信息
在JSP和Servlet中讀取web.xml的初始化參數。
一、在Servlet中讀取:
在Servlet中一般可以用ServletConfig對象的getInitParameter方法去讀取指定的參數的值。舉個例子:
新建一個Servlet:GetInitParameter.java
並在web.xml中增加如下配置:
<servlet>
<servlet-name>GetInitParameter</servlet-name>
<servlet-class>com.shc.GetInitParameter</servlet-class>
<init-param>
<param-name>Baidu</param-name>
<param-value>http://www.baidu.com</param-value>
</init-param>
<init-param>
<param-name>Wangyi</param-name>
<param-value>http://www.163.com</param-value>
</init-param>
</servlet>
<servletclass>com.shc.GetInitParameter</servlet-class>是servlet的完整路徑,包括包名。
配置好了web.xml,現在可以在程序中讀取初始化的參數了。在init(ServletConfig config)方法中傳遞了一個ServletConfig參數,可以這樣獲取初始化參數:
public void init(ServletConfig config) throws ServletException
{
super.init(config);
String email = config.getInitParameter("Baidu");
String name = config.getInitParameter("Wangyi");
}
在其他的方法中象doGet(),doPost(),service()方法中可以用getServeltConfig()方法得到一個ServetConfig對象,在利用該對象的getInitParameter()方法取到對應的初始化參數。
String baidu = getServletConfig().getInitParameter("Baidu");
String wangyi= getServletConfig().getInitParameter("Wangyi");
二、在JSP中讀取:
在JSP中讀取的方式和Servlet中的doGet(),doPost(),Service()
的方法一樣,都是由ServletConfig對象來讀取的。
<% String baidu = getServletConfig().getInitParameter("Baidu");
String wangyi= getServletConfig().getInitParameter("Wangyi");
%>
但是,在web.xml的配置需要注意一下,新增如下:
<servlet>
<servlet-name>GetInitParam</servlet-name>
<jsp-file>GetInitParam.jsp</jsp-file>
<init-param>
<param-name>Baidu</param-name>
<param-value>http://www.baidu.com</param-value>
</init-param>
<init-param>
<param-name>Wangyi</param-name>
<param-value>http://www.163.com</param-value>
</init-param>
</servlet>
在servlet-mapping中也要配置好:
<servlet-mapping>
<servlet-name>GetInitParam</servlet-name>
<url-pattern>GetInitParam.jsp</url-pattern>
</servlet-mapping>
上面的GetInitParam.jsp出現的標籤需要jsp文件的全部路徑。
三.在web.xml中配置通用參數
<context-param>
<param-name>context/param</param-name>
<param-value>application param</param-value>
</context-param>
application範圍內的參數,存放在servletcontext中,在web.xml中配置如下上。
在servlet裏面可以通過getServletContext().getInitParameter("context/param")得到。
init-param屬於一個servlet所有,context-param屬於整個應用程序所有 ,不僅是在servlet中可以得到,jsp文件中也可以得到.
在jsp中config就相當於這裏的servletContext,
<%=config.getServletContext().getInitParameter("...") %>.
action中ServletActionContext.getServletContext().getInitParameter("...").
Servlet響應結果導航
1.使用response.getWriter()方式把響應數據直接發送給瀏覽器
2.使用response.sendRedirect(url)方式告訴瀏覽器重新請求url資源(url帶上項目路徑)
3.使用 請求的轉發request.getRequestDispatcher(path).forward(request,response)方式把請求轉發到另一個Servlet,讓另一個Servlet去進一步處理請求並生成響應(path不帶項目路徑)
請求轉發與重定向的區別
1.從地址欄顯示來說
轉發(forward)是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,然後把這些內容再發給瀏覽器.瀏覽器根本不知道服務器發送的內容從哪裏來的,所以它的地址欄還是原來的地址.
重定向(redirect)是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器重新去請求那個地址.所以地址欄顯示的是新的URL.所以重定向重定向(redirect)等於客戶端向服務器端發出兩次request,同時也接受兩次response。
轉發(forward)只是一次request一次response
2.從效率來說
forward:高.
redirect:低.
3.Forward能夠存儲request Scope的Attribute而Redirect卻不行。
4.Forward需要在Servlet中需要通過一個Dispatcher來實現。
5.Redirect能夠防止某些情況下客戶端Refresh造成的一些未知後果(例如連續刪除)
6.從運用地方來說
forward:一般用於用戶登陸的時候,根據角色轉發到相應的模塊.
redirect:一般用於用戶註銷登陸時返回主頁面和跳轉到其它的網站
7.傳值
在重定向(redirect)方法中傳值
1. 通過session傳遞,前提是同一個服務器
2.拼裝帶參數的url,直接redirect到新的地址上
轉發(forward)方法中傳值
1.request.setAttribule("userName",name);//也可以傳遞對象
2.通過session傳遞,前提是同一個服務器
3.拼裝帶參數的url