首頁>技術>

一、簡介

最近看原始碼,涉及servlet這一塊。藉此對servlet及相關原始碼等知識進行回顧和介紹。通常說的servlet開發其實是一種開發動態網頁的解決方案,它包含實現javax.servlet.Servlet介面的servlet程式和解析servlet程式的servlet引擎(即是servlet容器,如tomcat等)。servlet程式是在伺服器端執行的。

二、servlet結構

一個servlet是一個在web伺服器執行的小程式。

2.1 servlet依賴包

servlet開發依賴包為javax.servlet-api.jar,通常servlet容器中會有(如tomcat),因此打包一般在編譯器使用。

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>javax.servlet-api</artifactId>

<version>3.1.0</version>

<scope>compile</scope>

</dependency>

2.2 servlet流程

graph TB

request -->|請求| servletContainer(servlet容器/引擎)

servletContainer -->|呼叫| servletApi(servlet api)

servlet程式 -->|實現| servletApi

servlet引擎和servlet程式透過servlet api通訊,流程為:servlet程式實現servlet api介面,外界請求到servlet容器時,servlet容器透過servlet引擎,呼叫servlet api,實現對servlet程式的呼叫。

2.3 servlet註冊

servlet程式是在web.xml中註冊的,包含servlet名稱、servlet實現類、servlet請求地址,格式如下

<servlet>

<servlet-name>servletName</servlet-name>

<servlet-class>servlet實現類</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>servletName</servlet-name>

<url-pattern>servlet匹配地址</url-pattern>

</servlet-mapping>

2.3.1 servlet註冊位置

通常servlet是在應用程式的web.xml中註冊,但其實在servlet容器中(如tomcat), 在conf/web.xml還有個全域性的註冊(所有應用程式均可使用,控制全域性的跳轉)。

2.3.2 servlet匹配地址

servlet請求地址可以是固定的一個,也可採用萬用字元來匹配多個地址,不過採用萬用字元只能有兩種格式:

*.副檔名,此時 *前面不能有分割符 / ,這種方式的匹配優先順序最低,如: *.html 匹配.html結尾的地址;

以分割符/開頭並以*結尾的,如: /stu/ *,匹配所有/stu/開頭的地址;

servlet匹配地址採用最具體原則,地址匹配越具體,越優先容易匹配,其中 *.副檔名 模式的匹配優先順序最低。

2.3.3 預設servlet

預設servlet位於servlet容器中的conf/web.xml中,如果servlet匹配地址為/,則該servlet為預設servlet,當外界請求地址找不到servlet匹配地址時,就會走預設servlet。通常訪問靜態資源(如圖片、html等)時,走的就是預設servlet,即此時不在需要單獨配置servlet。

<servlet>

<servlet-name>default</servlet-name>

<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>default</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

2.4 servlet類載入

servlet類載入並非完全的雙親委派模式,略有不同,改為當前類載入器優先,目的是對不同web應用間相互隔離(比如不同web應用依賴不同版本的同類jar包,需要相互隔離),這裡以tomcat中類載入為例,其類載入器有:

graph BT

system --- bootstrap

common --- system

webapp1 --- common

webapp2 --- common

webappx --- common

2.4.1 bootstrap

bootstrap類載入器(包含jvm載入器和ExtClassLoader)用於載入jvm核心包(rt.jar)和系統擴充套件目錄下的包(<java_home>/jre/lib/ext)。

2.4.2 sytem

system類載入器(通常為AppClassLoader)載入classpath環境變數設定的指定目錄中的類。實際使用(tomcat啟動指令碼,$CATALINA_HOME/bin/catalina.sh)中會忽略原有環境變數的設定,而改為載入$CATALINA_HOME/bin/bootstrap.jar、$CATALINA_HOME/bin/tomcat-juli.jar、commons-daemon.jar等jar包。

2.4.3 cmmon

common類載入器載入tomcat內部類和所用webapp 共享的類($CATALINA_HOME/lib).

