Servlet源码分析
http://c.biancheng.net/servlet2/servletcontext.html //Servlet教程
1 HttpServlet
1.1 定义HTTP METHOD
private static final long serialVersionUID = 8466325577512134784L;
private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String METHOD_POST = "POST";
private static final String METHOD_PUT = "PUT";
private static final String METHOD_TRACE = "TRACE";
private static final String HEADER_IFMODSINCE = "If-Modified-Since";
private static final String HEADER_LASTMOD = "Last-Modified";
private static final String LSTRING_FILE = "jakarta.servlet.http.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle.getBundle("jakarta.servlet.http.LocalStrings");
1.2 重写DoGet方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
resp.sendError(this.getMethodNotSupportedCode(protocol), msg);
}
//负责抛出异常,说不支持请求;
//我们只需要去负责Override doGet doPost就OK了;
1.3 service方法(Main)
String method = req.getMethod(); //获取是什么方法
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp); //没有检测到方法就走Doget
} 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);
}
2 GenericServlet
2.1 定义常量
private static final long serialVersionUID = -8592279577370996712L;
private static final String LSTRING_FILE = "jakarta.servlet.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle.getBundle("jakarta.servlet.LocalStrings");
private transient ServletConfig config;
2.2 destroy
public void destroy() {
}
//gernericServlet 方法中没有实现
2.3 init()
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
3 ServletConfig
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
4. Servlet
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
3 servlet config
3.1 获取servlet Name and init-param
@Override
public void init(ServletConfig config) throws ServletException {
String Name = config.getServletName();
System.out.println("ServletNamee:"+Name);
String URL= config.getInitParameter("url");
System.out.println(URL);
}
3.2 web.xml
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>com.spacexist.HelloWorld</servlet-class>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://locahost:3306/test</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
4 servlet context
4.1 获取web.xml context-param参数
//通过 GenericServlet的getServletContext方法获取ServletContext对象
ServletContext servletContext = this.getServletContext();
//通过 ServletConfig的 getServletContext方法获取ServletContext对象
ServletContext servletContext = this.getServletConfig().getServletContext()
4.2 Attribute
public void setAttribute(String name, Object object);
public void removeAttribute(String name);
public Object getAttribute(String name);
5 请求转发
req.setAttribute(key,value);
req.getdispacher(url).forward(req,reps);
6 Filter
public interface Filter {
default public void init(FilterConfig filterConfig) throws ServletException {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
chain.doFilter(request,response); // xml中filter按顺序调用,最后一个调用完后调用<servlet-maping>service();
default public void destroy() {}
}
<filter>
<filter-name>TestFilter2</filter-name>
<filter-class>top.spacexist.FilterDemo2</filter-class>
</filter>
<filter-mapping>
<filter-name>TestFilter2</filter-name>
<url-pattern>/filter</url-pattern>
</filter-mapping>
<filter>
<filter-name>TestFilter</filter-name>
<filter-class>top.spacexist.TestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/filter</url-pattern>
</filter-mapping>
7 Listener
7 Servlet 生命周期
//tomcat 第一次启动会调用 init(); 单例模式 只会实例化一次;
//接着每次访问一次就会调用Service(req,reps);service方法中处理各种请求
//最后 当服务器关闭时调用 destroy()方法
//Tomcat ->init(req,reps) ->service(req,reps) ->doGet(req,reps);
text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzc3MDgyNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=“123123” data-align=“center”>[外链图片转存中…(img-Q9A6fPkw-1665410674426)]
[外链图片转存中…(img-alytrTZM-1665410674426)]