HttpServlet源码分析
HttpServlet源码分析
概念
HttpServlet类是专门为Http协议准备的
在哪个包下: jakarta.servlet.http.HttpServlet
到目前为止我们接触了servlet规范中的哪些接口?
- jakarta.servlet.Servlet 核心接口
- jakarta.servlet.ServletCaonfig Servlet配置信息接口
- jakarta.servlet.ServletContext Servlet上下文接口
- jakarta.servlet.ServletRequest Servlet请求接口
- jakarta.servlet.ServletResponse Servlet响应接口
- jakarta.servlet.ServletExcepetion Servlet异常
- jakarta.servlet.GenericServlet 标准通用的Servlet类
源码分析
回忆servlet生命周期
- 用户第一次请求
- Tomcat服务器通过反射机制,调用无参数的构造方法,创建Servlet对象(web.xml文件中配置的Servlet类对应的对象)
- Tomcat调用init()方法完成初始化
- Tomcat服务器吊桶Servlet对象的servlice()方法处理请求
- 用户第二次请求
- Tomcat服务器调用service()方法处理请求
- 服务器关闭
- Tomcat服务器调用Servlet对象中的destroy()方法,做销毁之前的处理工作
- Tomcat服务器销毁Servlet对象
源码分析
public class ServletTest1 extends javax.servlet.http.HttpServlet { //用户第一次请求ServletTest1会被创建 同时执行无参数的构造方法 public ServletTest1(){ } public abstract class GenericServlet implements Servlet, ServletConfig, Serializable { //用户第一次请求 这个类中的带参数的init()会执行 然后执行无参的init() public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { } } //用户第一次发送请求 public abstract class HttpServlet extends GenericServlet { 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(lStrings.getString("http.non_http")); } // 调用重载的service()方法 this.service(request, response); } } //也就是这个方法 用来判断请求方式 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); } } /** 通过以上源代码进行分析,可以发现,只要HttpServlet类中的doGet()或doPost()方法执行,必然会报405 怎么避免405错误 后端重写doget()方法,前端一定要发送get请求 后端重写dopost()方法,前段一定要发送post请求 */ } }
结束:
- 编写一个Servlet类,直接继承HttpServlet
- 重写doget()或dopost()方法,到底重写谁,看前端发送的请求
- 将Servlet类配置到web.xml文件中
- 准备前端的页面(from表单)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!