2.4.4 webapp

webapp類載入器用於載入當前webapp應用程式下的/Web-INF/classes和/Web-INF/lib目錄中的class檔案和jar包。webapp類載入器僅對當前web應用程式可見。

2.4.5 完整類載入流程

當有類載入需求時,優先在當前應用程式的webapp類載入器載入,若沒有,再使用雙親委派,委託common類載入器,commont類載入器接著委託system類載入器,若system類載入器失敗,才由common類載入器載入,若common類載入器還是載入失敗,則拋異常。

2.5 servlet生命週期

2.5.1 servlet初始化

一個servlet在其生命週期中只會初始化一次,同一個servlet也只會有一個例項。但servlet內的service(HttpServletRequest req, HttpServletResponse resp)方法會被多次呼叫,每次請求會新生成HttpServletRequest和HttpServletResponse例項。同一個servlet只有一個servlet物件,因此需要注意多執行緒安全問題。

2.5.2 servlet建立多個例項

servlet實現javax.servlet.SingleThreadModel介面後,可建立多個servlet例項(構成servlet例項池,每次請求使用一個)來處理請求,此時每個請求單獨對用一個servlet例項(顯然不存在併發引起的問題),當然該介面已經標記為@deprecated(過時),不在推薦使用,而推薦使用多執行緒同步來處理問題。使用示例如下:

import javax.servlet.SingleThreadModel;

import javax.servlet.http.HttpServlet;

public class SingleServlet extends HttpServlet implements SingleThreadModel {

}

三、servlet主要類

servlet主要類圖如下:

接下來將分別介紹。

3.1 ServletContext類

每個web應用程式都是一個獨立的Servlet容器,都有一個ServletContext物件。ServletContext定義了一組和servlet容器通訊的方法(比如獲取servlet容器初始化引數,這樣就不需要在應用程式中寫死,而是一個變數),ServletContext物件存在於ServletConfig物件中,當每個Servlet初始化時,ServletContext會隨著ServletConfig提供給每個Servlet。

package javax.servlet;

import java.io.InputStream;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.Enumeration;

import java.util.EnumSet;

import java.util.EventListener;

import java.util.Map;

import java.util.Set;

import javax.servlet.descriptor.JspConfigDescriptor;

//ServletContext定義了一組和servlet容器通訊的方法,每個web應用程式都有獨立的ServletContext,

//在每個Servlet初始化時,會隨著ServletConfig提供給每個Servlet

