【Java学习笔记】64:实现Servlet,认识其核心方法
上篇通过课本上的实例学习了Servelt怎么使用,从这篇开始详细的学习其中的细节。实现Servlet实现一个自己的Servlet类,可以通过直接去实现Servlet接口,也可以去继承实现了Servlet接口的GenericServlet类,也可以去继承间接实现了Servlet接口的HttpServlet类,它们的关系如下:Servlet的核心方法建立一个继承了Servl...
上篇通过课本上的实例学习了Servelt怎么使用,从这篇开始详细的学习其中的细节。
实现Servlet
实现一个自己的Servlet类,可以通过直接去实现Servlet接口,也可以去继承实现了Servlet接口的GenericServlet类,也可以去继承间接实现了Servlet接口的HttpServlet类,它们的关系如下:
Servlet的核心方法
建立一个继承了Servlet接口
的类可以直观地看到Servlet中要求被覆写的一些重要方法:
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class MyServlet implements Servlet {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
init()
方法将在第一次创建Servlet时被调用,且后面不会再调用它。用来创建和加载一些初始化数据。
destroy()
方法是在Servlet生命周期结束时被调用,且之前不会去调用它。用来关闭和数据库的连接,终止服务线程,将Cookie写回磁盘等操作。
service()
方法是Servlet中最核心的方法,用来处理来自客户端的请求。如果是去继承实现了Servlet接口的GenericServlet类
,那么只要求重写这个serivce()方法:
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class MyServlet extends GenericServlet {
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
更简便和常用的方式是去继承HttpServlet类
,这时并不要求覆写任何方法:
import javax.servlet.http.HttpServlet;
public class MyServlet extends HttpServlet {
}
但这样显然就没有可用价值,在网上找了HttpServlet类的源码,其中有两个service()方法,一个是覆写了父类抽象的service()方法:
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequestrequest;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException("non-HTTP request or response");
}
service(request, response);
}
在该方法中仅是对传进来的ServletRequest类
的参数做了检查,然后调用了另一个service()方法:
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);
}
}
暂不去关注其细节,但仍能看到该方法中的分支语句调用了不同的do*()
方法,这就是根据状态的不同以及客户端的请求不同调用的不同处理方法。一般只需要**覆盖**HttpServlet中的doGet()
和doPost()
方法,并使其实现一样的功能(一个调用另一个)即可。
实际上前者是处理那些未指定method参数或指定其值为”get”的HTML表单提交,后者是处理指定了参数为”post”的HTML表单提交,很多时候目的是一样的。
更多推荐
所有评论(0)