初识Servlet
目录结构:WEB-INF(lib classes web.xml jsp文件)
首先用户创建的servlet都是继承于httpservlet,用户可以通过重写service方法或者dopost,doget方法对用户请求做出响应。
servlet生命周期:
当我们说 servlet 具有生命周期时,只是指在调用 servlet 时,事情是以一种可预见的方式发生的。换言之,在任何 servlet 上创建的方法总是按相同的次序被调用的。下面是一个典型场景:
1.用户在浏览器中输入一个 URL。Web 服务器配置文件确定该 URL 是否指向一个由运行于服务器上的 servlet 容器所管理的 servlet。
2.如果还没有创建该 servlet 的一个实例(一个应用程序只有一个 servlet 实例),那么该容器就加载该类,并将之实例化。
3.该容器调用 servlet 上的 init()。(初始化只有一次)
4.该容器调用 servlet 上的 service(),并在包装的 HttpServletRequest 和 HttpServletResponse 中进行传递。
5.该 servlet 通常访问请求中的元素,代表其他服务器端类来执行所请求的服务并访问诸如数据库之类的资源,然后使用该信息填充响应。
6.如果有必要,在 servlet 的有用生命结束时,该容器会调用 servlet 上的 destroy() 来清除它。
ps:1.两个service方法
以下是HttpServlet的部分源代码:
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 = req.getDateHeader(HEADER_IFMODSINCE); 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); } }
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); } }两个参数不一样?一个protected,一个public有什么意义呢。
2.两个init 方法
以下是GenericServlet的部分源代码:
public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); }
public void init() throws ServletException { // NOOP by default }防止漏掉this.config=config,导致config为null。
一个简单的servlet实例:
HelloWorldServlet
package ig.sd.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloWorldServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { System.out.println("service"); super.service(request, response); } public HelloWorldServlet() { System.out.println("constructor running\n"); } @Override public void init() { System.out.printf("init\n"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet"); PrintWriter writer = resp.getWriter(); writer.write("HelloWorld"); writer.close(); } }
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app> <servlet> <servlet-name>HelloWorldServlet</servlet-name> <servlet-class>ig.sd.servlet.HelloWorldServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloWorldServlet</servlet-name> <url-pattern>/HelloWorldServlet</url-pattern> </servlet-mapping> </web-app>