public interface ServletContext {

//返回web應用程式的context路徑,也就是在<tomcat_home>/conf/server.xml中context元素path的值

public String getContextPath();

//返回指定路徑(容器中其他web應用程式的ServletContext,路徑必須以/開頭)的ServletContext,沒有或沒許可權則返回null

public ServletContext getContext(String uripath);

//返回Servlet api的主版本,如3.0則返回3

public int getMajorVersion();

//返回Servlet api的次版本,如3.0則返回0

public int getMinorVersion();

//返回servlet容器支援的servlet主版本

public int getEffectiveMajorVersion();

//返回servlet容器支援的servlet次版本

public int getEffectiveMinorVersion();

//返回指定檔案的mime型別(如text/html、image/gif)

public String getMimeType(String file);

//返回指定路徑下的所有資源地址(檔案或目錄,不遞迴獲取)

public Set<String> getResourcePaths(String path);

//返回給定地址的url,地址必須以/開頭並會被解析為相對當前context root路徑, 或者

public URL getResource(String path) throws MalformedURLException;

//返回指定資源的InputStream

public InputStream getResourceAsStream(String path);

//返回RequestDispatcher物件,作為對給定路徑資源的包裝。

//RequestDispatcher可用於forward請求或者在response響應中包含動態或靜態資源

public RequestDispatcher getRequestDispatcher(String path);

//返回作為對給定名稱servlet包裝的RequestDispatcher

public RequestDispatcher getNamedDispatcher(String name);

//在servlet日誌檔案中記錄資訊

public void log(String msg);

//在servlet日誌檔案中記錄資訊,包含堆疊資訊

public void log(String message, Throwable throwable);

//返回給定虛擬地址的真實完整地址,如:/index.html返回http://localhost:8080/index.html

public String getRealPath(String path);

//返回執行的servlet的servlet容器名稱和版本資訊

public String getServerInfo();

//返回指定名稱的context初始化引數

public String getInitParameter(String name);

//返回context初始化引數名稱集合

public Enumeration<String> getInitParameterNames();

//在ServletContext中設定context初始化引數,若已經存在指定名稱的context初始化引數,則失敗,返回false(@since Servlet 3.0)

public boolean setInitParameter(String name, String value);

//返回在servlet容器中給定名稱的屬性值

public Object getAttribute(String name);

//返回ServletContest中屬性名稱集合

public Enumeration<String> getAttributeNames();

//在ServletContext中設定屬性值,如果已經存在則覆蓋

public void setAttribute(String name, Object object);

//在ServletContext中移除屬性

public void removeAttribute(String name);

//返回應用名稱,即display-name值

public String getServletContextName();

//在ServletContext中新增servlet(@since Servlet 3.0)

public ServletRegistration.Dynamic addServlet(

String servletName, String className);

//在ServletContext中新增servlet例項(@since Servlet 3.0)

public ServletRegistration.Dynamic addServlet(

String servletName, Servlet servlet);

//在ServletContext中新增servlet(@since Servlet 3.0)

public ServletRegistration.Dynamic addServlet(String servletName,

Class <? extends Servlet> servletClass);

//根據類例項例項化servlet

public <T extends Servlet> T createServlet(Class<T> clazz)

throws ServletException;

//獲取指定名稱的servlet註冊資訊ServletRegistration(@since Servlet 3.0)

public ServletRegistration getServletRegistration(String servletName);

//以map形式獲取所有ServletRegistration物件

public Map<String, ? extends ServletRegistration> getServletRegistrations();

//在servlet context中新增Filter(@since Servlet 3.0)

public FilterRegistration.Dynamic addFilter(

String filterName, String className);

//在servlet context中新增Filter例項(@since Servlet 3.0)

public FilterRegistration.Dynamic addFilter(

String filterName, Filter filter);

//在servlet context中新增Filter(@since Servlet 3.0)

public FilterRegistration.Dynamic addFilter(String filterName,

Class <? extends Filter> filterClass);

//根據類例項例項化Filter

public <T extends Filter> T createFilter(Class<T> clazz)

throws ServletException;

//返回給定名稱的Filter註冊資訊FilterRegistration (@since Servlet 3.0)

public FilterRegistration getFilterRegistration(String filterName);

//以map形式返回所用的Filter註冊資訊FilterRegistration (@since Servlet 3.0)

public Map<String, ? extends FilterRegistration> getFilterRegistrations();

//返回SessionCookieConfig物件

public SessionCookieConfig getSessionCookieConfig();

//設定session跟蹤方式(@since Servlet 3.0)

public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes);

//返回預設session跟蹤方式(@since Servlet 3.0)

public Set<SessionTrackingMode> getDefaultSessionTrackingModes();

//返回有效的session跟蹤方式(@since Servlet 3.0)

public Set<SessionTrackingMode> getEffectiveSessionTrackingModes();

//新增監聽器EventListener

public void addListener(String className);

//新增監聽器EventListener

public <T extends EventListener> void addListener(T t);

//新增監聽器EventListener

public void addListener(Class <? extends EventListener> listenerClass);

//根據類名例項化監聽器EventListener

public <T extends EventListener> T createListener(Class<T> clazz)

throws ServletException;

//獲取在web.xml和web-fragment.xml中的jsp config

public JspConfigDescriptor getJspConfigDescriptor();

//獲取載入ServletContext的類載入器

