Servlet 的 HelloWorld
1.創建一個 Servlet 接口的實現類.
public class HelloServlet implements Servlet {
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("destroy");
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
System.out.println("getServletConfig");
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
System.out.println("getServletInfo");
return null;
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("init");
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("service");
}
public HelloServlet() {
super();
// TODO Auto-generated constructor stub
System.out.println("HelloServlet ...Constructor");
}
}
2.在 web.xml 文件中配置和映射這個 Servlet
<!-- 配置和映射 Servlet -->
<servlet>
<!-- Servlet 註冊的名字 -->
<servlet-name>helloServlet</servlet-name>
<!-- Servlet 的全類名 -->
<servlet-class>com.javaweb.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 需要和某一個 servlet 節點的 serlvet-name 子節點的文本節點一致 -->
<servlet-name>helloServlet</servlet-name>
<!-- 映射具體的訪問路徑: / 代表當前 WEB 應用的根目錄. -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
啓動Tomcat,瀏覽器訪問http://localhost:8080/項目名/hello
控制檯打印
HelloServlet ...Constructor
init
service
3.Servlet 生命週期
第一次訪問http://localhost:8080/項目名/hello,結果如上
之後再訪問只輸出
...
service
service
service
...
stop tomcat後打印
destroy
1). 構造器: 只被調用一次. 只有第一次請求 Servlet 時, 創建 Servlet 的實例. 調用構造器. 這說明 Serlvet 的單實例的!
2). init 方法: 只被調用一次. 在創建好實例後立即被調用. 用於初始化當前 Servlet.
3). service: 被多次調用. 每次請求都會調用 service 方法. 實際用於響應請求的.
4). destroy: 只被調用一次. 在當前 Servlet 所在的 WEB 應用被卸載前調用. 用於釋放當前 Servlet 所佔用的資源.
4. load-on-startup 參數:
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.javaweb.HelloServlet</servlet-class>
<!-- 可以指定 Servlet 被創建的時機 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>secondServlet</servlet-name>
<servlet-class>com.javaweb.SecondServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
2). load-on-startup: 可以指定 Serlvet 被創建的時機. 若爲負數, 則在第一次請求時被創建.若爲 0 或正數, 則在當前 WEB 應用被
Serlvet 容器加載時創建實例, 且數值越小越早被創建.
5. 關於 serlvet-mapping:
1). 同一個Servlet可以被映射到多個URL上,即多個 <servlet-mapping> 元素的<servlet-name>子元素的設置值可以是同一個
Servlet的註冊名。
例如
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.javaweb.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
即 HelloServlet 可以 通過 /hello 訪問,也可以通過/hello2來訪問2). 在Servlet映射到的URL中也可以使用 * 通配符,但是隻能有兩種固定的格式:
一種格式是“*.擴展名”,另一種格式是以正斜槓(/)開頭並以“/*”結尾。
<servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
OR
<servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
注意: 以下的既帶 / 又帶擴展名的不合法.
<servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<url-pattern>/*.action</url-pattern>
</servlet-mapping>
6. ServletConfig: 封裝了 Serlvet 的配置信息, 並且可以獲取 ServletContext 對象
1). 配置 Serlvet 的初始化參數
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.javaweb.HelloServlet</servlet-class>
<!-- 配置 Serlvet 的初始化參數。 且節點必須在 load-on-startup 節點的前面 -->
<init-param>
<!-- 參數名 -->
<param-name>user</param-name>
<!-- 參數值 -->
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>root</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
2). 獲取初始化參數,Serlvet 的配置名稱(瞭解),獲取 ServletContext 對象
@Override
public void init(ServletConfig servletConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("init");
// 獲取初始化參數
String user = servletConfig.getInitParameter("user");
System.out.println("user: " + user);
Enumeration<String> names = servletConfig.getInitParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = servletConfig.getInitParameter(name);
System.out.println("--" + name + " : " + value);
}
//獲取Servlet註冊名稱
String servletName = servletConfig.getServletName();
System.out.println(servletName);
//獲取ServletContext
ServletContext servletContext = servletConfig.getServletContext();
}
結果
init
user: root
--user : root
--password : root
hello
(1)、public String getInitParameter(String name):返回指定名稱的初始化參數值;
(2)、public Enumeration getInitParameterNames():返回一個包含所有初始化參數名的Enumeration對象;
(3)、public String getServletName():返回在DD文件中<servlet-name>元素指定的Servlet名稱;
(4)、public ServletContext getServletContext():返回該Servlet所在的上下文對象;
7.ServletContext
1). 可以由 SerlvetConfig 獲取:
ServletContext servletContext = servletConfig.getServletContext();
2). 該對象代表當前 WEB 應用: ServletContext,是一個全局的儲存信息的空間,服務器開始,其就存在,服務器關閉,其才釋放。
可以從中獲取到當前 WEB 應用的各個方面的信息.
①. 獲取當前 WEB 應用的初始化參數
設置初始化參數: 可以爲所有的 Servlet 所獲取
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
方法:
getInitParameter
getInitParameterNames
代碼
@Override
public void init(ServletConfig servletConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("init");
...
// 獲取ServletContext
ServletContext servletContext = servletConfig.getServletContext();
String contextParam = servletContext.getInitParameter("driver");
System.out.println(contextParam);
Enumeration<String> names2 = servletContext.getInitParameterNames();
while (names2.hasMoreElements()) {
String name = names2.nextElement();
String value = servletContext.getInitParameter(name);
System.out.println("kk" + name + " : " + value);
}
}
②. 獲取當前 WEB 應用的某一個文件在服務器上的絕對路徑, 而不是部署前的路徑
String realPath = servletContext.getRealPath("/");
System.out.println(realPath);
String realPath2 = servletContext.getRealPath("/hello.jsp");
System.out.println(realPath2);
輸出
D:\workspaces\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FirstWeb\
D:\workspaces\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FirstWeb\hello.jsp
③. 獲取當前 WEB 應用的名稱:
getContextPath()
String servletContextName = servletContext.getServletContextName();
String contextPath = servletContext.getContextPath();
System.out.println(contextPath + "------" + servletContextName);
結果/FirstWeb------FirstWeb
④. 獲取當前 WEB 應用的某一個文件對應的輸入流.
getResourceAsStream(String path): path 的 / 爲當前 WEB 應用的根目錄.
代碼:
Properties pros = new Properties();
try {
ClassLoader classLoader = getClass().getClassLoader();
InputStream is = classLoader.getResourceAsStream("jdbc.properties");
System.out.println("1. " + is);
pros.load(is);
System.out.println(pros.getProperty("name"));
} catch (Exception e) {
e.printStackTrace();
}
pros = new Properties();
try {
InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc.properties");
System.out.println("2. " + is2);
pros.load(is2);
System.out.println(pros.getProperty("name"));
} catch (Exception e) {
e.printStackTrace();
}
等等。。。
8. GET 請求和 POST 請求:
1). 使用GET方式傳遞參數:
①. 在瀏覽器地址欄中輸入某個URL地址或單擊網頁上的一個超鏈接時,瀏覽器發出的HTTP請求消息的請求方式爲GET。
②. 如果網頁中的<form>表單元素的 method 屬性被設置爲了“GET”,瀏覽器提交這個FORM表單時生成的HTTP請求消息的請求方式也爲GET。
③. 使用GET請求方式給WEB服務器傳遞參數的格式:
http:/localhost:8080/counter.jsp?name=lc&password=123
④. 使用GET方式傳送的數據量一般限制在 1KB 以下。
2). 使用 POST 方式傳遞參數:
①. POST 請求方式主要用於向 WEB 服務器端程序提交 FORM 表單中的數據: form 表單的 method 置爲 POST
②. POST 方式將各個表單字段元素及其數據作爲 HTTP 消息的實體內容發送給 WEB 服務器,傳送的數據量要比使用GET方式傳送的數據量大得多。
POST /counter.jsp HTTP/1.1
referer: http://localhost:8080/Register.html
content-type: application/x-www-form-urlencoded
host: localhost:8080
content-length: 43
name=zhangsan&password=123 --請求體中傳遞參數
9. 如何在 Serlvet 中獲取請求信息:
1). Servlet 的 service() 方法用於應答請求: 因爲每次請求都會調用 service() 方法
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException
ServletRequest: 封裝了請求信息. 可以從中獲取到任何的請求信息.
ServletResponse: 封裝了響應信息, 如果想給用戶什麼響應, 具體可以使用該接口的方法實現.
這兩個接口的實現類都是服務器給予實現的, 並在服務器調用 service 方法時傳入.
2). ServletRequest: 封裝了請求信息. 可以從中獲取到任何的請求信息.
①. 獲取請求參數:
> String getParameter(String name):
根據請求參數的名字, 返回參數值.
若請求參數有多個值(例如 checkbox), 該方法只能獲取到第一個提交的值.
> String[] getParameterValues(String name): 根據請求參數的名字, 返回請求參數對應的字符串數組.
> Enumeration getParameterNames(): 返回參數名對應的 Enumeration 對象,
類似於 ServletConfig(或 ServletContext) 的 getInitParameterNames() 方法.
> Map getParameterMap(): 返回請求參數的鍵值對: key: 參數名, value: 參數值, String 數組類型.
②. 獲取請求的 URI:
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String requestURI = httpServletRequest.getRequestURI();
System.out.println(requestURI); // /day_29/loginServlet
③. 獲取請求方式:
String method = httpServletRequest.getMethod();
System.out.println(method); //GET
④. 若是一個 GET 請求, 獲取請求參數對應的那個字符串, 即 ? 後的那個字符串.
String queryString = httpServletRequest.getQueryString();
System.out.println(queryString); //user=ddf&password=123456&interesting=game&interesting=party&interesting=shopping
⑤. 獲取請求的 Serlvet 的映射路徑
String servletPath = httpServletRequest.getServletPath();
System.out.println(servletPath); // /loginServlet
⑥. 和 attribute 相關的幾個方法:
3). HttpServletRequest: 是 SerlvetRequest 的子接口. 針對於 HTTP 請求所定義. 裏邊包含了大量獲取 HTTP 請求相關的方法.
4). ServletResponse: 封裝了響應信息, 如果想給用戶什麼響應, 具體可以使用該接口的方法實現.
①. *getWriter(): 返回 PrintWriter 對象. 調用該對象的 print() 方法, 將把 print() 中的參數直接打印
到客戶的瀏覽器上.
②. 設置響應的內容類型: response.setContentType("application/msword");
③. void sendRedirect(String location): 請求的重定向. (此方法爲 HttpServletResponse 中定義.)
form表單
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="loginService" method="post">
用戶名<input name="user" type="text"><br> 密碼<input
name="password" type="password"><br> <br> <br>
愛好 :
<input type="checkbox" name="interesting" value="reading">reading
<input type="checkbox" name="interesting" value="shopping">shopping
<input type="checkbox" name="interesting" value="sport">sport
<input type="submit">
</form>
</body>
</html>
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class LoginServlet implements Servlet {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("請求來了。。。");
// 獲取請求參數
String user = request.getParameter("user");
String password = request.getParameter("password");
System.out.println("user=" + user + " password=" + password);
//request.getParameter("interesting") checkbox 只能獲取 第一個被選中的
String interesting = request.getParameter("interesting");
System.out.println("request.getParameter(\"interesting\")的值:" + interesting);
//獲取checkbox 全部被選中的值
String[] intreastinges = request.getParameterValues("interesting");
for (String str : intreastinges) {
System.out.println(str);
}
//獲取全部請求參數
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = request.getParameter(name);
System.out.println(name + " =" + value);
}
Map<String, String[]> map = request.getParameterMap();
for (Map.Entry<String, String[]> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + Arrays.asList(entry.getValue()));
}
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String requestURI = httpServletRequest.getRequestURI();
System.out.println(requestURI);
//獲取請求參數對應的那個字符串, 即 ? 後的那個字符串
String queryString = httpServletRequest.getQueryString();
System.out.println(queryString);
//獲取請求的 Serlvet 的映射路徑
String servletPath = httpServletRequest.getServletPath();
System.out.println(servletPath);
//獲取web項目的根路徑
String contextPath = httpServletRequest.getContextPath();
System.out.println(contextPath);
PrintWriter writer = response.getWriter();
writer.println("helloworld");
}
}
servlet理論上可以處理多種形式的請求響應形式
http只是其中之一
所以HttpServletRequest、 HttpServletResponse分別是ServletRequest和ServletResponse的子類
參考閱讀:
==========
HttpServletRequest和ServletRequest都是接口
HttpServletRequest繼承自ServletRequest
HttpServletRequest比ServletRequest多了一些針對於Http協議的方法。
如
getHeader(String name),
getMethod() ,
getSession()
等等。
他們對應的實現類:
javax.servlet.ServletRequestWrapper (implements javax.servlet.ServletRequest)
javax.servlet.http.HttpServletRequestWrapper (implements javax.servlet.http.HttpServletRequest)