Servlet源码解读

本文解析了Servlet-API-2.5中的核心接口,包括Servlet、GenericServlet、ServletRequest、ServletResponse等,并介绍了它们之间的关系及如何实现HTTP请求处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Servlet源码解读

此源码解读是基于servlet-api-2.5.

Servlet接口

Servlet接口是servlet包中最核心的接口,是所有Servlet必须直接或间接实现的接口。

public interface Servlet{
    publi c void init(ServletConfig config) throws ServletException;
    public ServletConfig getServletConfig();
    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;
    public String getServletInfo();
    public void destroy();
}

每一次新建servlet,都要实现Servlet接口里的方法,为了减轻我们的负担,Servlet包里为我们提供了一个模板类GenericServlet。该抽象类继承自Servlet,并实现了若干通用的初始化过程。1

public abstract class GenericServlet 
    implements Servlet, ServletConfig, java.io.Serializable{}

抽象类GenericServlet中有一个成员变量ServletConfig:

private transient ServletConfig config;

该成员变量封装了Servlet的相关配置信息。初始化时,Servlet容器调用Servlet的init()方法,将读取到的web.xml中的对应的Servlet配置信息封装成ServletConfig作为参数,传递给init()函数。

/**
     *
     * Called by the servlet container to indicate to a servlet that the
     * servlet is being placed into service.  See {@link Servlet#init}.
     *
     * <p>This implementation stores the {@link ServletConfig}
     * object it receives from the servlet container for later use.
     * When overriding this form of the method, call 
     * <code>super.init(config)</code>.
     *
     * @param config            the <code>ServletConfig</code> object
     *                  that contains configutation
     *                  information for this servlet
     *
     * @exception ServletException  if an exception occurs that
     *                  interrupts the servlet's normal
     *                  operation
     *
     * 
     * @see                 UnavailableException
     *
     */

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

同时,GenericServlet也实现了Servlet接口中定义的getServletConfig()方法,用以实现对ServletConfig config成员变量的访问。

ServletRequest和ServletRespouse接口

Servlet包中另外两个重要的接口是ServletRequest和ServletResponse。对于每个HTTP请求,Servlet容器都会封装一个ServletRequest对象传递给Servlet的service()方法,通过ServletRequest,可以获得一些请求相关的参数.ServletResponse则封装了一个Servlet的响应,通过ServletResponse可以设置一些参数和内容,进行返回。不过在返回之前,为了避免出现问题,通常会调用setContentType()方法,设置返回内容的类型,如果不设置,会默认以html的形式返回。

/**
     * Sets the content type of the response being sent to
     * the client, if the response has not been committed yet.
     * The given content type may include a character encoding
     * specification, for example, <code>text/html;charset=UTF-8</code>.
     * The response's character encoding is only set from the given
     * content type if this method is called before <code>getWriter</code>
     * is called.
     * <p>This method may be called repeatedly to change content type and
     * character encoding.
     * This method has no effect if called after the response
     * has been committed. It does not set the response's character
     * encoding if it is called after <code>getWriter</code>
     * has been called or after the response has been committed.
     * <p>Containers must communicate the content type and the character
     * encoding used for the servlet response's writer to the client if
     * the protocol provides a way for doing so. In the case of HTTP,
     * the <code>Content-Type</code> header is used.
     *
     * @param type  a <code>String</code> specifying the MIME 
     *          type of the content
     *
     * @see         #setLocale
     * @see         #setCharacterEncoding
     * @see         #getOutputStream
     * @see         #getWriter
     *
     */

    public void setContentType(String type);

ServletResponse中还定义了getWriter()方法,将文本返回给客户端的java.io.PrintWriter,在默认的情况下,PrintWriter对象使用ISO-8859-1编码,这可能会引起乱码.

    /**
     * Returns a <code>PrintWriter</code> object that
     * can send character text to the client.
     * The <code>PrintWriter</code> uses the character
     * encoding returned by {@link #getCharacterEncoding}.
     * If the response's character encoding has not been
     * specified as described in <code>getCharacterEncoding</code>
     * (i.e., the method just returns the default value 
     * <code>ISO-8859-1</code>), <code>getWriter</code>
     * updates it to <code>ISO-8859-1</code>.
     * <p>Calling flush() on the <code>PrintWriter</code>
     * commits the response.
     * <p>Either this method or {@link #getOutputStream} may be called
     * to write the body, not both.
     *
     * 
     * @return      a <code>PrintWriter</code> object that 
     *          can return character data to the client 
     *
     * @exception UnsupportedEncodingException
     *          if the character encoding returned
     *          by <code>getCharacterEncoding</code> cannot be used
     *
     * @exception IllegalStateException
     *          if the <code>getOutputStream</code>
     *          method has already been called for this 
     *          response object
     *
     * @exception IOException
     *          if an input or output exception occurred
     *
     * @see         #getOutputStream
     * @see         #setCharacterEncoding
     *
     */

    public PrintWriter getWriter() throws IOException;

ServletConfig和ServletContext接口

ServletConfig如上文介绍的,封装了对应Servlet的配置信息。
ServletContext则是一个全局的储存信息的空间。服务启动时,便会加载ServletContext,服务关闭时,才会释放ServletContext。2

HttpServlet、HttpServletRequest和HttpServletResponse

下面会提到三个新的接口或抽象类,下面先看看这三个类与上文提到的类有什么关系.
HttpServletRequest继承自ServletRequest

public interface HttpServletRequest extends ServletRequest

HttpServletResponse继承自ServletResponse

public interface HttpServletResponse extends ServletResponse

HttpServlet继承自GenericServlet

public abstract class HttpServlet extends GenericServlet
    implements java.io.Serializable

HttpServlet重写了doGet()方法和doPost()方法,并且用HttpServletRequest和HttpServletResponse替换了ServletRequest和ServletResponse

HttpServletRequest继承自ServletRequest

public interface HttpServletRequest extends ServletRequest

HttpServletResponse继承自ServletResponse

public interface HttpServletResponse extends ServletResponse

总结

在servlet-api-2.5中,最主要的成员包括: Servlet、GenericServlet、ServletRequest、ServletResponse,以及在http包下的分别继承自以上若干类的HttpServlet、HttpServletRequest和HttpServletResponse。当然还包括以后提到的HttpSeesion和Cookie。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值