关于servlet

没事看了会儿servlet,觉得里面的很多东西自己以前都不懂,用spring mvc用多了,以为servlet就是一个DispatcherServlet,通过web.xml里面的servlet-mapping映射后,通过配置的url可以直接访问servlet,servlet通过里面的某一个方法来处理这个请求,通过httpservletresponse返回给客户端。

对于到达Servlet容器的客户请求,Servlet容器创建特定于这个请求的ServletRequest对象和ServletResponse对象,然后调用Servlet的service方法。service方法从ServletRequest对象获得客户请求信息并处理该请求,通过ServletResponse对象向客户返回响应结果

其实要理解httpservlet还得从HTTP协议入手啊!HTTP是一种基于请求/响应模式的协议。客户端发送一个请求,服务器返回对该请求的响应。HTTP使用可靠的TCP连接,默认端口是80。在HTTP中,客户端/服务器之间的会话总是由客户端通过建立连接和发送HTTP请求的方式初始化,服务器不会主动联系客户端或要求与客户端建立连接。在会话开始后,浏览器或服务器都可以随时中断连接,例如,在浏览网页时可以随时点击“停止”按钮中断当前的文件下载过程,关闭与Web服务器的HTTP连接

所以对于httpservlet而言,它能根据客户端发出的http请求,生成相应的http的响应。HttpServlet首先必须读取HTTP请求的内容。Servlet容器负责创建HttpServletRequest对象,并把HTTP请求信息封装到HttpServletRequest对象中,这大大简化了HttpServlet解析请求数据的工作量。如果没有HttpServletRequest,HttpServlet只能直接处理Web客户发出的原始的字符串数据,有了HttpServletRequest后,只要调用HttpServletRequest的相关方法,就可以方便地读取HTTP请求中任何一部分信息;Servlet容器还向HttpServlet提供了HttpServletResponse对象,HttpServlet可以通过它来生成HTTP响应的每一部分内容

上面的内容大部分都是从网上摘抄下来的,现在说说我的想法吧。记得以前学servlet的时候老师就告诉我们直接继承httpServlet,然后重写doGet()和doPost()方法就可以了。以前不懂,只知道照着做,还以为servlet容器会自动判别是调用get方法还是调用post方法。今天看了一下httpservlet的源码,发现其实servelt是通过调用service()方法来处理客户端的请求的,不过httpservlet的service()方法里面是这样的:

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

原来是httpservlet里面的service()方法来判断是否是post方式还是get方式。至于为什么参数有ServletRequest变成了HttpServletRequest,我就不太清楚了,HttpServletRequest是ServletRequest的子类,也就是说HttpServletRequest更具体一点,可能是servlet容器来判断的吧,如果是一个http的客户端请求,servlet容器就把这些请求组装成一个httpservletrequest对象吧,如果不是http请求可能就组装成其它的servletrequest对象。个人看法,请各位指导指导,谢谢

原文地址:https://www.cnblogs.com/xiezhong/p/3988859.html