什麼是Servlet
Servlet是sun公司提供的一門用於開發動態web資源的技術。
A servlet is a small Java program that runs within a Web server.
Servlet作用
Servlets receive and respond to requests from Web clients,
usually across HTTP, the HyperText Transfer Protocol.
能夠接收客戶端請求,進行響應,並且遵循http協議
創建Servlet
編寫一個Java類,實現servlet接口。
public class MyFirstServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
}
把Servlet類部署到web.xml中。
<servlet>
<!--自己配的一個名稱-->
<servlet-name>MyFirstServlet</servlet-name>
<!--一定是servlet類所對應全路徑-->
<servlet-class>com.example.servlet.MyFirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--自己配的一個名稱,和上邊servlet的名稱一定要完全對應-->
<servlet-name>MyFirstServlet</servlet-name>
<!--映射的一個URL,一定是/開頭(具體路徑)-->
<url-pattern>/servlet/MyFirstServlet</url-pattern>
</servlet-mapping>
servlet調用過程
MyElipse-Servlet模板修改
到MyElipse安裝目錄下,搜索 *wizard*.jar
找到 com.genuitec.eclipse.wizards_11.5.0.me
替換templates/Servlet.java
Servlet生命週期
1.在默認情況下,Servlet生命週期執行過程如下:
在用戶第一次請求時:
1.實例化:構造方法1次
2.初始化:(init):1次
3.get 或者 post方法 每次請求都會被執行
3.服務:(service),以後每次請求,都會直接執行service() :N次
4.銷燬:當服務器停止或應用被移除,此時銷燬destory()方法執行: 1次
2.改寫生命週期
是通過<load-on-startup>來實現的
取值: 整數(1開始 越小優先級越高)
結果?
服務器啓動時,對應的Servlet就會執行生命週期(實例化,初始化)
以後每次用戶執行時,走service()方法
優點:當用戶每一次請求時,速度會變快
缺 點:如果load-on-startup配置太多,Tomcat啓動速度會變慢
Servlet具體配置
普通配置
配置多個映射地址
<servlet-mapping> <servlet-name>MyFirstServlet</servlet-name> <url-pattern>/servlet/MyFirstServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name> MyFirstServlet </servlet-name> <url-pattern>/my</url-pattern> </servlet-mapping>
配置統配符
2.通配符的使用 1./* (/servlet/* /* ) 2.*.擴展名(*.do *.action ) 不要這寫成/*.action <servlet-mapping> <servlet-name>MyFirstServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>myfirst</servlet-name> <url-pattern>*.czbk6</url-pattern> </servlet-mapping> http://localhost:8080/myapp/hello.action 3.總結規律: 1.能精確匹配的用精確匹配 /servlet/SecondServlet 2./*優先級高於*.擴展名
線程安全問題
說明servlet不是線程安全的,而且它設計目標就是採用多線程來處理用戶請求
線程安全問題解決方法:
1.synchronized:線程同步
2.用單線程:就是實現SingleThreadModel接口
總結:這兩種方法都不行,違背了設計意圖!!!
最終解決辦法:
程序員自己注意,不要定義成員變量,儘量用局部變量
合理決定在Servlet中定義的變量的作用
ServletConfig
1.什麼是ServletConfig
A servlet configuration object used by a servlet container used to
pass information to a servlet during initialization
2.作用?
1.得到初始化參數?
如何配置初始化參數?
<init-param>
<!-- 參數名 -->
<param-name></param-name>
<!-- 參數名所對應取值 -->
<param-value></param-value>
</init-param>
注意:該標籤出現在<load-on-startup>之前
getInitParameter("參數名");
//獲取所有的參數名稱
Enumeration<String> initParameterNames = servletConfig
.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
//獲取一個又一個的參數名稱
String elementName = initParameterNames.nextElement();
//根據參數名稱獲取參數內容
System.out.println(servletConfig.getInitParameter(elementName));
}
3.得到一個ServletConfig實例的兩種方法?
1,init(ServletConfig config)
2.getServletConfig(); //繼承父類GenericServlet或它的子類才行
ServletContext
1.什麼是ServletContext?
它是服務器產生的一個對象,它用於實現各個Servlet之間信息共享 ,用於獲取全局初始化參數
* 它是運行在服務器中,每個web應用程序都會有一個自己唯一的ServletContext對象。
* 由服務器在加載應用時,就創建好了。
* 它跟web應用程序同生命週期
2.作用? 域中傳值 -兩遍
1.作爲一個全局範圍的域對象來用(四大域作用範圍),可以實現應用範圍的數據共享.實現各個Servlet之間信息共享
實現原理:
就是在全局範圍內維護一個Map集合
setAttrbite(key,Value);
Object obj = getAttribute(key);
removeAttribute(key);
2.獲取全局化參數
getInitParameter("");
getInitParameterNames();
HttpServletRequest
HttpServletRequest 代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息都封裝到這個對象中,開發人員可以通過這個對象,獲取客戶端請求的信息
常用方法
getRequestURL方法返回客戶端發出請求時的完整URL。
getRequestURI方法返回請求行中的資源名部分。
getQueryString 方法返回請求行中的參數部分。
getRemoteAddr方法返回發出請求的客戶機的IP地址
getRemoteHost方法返回發出請求的客戶機的完整主機名
getRemotePort方法返回客戶機所使用的網絡端口號
getLocalAddr方法返回WEB服務器的IP地址。
getLocalName方法返回WEB服務器的主機名
** getMethod得到客戶機請求方式
獲得客戶機請求頭
** getHead(name)方法
getHeaders(String name)方法
getHeaderNames方法
獲得客戶機請求參數(客戶端提交的數據)
** getParameter(name)方法
** getParameterValues(String name)方法
getParameterNames方法
** getParameterMap方法 //做框架用,非常實用
getInputStream
請求參數的中文亂碼問題
瀏覽器是什麼編碼就以什麼編碼傳送數據 GET方式 new String(username.getBytes(“ISO-8859-1”),“UTF-8”); POST方式 request.setCharacterEncoding(“UTF-8”);//POST有效 更改Tomcat的配置解決URL編碼問題:<Connector URIEncoding=“UTF-8”/>
BeanUtils
導包 兩個jar包 logging BeanUtils ---不能夠解決亂碼 // 獲取參數 // 創建一個空對象 Student student = new Student(); // 獲取參數的集合 try { // 直接通過BeanUtils的靜態方法將請求參數的集合賦值進去,對對象進行賦值 BeanUtils.populate(student, req.getParameterMap()); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } // 修改亂碼問題 String string = new String( student.getUsername().getBytes("ISO-8859-1"), "UTF-8"); student.setUsername(string); // 可以打印信息了 System.out.println(student.toString());
HttpServletResponse
對象是指服務器的響應。
這個對象中封裝了向客戶端發送數據、發送響應頭,發送響應狀態碼的方法。
Response 響應數據及亂碼解決
response.setContentType("text/html;charset=UTF-8");
字節流解決亂碼問題
// 指定瀏覽器打開這個網頁的編碼方式
//MIME text/html */*
response.setContentType("text/html;charset=UTF-8");
// 字節流
// 輸出時,指定自己的編碼方式utf-8
response.getOutputStream().write("你好啊,收到了你的請求,很開心".getBytes("UTF-8"));
字符流解決亂碼問題
//通知瀏覽器打開方式爲utf-8
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("你好,我時刻在關注着白百合");