public ClassLoader getClassLoader();

//宣告角色(在isUserInRole使用)

public void declareRoles(String... roleNames);

//獲取ServletContext部署在邏輯主機上的配置的名稱

public String getVirtualServerName();

}

3.2 ServletConfig介面

ServletConfig為servlet配置物件,用於在servlet容器初始化servlet時傳遞資訊。介面定義如下:

package javax.servlet;

import java.util.Enumeration;

//servlet配置物件,用於在servlet容器初始化servlet時傳遞資訊

public interface ServletConfig {

//返回當前servlet例項的名稱

public String getServletName();

//返回ServletContext的引用

public ServletContext getServletContext();

//返回ServletContext的引用

public String getInitParameter(String name);

//返回當前servlet例項所有的初始化引數名稱

public Enumeration<String> getInitParameterNames();

}

示例(僅列出關鍵程式碼): web.xml中servlet配置如下:

<servlet>

<servlet-name>stuServlet</servlet-name>

<servlet-class>servlet.StuServlet</servlet-class>

<init-param>

<param-name>stuId</param-name>

<param-value>001</param-value>

</init-param>

<init-param>

<param-name>stuName</param-name>

<param-value>apple</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>stuServlet</servlet-name>

<url-pattern>/stuServlet</url-pattern>

</servlet-mapping>

StuServlet.java

package servlet;

import javax.servlet.ServletConfig;

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;

import java.util.Enumeration;

public class StuServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

/**************** ServletConfig ******************/

ServletConfig servletConfig = getServletConfig();

//返回當前servlet例項的名稱

String servletName = servletConfig.getServletName(); //stuServlet

//返回ServletContext的引用

ServletContext servletContextFromConfig = servletConfig.getServletContext();

//返回當前servlet例項指定名稱的初始化引數值

String stuId = servletConfig.getInitParameter("stuId"); //001

//返回當前servlet例項所有的初始化引數名稱

Enumeration<String> initParamNames = servletConfig.getInitParameterNames(); //stuId,stuName

}

}

3.3 Servlet介面

servlet是在web server端執行的java小程式,是所有Servlet需要實現的介面,定義了所有servlet必須實現的方法,方法包含服務請求、從服務中移除servlet以及servlet的整個生命週期(init、service、destroy)。接收和響應來自web客戶端的請求。介面定義如下:

package javax.servlet;

import java.io.IOException;

//Servlet介面定義了所有Servlet必須實現的方法

public interface Servlet {

//servlet初始化時呼叫的初始化方法,只會被呼叫一次,且在接收任意請求前完成初始化

public void init(ServletConfig config) throws ServletException;

//返回ServletConfig的引用

public ServletConfig getServletConfig();

//由servlet容器呼叫,對請求進行響應,需要注意多執行緒呼叫的情況(對臨界資源的訪問)

public void service(ServletRequest req, ServletResponse res)

throws ServletException, IOException;

public String getServletInfo();

//servlet容器呼叫,表示從容器中移除servlet,只會被呼叫一次,,此時呼叫service方法的所有執行緒都退出或超時了

public void destroy();

}

3.4 GenericServlet抽象類

GenericServlet抽象類是對Servlet介面和ServletConfig介面的預設實現,類定義如下:

public abstract class GenericServlet

implements Servlet, ServletConfig, java.io.Serializable

{

//具體實現方法在此略過,同實現介面一樣

}

3.5 HttpServlet類

HttpServlet提供了抽象類,用於子類建立http servlet。同時子類必須重寫doGet、doPost、doPut、doDelete、init、destory中至少一個方法,用於管理servlet生命週期中持有的資源。通常不需要重寫public service方法,對於doOption和doTrace方法也不需要重寫。servlet通常在多執行緒中執行,需要考慮臨界資源的同步訪問。HttpServlet類定義如下:

package javax.servlet.http;

import java.io.IOException;

import java.io.PrintWriter;

import java.io.OutputStreamWriter;

