【SpringMVC】Servlet

2018-08-13  本文已影响0人  半个橙子

Servlet是一套规范,其实就是一组接口,容器会回调接口的方法。我们按照这个规范写的代码就可以直接在Java的服务器上运行,等待容器的调用。

层次结构

HttpServlet.png

Servlet接口

public interface Servlet {
    //init方法在容器启动的时候被容器调用(当load-on-startup设置为负数或者不设置时会在Servlet第一次用到时才被调用),只会调用一次 
    void init(ServletConfig var1) throws ServletException;

    //getServletConfig方法用于获取ServletConfig
    ServletConfig getServletConfig();

    //service方法用于具体处理一个请求
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    //获取servlet相关的信息
    String getServletInfo();

    //主要用在Servlet销毁(一般指关闭服务器)时释放一些资源,也只会调用一次
    void destroy();
}
  <servlet>
    <display-name>contextConfig</display-name>
    <servlet-name>contextConfig</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 这些参数都会保存在servletConfig中传给DispatcherServlet.init-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:/xml/all.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

ServletConfig

public interface ServletConfig {
    //用于获取Servlet的名字,也就是我们在web.xml中定义的servlet-name
    String getServletName();
    //ServletContext 代表这个应用本身
    ServletContext getServletContext();
    //获取init-param配置的参数
    String getInitParameter(String var1);
    //获取配置的所有的init-params的名字集合
    Enumeration<String> getInitParameterNames();
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <!--Context级别的参数-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:/xml/all.xml</param-value>
  </context-param>
  <servlet>
    <display-name>contextConfig</display-name>
    <servlet-name>contextConfig</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--Servlet级别的参数-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:/xml/all.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
</web-app>

上面通过context-param配置的contextConfigLocation配置到了ServletContext中,而通过servlet下的init-params配置的contextConfigLocation配置到了ServletConfig中。
在Servlet中可以分别通过他们的getInitParamter方法进行获取,比如:

String contextConfigLocation = getServletConfig().getServletContext().getInitParameter("contextConfigLocation");
String servletLocation = getServletConfig().getInitParameter("contextConfigLocation");

GenericServlet

public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
}
public void init() throws ServletException {
}
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
 public Enumeration getInitParameterNames() {
        ServletConfig sc = this.getServletConfig();
        if (sc == null) {
            throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
        } else {
            return sc.getInitParameterNames();
        }
    }
  public void log(String message, Throwable t) {
        this.getServletContext().log(this.getServletName() + ": " + message, t);
    }

HttpServlet

HttpServlet是GenericServlet的子类,主要实现了父类的抽象方法service(ServletRequest var1, ServletResponse var2)

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
            HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse)res;
            this.service(request, response);
        } else {
            throw new ServletException("non-HTTP request or response");
        }
    }
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < lastModified) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_get_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读