Servlet深入学习

Servlet是学习j2ee的基础,所以必要对Servlet有所了解,Servlet是运行在tomcat容器中的,Tomcat设计的内容比较多,有专门的一本书介绍,我们简单了解一下Tomcat的容器模型

一、Tomcat的容器模型

Tomcat 的容器等级中,Context 容器是直接管理 Servlet 在容器中的包装类 Wrapper,所以 Context 容器如何运行将直接影响 Servlet 的工作方式。

二、Servlet的生命周期

Servlet加载=》实例化=>响应服务=》销毁;Servlet加载(1)在响应的浏览器的第一次请求时候创建,(2)可以再配置文件中配置,使得当Tomcat启动的时候就加载,

在web.xml中加上<load-on-startup>1</load-on-startup>就可以;Servlet出来请求的具体流程见下图




步骤:

  1. Web Client 向Servlet容器(Tomcat)发出Http请求
  2. Servlet容器接收Web Client的请求
  3. Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。
  4. Servlet容器创建一个HttpResponse对象
  5. Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet 对象。
  6. HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
  7. HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
  8. Servlet容器把HttpServlet的响应结果传给Web Client。

三、Servlet中最重要的几个函数
1、init()服务器加载Servlet时候执行,只执行一次,可以做一些初始化的工作
2、service(),Servlet核心,Servlet对象响应用户请求调用该方法处理业务逻辑,我们看一下源码
该方法将ServletRequest对象强转为HttpServletRequest对象,然后调用service方法
 public void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException {

        HttpServletRequest  request;
        HttpServletResponse response;
        
        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException("non-HTTP request or response");
        }
        service(request, response);
    }
以下方法主要对用户请求的类型进行分发,主要的是Get和Post请求,然后执行doGet和doPost方法,详情见源码,最后我会附上tomcat的源码
 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;
                try {
                    ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                } catch (IllegalArgumentException iae) {
                    // Invalid date header - proceed as if none was set
                    ifModifiedSince = -1;
                }
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // 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);
        }
    }
3、destory()在服务器停止或者Servlet卸载的时候执行,也只执行一次
四、我们可以重新以上的方法满足我们自已的需求,代码如下:
public class Test3 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.log("执行doGet()方法。。。。。。。");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.log("执行doPost()方法。。。。。。。");
	}

	@Override
	protected long getLastModified(HttpServletRequest req) {
		this.log("执行getLastModified()方法。。。。。。。");
		return -1;
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.log("执行service()方法。。。。。。。");	
		if(req.getMethod()=="GET")
			doGet(req,resp);
		else
			doPost(req,resp);		
	}
	@Override
	public void destroy() {
		this.log("执行destroy()方法。。。。。。。");
	}

	@Override
	public void init() throws ServletException {
		this.log("执行init()方法。。。。。。。");
	}

}
最后注明:Servlet非线程安全的,用的时候要注意
参考文章:
http://www.ibm.com/developerworks/cn/java/j-lo-servlet/
http://www.cnblogs.com/xuekyo/archive/2013/02/24/2924072.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值