一、Servlet 1. 什麼是Servlet Servlet 是 JavaEE 規範之一,規範就是介面 Servlet 就 JavaWeb 三大組件之一,三大組件分別是:Servlet 程式、Filter 過濾器、Listener 監聽器 Servlet 是運行在伺服器上的一個 java 小程式, ...
一、Servlet
1. 什麼是Servlet
- Servlet 是 JavaEE 規範之一,規範就是介面
- Servlet 就 JavaWeb 三大組件之一,三大組件分別是:Servlet 程式、Filter 過濾器、Listener 監聽器
- Servlet 是運行在伺服器上的一個 java 小程式,它可以接收客戶端發送過來的請求,並響應數據給客戶端
2. 手動實現Servlet程式
首先還是在IDEA中創建一個對應的模塊,具體看上一個,結果如下
- 編寫一個類去實現 Servlet 介面
- 實現 service 方法,處理請求,並響應數據
- 到 web.xml 中去配置 servlet 程式的訪問地址
1. 首先在src下建立一個java文件,實現Servlet介面,重寫方法
現在先看Servlet(),其他的省略
package com.md.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author MD
* @create 2020-07-24 14:44
*/
public class HelloServlet implements Servlet {
/**
* service方法專門用來處理請求和響應的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Service方法");
}
}
2. web.xml中進行配置,具體參數如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--servlet標簽給Tomcat配置Servlet程式-->
<servlet>
<!--給servlet程式起一個別名,通常是類名-->
<servlet-name>HelloServlet</servlet-name>
<!--servlet程式全類名-->
<servlet-class>com.md.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping標簽給servlet程式配置訪問地址-->
<servlet-mapping>
<!--servlet-name 作用是告訴伺服器,當前配置的地址給那個Servlet程式使用-->
<servlet-name>HelloServlet</servlet-name>
<!-- 配置訪問的地址 http://ip:port/hello , 可以自定義-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
當訪問地址http://localhost:8080/hello時,可以看到輸出語句了
3. url地址到Servlet程式
4. Servlet的聲明周期
- 執行 Servlet 構造器方法
- 執行 init 初始化方法
第一、二步,是在第一次訪問的時候創建 Servlet 程式會調用
- 執行 service 方法 每次訪問都會調用
- 執行 destroy 銷毀方法 在 web 工程停止的時候調用
package com.md.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author MD
* @create 2020-07-24 14:44
*/
public class HelloServlet implements Servlet {
public HelloServlet() {
System.out.println("1 構造器方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init初始化方法");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* service方法專門用來處理請求和響應的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3. service方法");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("4 destroy銷毀方法");
}
}
// 結果如下:
//1 構造器方法
//2 init初始化方法 只有第一次訪問執行
//3. service方法
//3. service方法 每次刷新都會執行這個方法
//4 destroy銷毀方法 關閉Tomcat會執行這個方法
4. GET 和 POST 請求的分發處理
此時請求的話無論執行get或者是post請求都會執行service()方法,這樣不方便,所以做瞭如下的改進,
其他方法省略,主要看service()
public class HelloServlet implements Servlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3. service方法");
// 1. 類型轉換
HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
// 2. 獲取請求的方式
String method = httpServletRequest.getMethod();
// 3. 處理不同的請求
if ("GET".equals(method)){
doGet();
}else if ("POST".equals(method)){
doPost();
}
}
/**
* 做get請求的操作
*/
public void doGet(){
System.out.println("get請求正在操作");
}
/**
* 做post請求的操作
*/
public void doPost(){
System.out.println("post請求正在操作");
}
}
5. 通過繼承 HttpServlet 實現 Servlet 程式
一般在實際項目開發中,都是使用繼承 HttpServlet 類的方式去實現 Servlet 程式
- 編寫一個類去繼承 HttpServlet 類
- 根據業務需要重寫 doGet 或 doPost 方法
- 到 web.xml 中的配置 Servlet 程式的訪問地址
Servle類中的代碼
package com.md.servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author MD
* @create 2020-07-24 15:25
*/
public class HelloServlet2 extends HttpServlet {
/**
* get請求時調用
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 --- get");
}
/**
* post請求時調用
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet2 --- post");
}
}
在web.xml中的配置
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.md.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
6. 使用IDEA創建Servlet程式
方便,快捷
配置Servlet信息
最後在web.xml中添加信息就可以了
<servlet>
<servlet-name>HelloServlet3</servlet-name>
<servlet-class>com.md.servlet.HelloServlet3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet3</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
7. Servlet類的繼承體系
二、ServletConfig類
ServletConfig 是 Servlet 程式的配置信息類
Servlet 程式和 ServletConfig 對象都是由 Tomcat 負責創建,我們負責使用
Servlet 程式預設是第一次訪問的時候創建,ServletConfig 是每個 Servlet 程式創建時,就創建一個對應的 ServletConfig 對象
1. ServletConfig 類的三大作用
- 可以獲取 Servlet 程式的別名 servlet-name 的值
- 獲取初始化參數 init-param
- 獲取 ServletContext 對象
首先還是在web.xml中進行配置
<!--servlet標簽給Tomcat配置Servlet程式-->
<servlet>
<!--給servlet程式起一個別名,通常是類名-->
<servlet-name>HelloServlet</servlet-name>
<!--servlet程式全類名-->
<servlet-class>com.md.servlet.HelloServlet</servlet-class>
<!--初始化參數-->
<init-param>
<!--參數名-->
<param-name>url</param-name>
<!--參數值-->
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
<!--可以配置多個-->
<init-param>
<!--參數名-->
<param-name>username</param-name>
<!--參數值-->
<param-value>root</param-value>
</init-param>
</servlet>
<!--servlet-mapping標簽給servlet程式配置訪問地址-->
<servlet-mapping>
<!--servlet-name 作用是告訴伺服器,當前配置的地址給那個Servlet程式使用-->
<servlet-name>HelloServlet</servlet-name>
<!-- 配置訪問的地址 http://ip:port/hello , 可以自定義-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
Servlet中的代碼:
其他方法就省略了,主要看這個就行,啟動Tomcat之後在地址欄輸入地址http://localhost:8080/hello時,可以看到輸出語句了,
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init初始化方法");
// 1. 可以獲取Servlet程式的別名servlet-name的值
System.out.println("HelloServlet的別名是:"+servletConfig.getServletName());
//HelloServlet的別名是:HelloServlet
// 2. 獲取初始化參數init-param
System.out.println("初始化參數url:"+servletConfig.getInitParameter("url"));
//初始化參數url:jdbc:mysql://localhost:3306/test
System.out.println("初始化參數username:"+servletConfig.getInitParameter("username"));
//初始化參數username:root
// 3. 獲取ServletContext對象
System.out.println(servletConfig.getServletContext());
//org.apache.catalina.core.ApplicationContextFacade@521f9e31
}
註意:
重寫init方法裡面一定要調用父類的init(config)操作
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("重寫的init方法");
}
三、ServletContext 類
1. 什麼是 ServletContext?
- ServletContext 是一個介面,它表示 Servlet 上下文對象
- 一個 web 工程,只有一個 ServletContext 對象實例
- ServletContext 對象是一個域對象
- ServletContext 是在 web 工程部署啟動的時候創建。在 web 工程停止的時候銷毀
什麼是域對象?
域對象,是可以像 Map 一樣存取數據的對象,叫域對象。
這裡的域指的是存取數據的操作範圍,整個 web 工程
存數據 | 取數據 | 刪除數據 | |
---|---|---|---|
Map | put() | get() | remove() |
域對象 | setAttribute() | getAttribute() | removeAttribute() |
2. ServletContext 類的四個作用
- 獲取 web.xml 中配置的上下文參數 context-param
- 獲取當前的工程路徑,格式:/工程路徑
- 獲取工程部署後在伺服器硬碟上的絕對路徑
- 像 Map 一樣存取數據
在ContextServlet類中,
package com.md.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author MD
* @create 2020-07-24 16:17
*/
public class ContextServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 獲取web.xml中配置的上下文參數
ServletContext context = getServletConfig().getServletContext();
String username = context.getInitParameter("username");
System.out.println("context-param中參數username的值為:"+username);
System.out.println("context-param中參數pwd的值為:"+context.getInitParameter("pwd"));
// 2. 獲取當前工程的路徑
System.out.println("當前工程的路徑:"+context.getContextPath());
// 3. 獲取工程部署後在伺服器磁碟上的絕對路徑,映射到IDEA代碼的web目錄,
// 相當於直接到了web目錄那,如果使用web目錄下的其他文件,直接/目錄名就可以
System.out.println("工程部署路徑:"+context.getRealPath("/"));
// 工程的絕對路徑:E:\Java\code\JavaWeb\out\artifacts\03_web_war_exploded\
// 比如web下有css目錄和imgs目錄
System.out.println(context.getRealPath("/css"));
System.out.println(context.getRealPath("/imgs/1.jpg"));
}
}
對應的配置文件web.xml
這個是直接在<web-app標簽下,而不是某個<servlet標簽下,
<!--context-param 是上下文參數,屬於整個的Web工程-->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<context-param>
<param-name>pwd</param-name>
<param-value>123456</param-value>
</context-param>
<servlet>
<servlet-name>ContextServlet</servlet-name>
<servlet-class>com.md.servlet.ContextServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServlet</servlet-name>
<url-pattern>/context</url-pattern>
</servlet-mapping>
ServletContext 像Map一樣存取數據,直接可以這樣
在ContextServlet1中,這個對應的web.xml就省略了
package com.md.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author MD
* @create 2020-07-24 16:40
*/
public class ContextServlet1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 通過getServletContext()直接獲取ServletContext對象
ServletContext context = getServletContext();
System.out.println("保存前:"+context.getAttribute("key1")); // null
// 2. 設置值
context.setAttribute("key1","value1");
// 3. 獲取值
System.out.println("保存後:"+context.getAttribute("key1")); //value1
//
}
}
也可以在不同的Service中獲取的到,因為是域對象
這個是整個web都可以獲取到這個值,通過ContextServlet2也是可以獲取到的
public class ContextServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 由於context是域對象,整個web只有一個,所以這個獲取的和ContextServlet1里的是同一個
ServletContext context = getServletContext();
// 只要ContextServlet1運行過,設置過這個值,那麼這個就可以獲取到值
System.out.println(context.getAttribute("key1")); //value1
}
}