Servlet类图
- javax.Servlet 接口定义了:servlet与servlet容器之间的契约——简单讲,容器将将 servlet.class载入内存,创建实例,调用方法
- javax.Servlet.http接口定义:httpServlet 与 servlet容器之间的契约
servlet接口生命周期方法(一个对象对个线程调用,存在线程安全问题)
-
- init 第一次请求时,被调用,入参为ServletConfig对象
- service 每次请求
- destroy 销毁时
这两个对象会作为参数传入service方法
ServletRequest 对于每个http请求,容器都会创建一个ServletRequest实例,包含http请求体里面的数据
ServletResponse 表示一个Servlet响应,在调用service方法前创建ServletResponse 对象
-
- 其getWriter方法返回的PrintWriter方法 默认编码是 ISO-8859-1
- 所以会存在中文乱码问题
ServletConfig 容器初始化Servlet时,init的入参类型,可以获取web.xml中设置的key-value值
-
- 还能获取ServletContext对象
ServletContext 表示Servlet应用程序,再一个应用多个容器的封不是环境中,每台java虚拟机上的应用都会有一个ServletContext对象
-
- 获取方式: javax.servlet.ServletConfig#getServletContext() 方法返回
- 可以用来从应用中共享数据,其中有个map对象
为了简化操作,出现了
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable{}
-
- 将ServletConfig 对象赋予一个 成员变量,提供了getServletConfig()方法获取
- 提供了Servlet接口的默认实现
- 提供方法,包围ServletConfig中的方法
这样子类只要重写 init()的空参方法 就能加入自己想要初始化的操作了
public void init(ServletConfig config) throws ServletException { this.config = config; this.init();}public void init() throws ServletException {}
HttpServlet 其中的很多类 覆盖了Servlet接口的类
-
- HttpServlet extends GenericServlet
- HttpServletRequest extends ServletRequest
- HttpServletResponse extends ServletResponse
两个service方法,将入参向下转型(因为servlet容器实际是预备使用HTTP的,所以传入service(ServletRequest req, ServletResponse res)的入参实际是http实现类的对象)
ServletRequest ——> HttpServletRequestServletResponse——>HttpServletResponse,根据http头里面 method 调用不同的处理方法
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; try { ifModifiedSince = req.getDateHeader("If-Modified-Since"); } catch (IllegalArgumentException var9) { ifModifiedSince = -1L; } if (ifModifiedSince < lastModified / 1000L * 1000L) { 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); } } public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request; HttpServletResponse response; try { request = (HttpServletRequest)req; response = (HttpServletResponse)res; } catch (ClassCastException var6) { throw new ServletException("non-HTTP request or response"); } this.service(request, response); }
HttpServletRequest http环境中的serlvet请求
-
- String getContextPath();
- Cookie[] getCookies();
- String getHeader(String var1);
HttpServletResponse http环境中的serlvet响应
-
- void addCookie(Cookie var1);
- void addHeader(String var1, String var2);
- void sendRedirect(String var1) throws IOException;
部署描述符-web.xml文件
- xml中定义的key-value参数 能够覆盖注解中配置的值
- 可以使用<load-on-startup>标签,在启动容器时就初始化servlet