Java Servlet简单总结

概述

什么是Servlet

javax包下的一个interface,定义了Java处理web请求的标准,运行于Servlet容器(如 Tomcat,Jetty)中。Servlet有权访问所有的Java API,包括JDBC API。广义的Servlet指实现了Servlet接口的类。

Servlet干了什么

  • 接收客户端请求
  • 容器初始化并调用Servlet,Servlet生成响应内容
  • 返回内容给客户端

Servlet的源码与组件

Servlet的方法和生命周期

public interface Servlet {

    //初始化Servlet
    public void init(ServletConfig config) throws ServletException;

    //获取ServletConfig对象
    public ServletConfig getServletConfig();

    //用于处理一个请求
    public void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException;

    //获取Servlet相关信息
    public String getServletInfo();

    //销毁
    public void destroy();
}

以上代码及注释中,基本就可以看出生命周期了。需要注意的是destroy()方法的调用时机,一般是指关闭容器。desttoy方法中会做一些销毁容器或清理一些资源的工作,和init()方法一样在整个生命周期中只会被调用一次。

组件解析

Servlet的源码中,还出现了以下几个组件,对其作用进行简单概述。

ServletRequest

Servlet容器对于每一个请求,都会创建一个ServletRequest对象,将其作为参数传递给 Servlet的service方法。ServletRequest对象内封装了请求中参数名称和值,属性和输入流等信息。

ServletConfig

存储Servlet配置信息,包括服务端口,服务名称,远程地址,参数列表等。因为api太多就不贴了,感兴趣的可以去查元源代码或者api文档。

ServletResponse

从Servlet的源码来看,ServletResponse对象也是作为参数传递给service方法的,也就是说在调用service方法之前容器就创建了这个对象。ServletResponse对象中的getWriter()方法返回了一个 java.io.PrintWriter,如果没有指定字符集,默认使用ISO-8859-1编码,在传输中文的情况下会导致乱码。

ServletContext

ServletContext代表了应用本身,所以ServletContext是可以被当前所有的Servlet共享,所以ServletContext中存放的数据需要是线程安全的。

GenericServlet

GenericServlet是Servlet的默认实现,作用就是可以直接调用Servlet的方法,而不用自己去实现所有方法。因为GenericServlet还实现了ServletConfig,所以也可以直接调用ServletConfig的方法。此组件使用不多,用的比较多的还是熟悉的HttpServlet。

HttpServlet

使用http协议实现的实现类,继承自GenericServlet。HttpServlet重写了GenericServlet的service()方法,源码如下。

protected void service(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException
{
    //获取请求类型
    String method = req.getMethod();

    //根据请求类型进行路由,调用不同的请求类型处理方法,开发过程中只需要复写指定类型的方法即可
    if (method.equals(METHOD_GET)) {
        //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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值