玖叶教程网

前端编程开发入门

servlet相关源码解析(servlet工作原理解析)

一、简介

最近看源码,涉及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值为0或正数时,值越小,越早被加载,为负数时,则由容器决定加载时机-->

<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;

//返回关于servlet的信息(如作者、版本号、版权等)

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{}

//由server(通过service方法调用)调用,用于处理delete请求。用于从服务器上删除文件

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,在后续逐步介绍。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言