課時1 Servlet是什麼
Servlet作用是處理請求
接收請求
處理請求
完成響應
課時2 實作Servlet方式
依賴
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
實作方式
// 實作接口:
javax.servlet.Servlet
// 繼承類:
javax.servlet.GenericServlet
// 繼承類:
javax.servlet.HttpServlet
繼承示例
AServlet.java
import javax.servlet.*;
import java.io.IOException;
public class AServlet implements Servlet{
// 建立時執行
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
// 擷取配置資訊
@Override
public ServletConfig getServletConfig() {
return null;
}
// 處理請求
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
// 擷取servlet資訊
@Override
public String getServletInfo() {
return null;
}
// 銷毀前調用
@Override
public void destroy() {
}
}
課時3 Servlet的生命周期
生命周期
init 執行個體化調用
service 每次處理請求都調用
destroy 銷毀調用
特性
(1)單例,每個類隻有一個對象
(2)線程不安全,效率最高
Servlet類由使用者自定義,對象由伺服器來建立,并有伺服器調用對應的方法
浏覽器通路Servlet
給Servlet配置一個路徑
web.xml
<?xml version="1.0" encoding="utf-8" ?>
<web-app>
<!-- 注冊 Servlet,幫助web伺服器反射該類 -->
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>AServlet</servlet-class>
</servlet>
<!-- 映射 Servlet 資源,用url-pattern元素标示 URL -->
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>demo</url-pattern>
</servlet-mapping>
</web-app>
目錄結構
webapp
└── WEB-INF
├── classes
│ └── AServlet.class
└── web.xml
課時4 ServletConfig介紹
interface ServletConfig{
// 擷取servlet-name中的内容
String getServletName()
// 擷取Servlet上下文對象
ServletContext getServletContext()
// 擷取指定初始化參數值
String getInitParameter(String name)
// 擷取所有初始化參數值
Enumeration<String> getInitParameterNames()
}
<servlet>
<init-param>
<param-name>name</param-name>
<param-value>Tom</param-value>
</init-param>
</servlet>
擷取參數
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(servletConfig.getInitParameter("name"));
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(servletConfig.getInitParameter("name"));
}
課時5 ServletRequest和Servletresponse對象
interface ServletRequest;
interface ServletResponse;
課時6 GenericServlet介紹
GenericServlet可以隻覆寫service方法,不用全寫
基本原理
import javax.servlet.*;
import java.io.IOException;
public class AServlet implements Servlet {
private ServletConfig config = null;
@Override
public void init(ServletConfig servletConfig) {
this.config = servletConfig;
this.init();
}
// 實作此方法,初始化後可以調用
public void init() {
}
@Override
public ServletConfig getServletConfig() {
return this.config;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
使用示例
import javax.servlet.*;
import java.io.IOException;
public class AServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
servletResponse.getWriter().write("<h2>hello<h2>");
}
}
課時7 HttpServlet介紹
源碼
package javax.servlet.http;
public abstract class HttpServlet extends GenericServlet {
// 重寫
protected void doGet(HttpServletRequest req, HttpServletResponse resp);
// 重寫
protected void doPost(HttpServletRequest req, HttpServletResponse resp);
protected void service(HttpServletRequest req, HttpServletResponse resp);
public void service(ServletRequest req, ServletResponse res){
if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
this.service(request, response);
} else {
throw new ServletException("non-HTTP request or response");
}
}
}
使用示例: 接收GET請求
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("<h2>hello</h2>");
}
}
課時8 Servlet的細節
1、非線程安全
一個Servlet類隻有一個執行個體對象,不是線程安全的,工作效率高
(1)不要在Servlet中建立成員,建立局部變量即可
(2)可以建立無狀态成員
(3)可以建立有狀态的成員,但是狀态必須為隻讀
2、建立時啟動
預設情況下,伺服器會在第一次通路Servlet時建立執行個體對象
給load-on-startup設定一個非負整數
正數的值越小,啟動該servlet的優先級越高
可以配置建立時啟動
<servlet>
<servlet-name>servletName</servlet-name>
<load-on-startup>0</load-on-startup>
</servlet>
3、url-pattern
可以有多個通路路徑
可以使用字首或者字尾通配符
*
<servlet>
<servlet-name>servletName</servlet-name>
<!-- 字尾比對 -->
<url-pattern>/demo/*</url-pattern>
<!-- 字首比對 -->
<url-pattern>*.do</url-pattern>
<!-- 比對所有url -->
<url-pattern>/*</url-pattern>
</servlet>
課時9 在conf下的web.xml檔案内容介紹
${CATALINA_HOME}/conf/web.xml
<!-- 優先級最低 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 過期時間30分鐘 -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- 類型映射 -->
<mime-mapping>
<extension>xml</extension>
<mime-type>application/xml</mime-type>
</mime-mapping>
課時10 Servlet與反射
Servlet通過反射,擷取配置檔案的類名,進行執行個體化和方法調用
課時11 ServletContext概述
一個項目隻有一個ServletContext對象
可以在多個Servlet中傳遞對象
Tomcat啟動時建立,關閉時銷毀
課時12 擷取ServletContext對象
擷取ServletContext
class ServeletConfig{
ServletContext getServletContext();
}
class GenericServlet{
ServletContext getServletContext();
}
課時13 示範ServletContext
域對象: 在多個Servlet中傳遞資料
class ServletContext{
// 設定 多次調用會覆寫
void setAttribute(String name, Object vlaue);
// 擷取
Object getAttribute(String name);
// 移除
void removeAttribute(String name);
// 擷取全部屬性名稱
Enumeration getAttributeNames();
}
例如: AServlet的資料可以傳遞到BServlet
package com.pengshiyu;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String name = request.getParameter("name");
ServletContext context = getServletContext();
context.setAttribute("name", name);
response.getWriter().write("<h2>" + name +"</h2>");
}
}
package com.pengshiyu;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletContext context = getServletContext();
String name = (String)context.getAttribute("name");
response.getWriter().println(name);
}
}
課時14 ServletContext擷取公共的初始化參數
Servlet隻能擷取自己的初始化參數
ServletContext擷取公共的初始化參數
<web-app>
<context-param>
<param-name>key</param-name>
<param-value>value</param-value>
</context-param>
</web-app>
package com.pengshiyu;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletContext context = getServletContext();
String name = context.getInitParameter("key");
response.getWriter().println(name);
}
}
課時15 ServletContext擷取資源相關方法
以webapp文根目錄
ServletContext context = getServletContext();
// 擷取絕對路徑
String path = context.getRealPath("/index.html");
// 擷取檔案後轉為輸入流
InputStream in = context.getResourceAsStream("/index.html");
// 擷取目錄下的檔案
Set<String> set = context.getResourcePaths("/");
// [/hello.html, /WEB-INF/]
課時16 網站通路量統計小案例
使用ServletContext對象共享統計資料
package com.pengshiyu;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletContext context = getServletContext();
Integer count = (Integer) context.getAttribute("count");
if (count == null) {
count = 1; // 第一次通路
} else {
count++;
}
response.setContentType("text/html; charset=UTF-8");
response.getWriter().println("<h2>第"+count+"次通路</h2>");
context.setAttribute("count", count);
}
}
課時17 擷取類路徑下的資源
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
代碼執行個體
package com.pengshiyu;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
public class Demo {
public static void main(String[] args) throws IOException {
Class<Demo> clazz = Demo.class;
// 1、相對于.class所在目錄
InputStream input1 = clazz.getResourceAsStream("1.txt");
System.out.println(IOUtils.toString(input1, StandardCharsets.UTF_8));
// 2、相對于/classes
InputStream input2 = clazz.getResourceAsStream("/2.txt");
System.out.println(IOUtils.toString(input2, StandardCharsets.UTF_8));
ClassLoader loader = clazz.getClassLoader();
// 3、相對于/classes
InputStream input3 = loader.getResourceAsStream("3.txt");
System.out.println(IOUtils.toString(input3, StandardCharsets.UTF_8));
}
}
課時18 BaseServlet
一個Servlet中可以有多個請求處理方法
BaseServlet.java
package com.pengshiyu;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String methodName = req.getParameter("method");
if(methodName == null || methodName.trim().isEmpty()){
throw new RuntimeException("method is null or empty");
}
System.out.println(methodName);
// 通過參數擷取方法
Class clazz = this.getClass();
Method method = null;
try {
method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException("方法擷取失敗");
}
// 調用方法
try {
method.invoke(this, req, resp);
} catch (Exception e) {
throw new RuntimeException("調用失敗");
}
}
}
package com.pengshiyu;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends BaseServlet {
public void getAge(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().print("getAge");
}
public void getName(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().print("getName");
}
}
調用時傳入查詢參數
http://localhost:8080/demo/hello?method=getAge