(六)HttpServlet

通常浏览器客户端都是通过Http协议来访问服务端资源,而Servlet也主要是应运于http协议的请求和响应。为此sun公司为我们提供个抽象的类HttpServlet,它继承自GenericServlet类,用于创建适合Web站点的HTTP Servlet。

在HttpServlet中主要是对Service的重写

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        ................
        
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        service(request, response);
    }

   在servlce中将ServeltRequest和ServletResponse转换为HttpServletRequest 和HttpServletResponse传给重载后的service

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();

        if (method.equals("GET")) {
            long lastModified = getLastModified(req);
            if (lastModified == -1L) {
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < lastModified) {
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);
        } else if (method.equals("POST")) {
            doPost(req, resp);
        } else if (method.equals("PUT")) {
            doPut(req, resp);
        } else if (method.equals("DELETE")) {
            doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            doOptions(req, resp);
        } else if (method.equals("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(501, errMsg);
        }
    }

此时由重载的Service来对客户端的请求,进行处理。为此HttpServlet分别提供了7个do**处理方法,主要针对HTTP1.1中定义的7种请求方法:GET、POST、HEAD、PUT、DELETE、TRACE和OPTIONS。

        protected void doGet (HttpServletRequest req, 
                HttpServletResponse resp) throws ServletException, java.io.IOException
        protected void doPost (HttpServletRequest req, 
                HttpServletResponse resp) throws ServletException, java.io.IOException
        protected void doHead (HttpServletRequest req, 
                HttpServletResponse resp) throws ServletException, java.io.IOException
        protected void doPut (HttpServletRequest req, 
                HttpServletResponse resp) throws ServletException, java.io.IOException
        protected void doDelete (HttpServletRequest req, 
                HttpServletResponse resp) throws ServletException, java.io.IOException
        protected void doTrace (HttpServletRequest req, 
                HttpServletResponse resp) throws ServletException, java.io.IOException
        protected void doOptions (HttpServletRequest req, 
                HttpServletResponse resp) throws ServletException, java.io.IOException

在重载后的service中,通过判断req.getMethod(); 来调用相应的请求方法做出处理。

总结如下:

这7个方法的参数类型及异常抛出类型与HttpServlet类中的第二个重载的service()方法是一致的。

当容器接收到一个针对HttpServlet对象的请求时,调用该对象中的方法顺序如下:

① 调用公共的(public)service()方法。

② 在公共的service()方法中,首先将参数类型转换为HttpServletRequest和HttpServletResponse,

    然后调用保护的(protected)service()方法,将转换后的HttpServletRequest对象和HttpServletResponse对象作为参数传递进去。

③ 在保护的service()方法中,首先调用HttpServletRequest对象的getMethod()方法,获取HTTP请求方法的名字,然后根据请求方法的类型,调用相应的doXxx ()方法。

    因此,我们在编写HttpServlet的派生类时,通常不需要去覆盖service()方法,而只需重写相应的doXXX()方法。

 

HttpServlet类对TRACE和OPTIONS方法做了适当的实现,因此我们不需要去覆盖doTrace()和doOptions()方法。

而对于其他的5个请求方法,HttpServlet类提供的实现都是返回HTTP错误,对于HTTP 1.0的客户端请求,这些方法返回状态代码为400的HTTP错误,表示客户端发送的请求在语法上是错误的。

而对于HTTP 1.1的客户端请求,这些方法返回状态代码为405的HTTP错误,表示对于指定资源的请求方法不被允许。这些方法都是使用javax.servlet.ServletRequest接口中的getProtocol()方法来确定协议的。

HttpServlet虽然是抽象类,但在这个类中没有抽象的方法,其中所有的方法都是已经实现的。只是在这个类中对客户请求进行处理的方法,没有真正的实现,当然也不可能真正实现,因为对客户请求如

何进行处理,需要根据实际的应用来决定。我们在编写HTTP Servlet的时候,根据应用的需要,重写其中的对客户请求进行处理的方法即可。

posted @ 2016-01-18 16:33  姩澕  阅读(219)  评论(0编辑  收藏  举报