前言:什么是Servlet?
Servlet是采用Java写的Web服务器端程序。
当客户端(浏览器)向服务器端发起请求时,服务器将请求(Request)进行封装后便调用Servlet程序处理请求,Servlrt将处理后的结果(Response)返回给服务器,服务器对结果进行封装后返回给客户端。
我们在学习开发中往往采用TomCat来作为服务器,由TomCat来调用Servlet处理Web请求。
Servlet
Servlet中的方法
1 2 3 4 5 6 7 8 9 10 11
| public interface Servlet { void init(ServletConfig var1) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; String getServletInfo(); void destroy(); }
|
当客户端向服务器发起请求时,服务器启动Servlet,Servlet首先调用 getServletConfig() 方法获得Servlet相关配置,并作为参数传递给 init() 方法,init() 方法用来初始化Servlet,Servlet初始化完成后就会调用 service() 方法处理请求 ,getServletInfo() 可以获得Servlet的一段描述信息,当请求处理结束后,便会调用 destroy() 方法销毁Servlet。这也是Servlet的生命周期。
ServletRequest 及 ServletResponse
Servlet在调用 service() 方法前会生成ServletRequest对象和ServletResponse对象。
我们可以通过ServletRequest中的方法来获取请求的相关信息:
1 2 3 4 5 6 7 8 9
| public interface ServletRequest { int getContentLength(); String getContentType(); String getParameter(String var1); }
|
可以通过ServletResponse中的方法自定义返回结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public interface ServletResponse { String getCharacterEncoding(); String getContentType(); ServletOutputStream getOutputStream() throws IOException; PrintWriter getWriter() throws IOException; void setCharacterEncoding(String var1); void setContentLength(int var1); void setContentType(String var1); void setBufferSize(int var1); int getBufferSize(); void flushBuffer() throws IOException; void resetBuffer(); boolean isCommitted(); void reset(); }
|
GenericServlet
直接实现Servlet接口较为复杂,我们需要实现其中的全部方法。GenericServlet抽象类的出现很好的解决了这个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| public abstract class GenericServlet implements Servlet, ServletConfig, Serializable { private static final String LSTRING_FILE = "javax.servlet.LocalStrings"; private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings"); private transient ServletConfig config; public GenericServlet() { } public void destroy() { } public String getInitParameter(String name) { ServletConfig sc = this.getServletConfig(); if (sc == null) { throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized")); } else { return sc.getInitParameter(name); } } public Enumeration<String> getInitParameterNames() { ServletConfig sc = this.getServletConfig(); if (sc == null) { throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized")); } else { return sc.getInitParameterNames(); } } public ServletConfig getServletConfig() { return this.config; } public ServletContext getServletContext() { ServletConfig sc = this.getServletConfig(); if (sc == null) { throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized")); } else { return sc.getServletContext(); } } public String getServletInfo() { return ""; } public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { } public void log(String msg) { this.getServletContext().log(this.getServletName() + ": " + msg); } public void log(String message, Throwable t) { this.getServletContext().log(this.getServletName() + ": " + message, t); } public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; public String getServletName() { ServletConfig sc = this.getServletConfig(); if (sc == null) { throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized")); } else { return sc.getServletName(); } } }
|
GenericServlet抽象类为我们提供了Servlet接口中方法的默认实现,我们可以只实现我们需要的方法。
HttpServlet
在实际的开发中,我们更常使用HttpServlet抽象类,它继承了GenericServlet抽象类。
HttpServlet覆盖了GenericServlet中的 service() 方法,在方法中调用了提供的另一个 service() 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| 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); } }
|
根据不同的Http请求类型调用不同的doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete方法,当我们需要实现具体的逻辑时只需要覆盖相应的do方法即可。
HttpServletRequest
HttpServletRequest继承自ServletRequest,新增了几个方法:
1 2 3 4 5 6 7 8 9 10 11
| String getContextPath();
Cookie[] getCookies();
String getHeader(String var1);
String getMethod();
String getQueryString();
HttpSession getSession();
|
HttpServletResponse
HttpServletResponse继承自ServletResPonse,新增了几个方法:
1 2 3 4 5 6 7 8 9
| void addCookie(Cookie var1);
void addHeader(String var1, String var2);
void setHeader(String name, String value);
void sendRedirect(String var1) throws IOException;
void setStatus(int var1);
|