import java.io.UnsupportedEncodingException;

import java.lang.reflect.Method;

import java.text.MessageFormat;

import java.util.Enumeration;

import java.util.Locale;

import java.util.ResourceBundle;

import javax.servlet.*;

//HttpServlet提供了抽象類,用於子類建立http servlet

public abstract class HttpServlet extends GenericServlet

{

//由server(透過service方法呼叫)呼叫,用於處理get請求(也支援head請求)。使用時需要重寫該方法

protected void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException{}

//返回HttpServletRequest物件最近修改時間,時間為子1970年1月1日到現在的毫秒數。如果不知道,則返回負數

protected long getLastModified(HttpServletRequest req) {}

//接收來自service方法的head請求並處理(重寫只需要設定response headers)

protected void doHead(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException{}

//由server(透過service方法呼叫)呼叫,用於處理post請求。可一次性發送無長度限制的資料

protected void doPost(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException{}

//由server(透過service方法呼叫)呼叫,用於處理put請求。客戶端可放置檔案到伺服器

protected void doPut(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException{}

protected void doDelete(HttpServletRequest req,

HttpServletResponse resp)

throws ServletException, IOException{}

//由server(透過service方法呼叫)呼叫,用於處理option請求

protected void doOptions(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException{}

//由server(透過service方法呼叫)呼叫,用於處理trace請求。通常用於debug

protected void doTrace(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException{}

//接收來自公開方法service(ServletRequest req, ServletResponse res)的請求,並分發給doXX方法處理

protected void service(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

{

String method = req.getMethod();

if (method.equals(METHOD_GET)) {

long lastModified = getLastModified(req);

if (lastModified == -1) {

// servlet doesn't support if-modified-since, no reason

// to go through further expensive logic

doGet(req, resp);

} else {

long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);

if (ifModifiedSince < lastModified) {

// If the servlet mod time is later, call doGet()

// Round down to the nearest second for a proper compare

// A ifModifiedSince of -1 will always be less

maybeSetLastModified(resp, lastModified);

doGet(req, resp);

} else {

resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);

}

}

} else if (method.equals(METHOD_HEAD)) {

long lastModified = getLastModified(req);

maybeSetLastModified(resp, lastModified);

doHead(req, resp);

} else if (method.equals(METHOD_POST)) {

doPost(req, resp);

} else if (method.equals(METHOD_PUT)) {

doPut(req, resp);

} else if (method.equals(METHOD_DELETE)) {

doDelete(req, resp);

} else if (method.equals(METHOD_OPTIONS)) {

doOptions(req,resp);

} else if (method.equals(METHOD_TRACE)) {

doTrace(req,resp);

} else {

//

// Note that this means NO servlet supports whatever

// method was requested, anywhere on this server.

//

String errMsg = lStrings.getString("http.method_not_implemented");

Object[] errArgs = new Object[1];

errArgs[0] = method;

errMsg = MessageFormat.format(errMsg, errArgs);

resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);

}

}

//將請求發給protected service處理,通常該方法不需要重寫

@Override

public void service(ServletRequest req, ServletResponse res)

throws ServletException, IOException{}

}

3.6 ServletRequest介面

ServletRequest介面定義了一個包含使用者請求資訊的物件給servlet的service方法。ServletRequest提供的資料包括引數名稱和值、屬性、輸入流。介面定義如下:

package javax.servlet;

import java.io.*;

import java.util.*;

//定義了一個包含使用者請求資訊的物件給servlet的service方法。ServletRequest提供的資料包括引數名稱和值、屬性、輸入流

public interface ServletRequest {

//獲取屬性資訊,沒有則返回null

public Object getAttribute(String name);

//返回屬性名稱集合

public Enumeration<String> getAttributeNames();

//返回請求body的字元編碼,如果沒有指定則返回null

public String getCharacterEncoding();

//設定請求body的字元編碼,且設定必須在讀取引數或讀取使用getReader()操作前,否則不生效

public void setCharacterEncoding(String env) throws UnsupportedEncodingException;

//返回請求body的位元組長度,或者當長度不確定或超出了int的最大長度,則返回-1

public int getContentLength();

//返回請求body的位元組長度,或者當長度不確定,則返回-1

public long getContentLengthLong();

//返回請求body的mine type,如果不確定,則返回null

public String getContentType();

//獲取請求bode的資料二進位制流的ServletInputStream

public ServletInputStream getInputStream() throws IOException;

//返回指定引數的值,當引數有多個值時,則返回讀取到的第一個值。對於請求body中的資料,則不能使用該方法,應該使用getInputStream或getReader

public String getParameter(String name);

//返回引數名稱集合,沒有則返回空集合

public Enumeration<String> getParameterNames();

//返回指定引數的值陣列,沒有則返回null

public String[] getParameterValues(String name);

//返回引數map,key為引數名稱,value為引數值

public Map<String, String[]> getParameterMap();

//返回請求使用的協議版本號,如:HTTP/1.1

public String getProtocol();

//返回請求使用的schema,如:http、https、ftp

public String getScheme();

//返回請求傳送的伺服器主機名稱,即是Host頭中:前面值

public String getServerName();

//返回請求傳送的埠號,即是Host頭中:後面的值

public int getServerPort();

//以BufferedReader方式讀取請求體body中字元資料

public BufferedReader getReader() throws IOException;

//返回客戶端或最後一個發出請求的代理的ip

public String getRemoteAddr();

返回客戶端或最後發出請求的代理的完整合規的名稱

public String getRemoteHost();

//在request中設定屬性

public void setAttribute(String name, Object o);

//移除request中的屬性

public void removeAttribute(String name);

//返回客戶端將接收內容的方言(如zh_CN)

public Locale getLocale();

//返回客戶端將接收內容的方言集合(如zh_CN、zh)

public Enumeration<Locale> getLocales();

//請求是使用安全通道(如https)

public boolean isSecure();

//返回RequestDispatcher物件,它作為對給定路徑上資源的包裝,它可用於請求重定向或在相應中包含靜態或動態資源

public RequestDispatcher getRequestDispatcher(String path);

//返回客戶端或發請求的最後代理的埠號

public int getRemotePort();

//返回接收請求的介面的ip主機名(如:ip6-localhost)

public String getLocalName();

//返回接收請求的介面的ip地址

public String getLocalAddr();

//返回接收請求的介面的埠號

public int getLocalPort();

//獲取最後發出的ServletRequest的ServletContext

public ServletContext getServletContext();

//將請求轉為非同步模式,同時初始化它的AsyncContext(包含有ServletRequest和ServletResonse),並返回AsyncContext

public AsyncContext startAsync() throws IllegalStateException;

public AsyncContext startAsync(ServletRequest servletRequest,

ServletResponse servletResponse)

throws IllegalStateException;

//檢查請求是否已經裝為非同步模式

public boolean isAsyncStarted();

//檢查請求是否支援非同步模式

public boolean isAsyncSupported();

//獲取AsyncContext

public AsyncContext getAsyncContext();

//返回DispatcherType(如:REQUEST)

public DispatcherType getDispatcherType();

}

3.7 HttpServletRequest介面

HttpServletRequest繼承自ServletRequest介面,提供了關於http servlet請求資訊。介面定於如下:

package javax.servlet.http;

import java.io.IOException;

import java.util.*;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

//HttpServletRequest繼承自ServletRequest介面,提供了關於http servlet請求資訊。

public interface HttpServletRequest extends ServletRequest {

//基本驗證識別符號

public static final String BASIC_AUTH = "BASIC";

//表單驗證識別符號

public static final String FORM_AUTH = "FORM";

//客戶端驗證識別符號

public static final String CLIENT_CERT_AUTH = "CLIENT_CERT";

//驗證識別符號

public static final String DIGEST_AUTH = "DIGEST";

//返回用於保護servlet的驗證模式名稱,值為BASIC_AUTH,FORM_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH中之一或特別指定的值,沒有則返回null

public String getAuthType();

//返回當前請求客戶端傳送的所有Cookie物件組成的陣列

public Cookie[] getCookies();

//返回header值為時間的自1970年1月1日(GMT)至今的毫秒值(header如:If-Modified-Since),沒有則返回-1

public long getDateHeader(String name);

//返回指定header的值,沒有則返回null

public String getHeader(String name);

//返回指定header的值集合(有些相同header有多個不同值,如Accept-Language),沒有則返回null

public Enumeration<String> getHeaders(String name);

//返回所有header的名稱集合,沒有則返回null

public Enumeration<String> getHeaderNames();

//以int方式獲取header值,沒有則返回-1

public int getIntHeader(String name);

//返回請求的方法

public String getMethod();

//返回關聯當前請求的額外地址資訊(起於servlet地址止於引數,並以/結尾),如:servlet匹配地址為/teacher/*,請求為/teacher/one.jsp,則額外地址為/one.jsp

public String getPathInfo();

//返回額外地址資訊(參考getPathInfo方法)的真實資源地址

public String getPathTranslated();

//返回web應用程式的路徑

public String getContextPath();

//返回在地址後的引數串

public String getQueryString();

//返回登入使用者名稱

public String getRemoteUser();

//檢查user是否在許可權role中

public boolean isUserInRole(String role);

//返回當前授權使用者的Principal物件

public java.security.Principal getUserPrincipal();

//返回請求指定的sessionId

public String getRequestedSessionId();

//返回URI地址(URL的一部分,不包含引數,如:/teacher/one.jsp)

public String getRequestURI();

//返回URL地址(不包含引數部分,如:http://localhost:8080/teacher/one.jsp)

public StringBuffer getRequestURL();

//返回Servlet請求地址,不包含額外地址資訊(如:servlet匹配地址為/teacher/*,請求為/teacher/one.jsp,則返回為/teacher)

public String getServletPath();

//返回HttpSession,引數create表示沒有時是否要建立HttpSession,true:要 false:不要

public HttpSession getSession(boolean create);

//返回HttpSession,若沒有則直接新建一個

public HttpSession getSession();

//修改Session,建立新一個的session id

public String changeSessionId();

//檢測當前session是否合法

public boolean isRequestedSessionIdValid();

//檢測請求的session id是否來自於cookie

public boolean isRequestedSessionIdFromCookie();

//檢測請求的session id是否來自於url

public boolean isRequestedSessionIdFromURL();

//基於容器的安全策略授權請求的使用者

public boolean authenticate(HttpServletResponse response)

throws IOException,ServletException;

//基於容器的登入機制驗證登入

public void login(String username, String password)

throws ServletException;

//退出登入

public void logout() throws ServletException;

//對於multipart/form-data型別,返回所有的Part集合

public Collection<Part> getParts() throws IOException, ServletException;

//返回指定名稱的Part

public Part getPart(String name) throws IOException, ServletException;

//返回HttpUpgradeHandler例項用於升級

public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass)

throws IOException, ServletException;

}

3.8 ServletResponse介面

ServletResponse為servlet用於響應客戶端的物件,介面定義如下:

package javax.servlet;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Locale;

//ServletResponse為servlet用於響應客戶端的物件

public interface ServletResponse {

//返回相應的MIME字元編碼(可透過setCharacterEncoding、setContentType、setLocale方法確定),若沒有指定,則返回ISO-8859-1,參考RFC 2047 (http://www.ietf.org/rfc/rfc2047.txt)

public String getCharacterEncoding();

//返回相應的MIME body的content-type(只能透過方法setContentType設定,且在response提交之前),沒有則為null

public String getContentType();

//返回ServletOutputStream,適合在response中寫二進位制資料

public ServletOutputStream getOutputStream() throws IOException;

//返回PrintWriter,能夠向客戶端傳送文字字元,預設編碼為ISO-8859-1

public PrintWriter getWriter() throws IOException;

//設定response響應的字元編碼,會覆蓋方法setContentType或setLocale的設定,設定需在getWriter或response提交之前,否則不生效

public void setCharacterEncoding(String charset);

//設定response響應內容body的長度,即是設定Content-Length的header值

public void setContentLength(int len);

//設定response響應內容body的長度,即是設定Content-Length的header值(@since Servlet 3.1)

public void setContentLengthLong(long len);

//設定response的content type,包含內容型別和字元編碼,如:text/html;charset=UTF-8

public void setContentType(String type);

//設定response body的buffer大小,在實際傳送內容前,更大的buffer可以寫更多的內容,不過小buffer能讓客戶端更快收到資料

public void setBufferSize(int size);

//獲取response body的buffer大小

public int getBufferSize();

//強制重新整理buffer,即是提交response

public void flushBuffer() throws IOException;

//清空buffer中的內容(不清空status code、headers)

public void resetBuffer();

//檢測response是否提交

public boolean isCommitted();

//清空buffer中的內容(同時清空status code、headers)

public void reset();

//設定response的方言

public void setLocale(Locale loc);

//獲取response的方言

public Locale getLocale();

}

3.9 HttpServletResponse

HttpServletResponse繼承ServletResponse介面,提供在傳送響應response時,提供http功能,如訪問http的headers和cookies,介面定義如下:

package javax.servlet.http;

import java.io.IOException;

import java.util.Collection;

import javax.servlet.ServletResponse;

//繼承ServletResponse介面,提供在傳送響應response時,提供http功能,如訪問http的headers和cookies

public interface HttpServletResponse extends ServletResponse {

//新增cookie

public void addCookie(Cookie cookie);

//檢測是否含有指定名稱的header

public boolean containsHeader(String name);

//編碼指定url(包含session id, 根據瀏覽器是否支援來決定session id是否放到url)

public String encodeURL(String url);

//編碼在sendRedirect方法中的指定url(根據瀏覽器是否支援來決定session id是否放到url)

public String encodeRedirectURL(String url);

//傳送錯誤,包含status和指定訊息

public void sendError(int sc, String msg) throws IOException;

//傳送錯誤,包含status

public void sendError(int sc) throws IOException;

//使用指定url傳送臨時重定向給客戶端,此時code為302。地址在傳送給客戶端前,servlet會將地址轉為絕對地址,

//地址沒有以/開頭,會解析為相對當前地址,

//地址以一個/開頭,會解析為相對servlet容器root地址,

//地址以兩個/(即//)開頭,會解析為網路地址

public void sendRedirect(String location) throws IOException;

//以date型別設定header,如果已經存在則覆蓋

public void setDateHeader(String name, long date);

//以date型別新增header,相同header可以存在多個值

public void addDateHeader(String name, long date);

//設定header,如果已經存在則覆蓋

public void setHeader(String name, String value);

//新增header,相同header可以存在多個值

public void addHeader(String name, String value);

//設定header,如果已經存在則覆蓋

public void setIntHeader(String name, int value);

//新增header,相同header可以存在多個值

public void addIntHeader(String name, int value);

//設定status(當沒有錯誤時,有錯誤時不生效)

public void setStatus(int sc);

//獲取response當前status

public int getStatus();

//獲取response中指定名稱的header(@since Servlet 3.0)

public String getHeader(String name);

//獲取response中指定名稱的header集合(@since Servlet 3.0)

public Collection<String> getHeaders(String name);

//獲取response中的header名稱集合

public Collection<String> getHeaderNames();

//後續還有響應status定義,在此略過,詳情請檢視原始碼

}

四、備註

更多基於原始碼的關於Servlet,在後續逐步介紹。

17
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • python中日誌記錄