JavaWeb之详解Servlet(四)

        我们知道Servlet接口中有5个方法,通过其中一个方法getServletConfig()又可以拓展出四个方法,具体如下:

JavaWeb之详解Servlet(四)_第1张图片

        而开发Servlet的第二种方式,即继承GenericServlet。观察API,可知该类实现 Servlet, ServletConfig接口。所以该类依然有以上所有方法,不过不同的是,类与方法直接的关系是直接调用。
JavaWeb之详解Servlet(四)_第2张图片

        如果我们需要调用ServletConfig类的方法,就不需要像实现Servlet接口那样先去创建ServletConfig对象,然后再去调用该对象的方法。而现在只需要直接调用想要的方法即可,是不是简便了一些。

        这就是开发Serlvet的第二种方式。

        不管是实现Servlet接口还是继承GenericServlet类,我们需要做的便是重写public void service(ServletRequest req, ServletResponse res) 方法,而ServletRequestServletResponse都是接口,为了实现更加强大的功能,我们需要进行向下转型。

public void service(ServletRequest req, ServletResponse res) {
	//多态:分为向上转型与向下转型
	//上转型:将子类引用赋值给父类应用
	//下转型:将父类引用赋值给子类引用,但Java中式不支持真正的下转型。
	// 但若父类对象本身使用子类对象上转型而来,那么,可以通过强转的方式,将其赋值给子类对象
	HttpServletRequest request = (HttpServletRequest)req;
	HttpServletResponse response = (HttpServletResponse)res;
	
	//在子类或实现类中我们可以定义增加一个方法,利用重载,调用下面这个方法
	service(request, response);
}

        private void service(HttpServletRequest request, HttpServletResponse response) { }

        我们将业务逻辑代码写入上面的方法中即可。

        而开发Servlet的第三种方式恰好替我们完成了这种操作,即
在这里插入图片描述
        作为子类,我们只需要重写 service(HttpServletRequest request, HttpServletResponse response),完成业务逻辑的处理。除此之外,我们还可以通过该类判断请求是以什么方式进行的提交。JavaWeb之详解Servlet(四)_第3张图片

        同时该类与GenericServlet一样实现Servlet接口和ServletConfig接口,所以其具有GenericServlet的方法。显而易见,HttpServlet的功能更加强大,所以我们可以选择继承HttpServlet去开发。以下为service(HttpServletRequest req, HttpServletResponse resp)的源代码:

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) {
                doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                } catch (IllegalArgumentException iae) {
                    ifModifiedSince = -1;
                }
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    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 {
            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);
        }
    }

        观察源代码,我们可知,通过判断请求的方式,调用不同的方法。那么子类是去重写service(HttpServletRequest req, HttpServletResponse resp)方法,还是去重写doXXX()方法?答案是不唯一的,你可以去只重写doXXX()方法,但我更让更倾向于重写service(HttpServletRequest req, HttpServletResponse resp),然后根据自己的选择是否需要区分请求方式,若要区分,则重写doXXX()方法,并在你所重写的service()方法中调用doXXX()方法。

        以上几节内容便是开发Servlet的三种方式,但Servlet依然有很多知识需要我们去学习。

你可能感兴趣的:(详解Servlet)