• Servlet基础(一) Servlet简介 关键API介绍及结合源码讲解


      

    Servlet基础(一) Servlet基础和关键的API介绍

    Servlet简介

      Java Servlet是和平台无关的服务器端组件,它运行在Servlet容器中。

      Servlet容器负责Servlet和客户的通信以及调用Servlet的方法,Servlet和客户的通信采用“请求/响应”的模式。

      Servlet可完成如下功能:

      创建并返回基于客户请求的动态HTML页面。

      创建可以嵌入到现有HTML页面中的部分HTML页面(HTML片段)。

      与其他服务器资源(如数据库或基于Java的应用程序)进行通信。

    Servlet API

      Servlet的框架是由两个Java包组成:

      1.javax.servlet包:定义了所有的Servlet类都必须实现或扩展的通用接口和类。

      2.javax.servlet.http包:定义了采用HTTP协议通信的HttpServlet类。

     

    javax.servlet.Servlet

      Servlet的框架的核心是javax.servlet.Servlet接口,所有的Servlet都必须实现这一接口。

      在Servlet接口中定义了五个方法,其中有三个方法代表了Servlet的生命周期:

      init方法:负责初始化Servlet对象。

      service方法:负责响应客户的请求。

      destroy方法:当Servlet对象退出生命周期时,负责释放占用的资源。

    HttpServlet

      每一个Servlet都必须要实现Servlet接口。

      GenericServlet是个通用的、不特定于任何协议的Servlet,它实现了Servlet接口。

      HttpServlet继承于GenericServlet,因此我们定义的Servlet只需要继承HttpServlet即可。

      Servlet接口中定义了一个service方法,HttpServlet对该方法进行了实现。

      HttpServlet对service方法的实现方式:

      第一步,进行一个分发。

      将ServletRequestServletResponse转换为HttpServletRequestHttpServletResponse

      转换完毕后,会调用HttpServlet中自己的service方法,源码如下:

    复制代码
        @Override
        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);
        }
    复制代码

      第二步,从上个service方法中接收标准的HTTP请求,然后将它们继续分发到相应的doXXX方法中:

      源码:

    复制代码
    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方法中,首先从HttpServletRequest对象中获取HTTP请求方式的信息,然后再根据请求的方法名调用相应的方法doXXX方法。

      比如,如果请求方式为GET,那么调用doGet方法;如果请求方式为POST,那么调用doPost方法。

      如果你的Servlet类扩展了HttpServlet类,你通常不必实现service方法。

      需要注意的是在HttpServlet类中所提供的doGet、doPost等方法都是直接返回错误信息,所以我们需要在自己定义的Servlet类中override这些方法。

     

    ServletRequest接口

      ServletRequest接口中封装了客户请求信息,如客户请求方式、参数名和参数值、客户端正在使用的协议,以及发出客户请求的远程主机信息等。

      ServletRequest接口还为Servlet提供了直接以二进制方式读取客户请求数据流的ServletInputStream。

      ServletRequest的子类可以为Servlet提供更多的和特定协议相关的数据。

      例如,HttpServletRequest提供了读取HTTP Head信息的方法。

    ServletResponse接口

      ServletResponse接口为Servlet提供了返回响应结果的方法。

      它允许Servlet设置返回数据的长度和MIME类型,并且提供输出流ServletOutputStream。

      ServletResponse子类可以提供更多和特定协议相关的方法。

      例如,HttpServletResponse提供设定HTTP Head信息的方法。

     

    创建自己的HttpServlet类的步骤

      1.扩展HttpServlet抽象类。

      2.覆盖HttpServlet的部分方法,如覆盖doGet()或doPost()方法。

      3.获取HTTP请求信息,例如通过HttpServletRequest对象来检索HTML表单所提交的数据或URL上的查询字符串。

      无论是表单数据还是URL上的查询字符串,在HttpServletRequest对象中都以参数名/参数值的形式存放,你可以通过getParameter()方法检索参数信息。

      4.生成HTTP响应结果。

      通过HttpServletResponse对象可以生成响应结果。

      HttpServletResponse对象有一个getWritter()方法,该方法返回一个PrintWriter对象。

      用PrintWritter的print()println()方法可以向客户端发送字符串数据流。

      比如下面这个简单的Servlet:

    复制代码
    public class HelloWorldServlet extends HttpServlet
    {
        @SuppressWarnings("deprecation")
        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException
        {
    
            resp.setContentType("text/html");
    
            PrintWriter out = resp.getWriter();
    
            out.println("<html><head><title>Hello World Sample</title></head>");
            out.println("<body><h1>Hello World Title<h1><h2>" +new Date().toLocaleString() + "</h2></body></html>");
            out.flush();
    
        }
    
    }
    复制代码

    ServletContext和Web应用关系

      当Servlet容器启动Web应用时,为每个Web应用创建唯一的ServletContext对象。

      你可以把ServletContext看成是一个Web应用的服务器端组件的共享内存。

      在ServletContext中可以存放共享数据,它提供了读取或设置共享数据的方法:

      setAttribute(java.lang.String name, java.lang.Object object)把一个对象和一个属性名绑定,将这个对象存储在ServletContext中。

      getAttribute(java.lang.String name)根据给定的属性名返回所绑定的对象。

    参考资料

      圣思园张龙老师Java Web视频教程。

      参考文档:

      1.javax.servlet包:定义了所有的Servlet类都必须实现或扩展的通用接口和类。

      http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/package-summary.html

     

      2.javax.servlet.http包:定义了采用HTTP协议通信的HttpServlet类。

      http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/package-summary.html

      API的源码可以去Tomcat官网下载:

      http://tomcat.apache.org/download-70.cgi

     

  • 相关阅读:
    eclipse配置
    TableViewComponent v2
    4500装机指南
    【翻译】Ext JS 4——Ajax和Rest代理处理服务器端一场和消息的方法
    【翻译】Ext JS——高效的编码风格指南
    JDK8帮助文档生成-笔记
    【翻译】在Ext JS 5种使用ViewControllers
    【翻译】Ext JS最新技巧——2014-5-12
    PS图像特效算法——百叶窗
    人脸表情识别常用的几个数据库
  • 原文地址:https://www.cnblogs.com/liu-Gray/p/4862986.html
Copyright © 2020-2023  润新知