Servlet 分析
来源:互联网 发布:qq飞车飞碟数据被改 编辑:程序博客网 时间:2024/05/20 10:52
上面的servlet只是接口,相当于描述了servlet的标准,也就是说与协议无关。而HttpServlet的实现是根据Http协议来完成的。
打开源码看后发现大多数接口和抽象类,那么真正的实现都在哪呢?在servlet容器源代码里,即类似Tomcat这样的servlet容器。
所以我觉得可以这样理解Servlet的作用:它提供了操控的按钮,这些按钮一旦被安装到Servlet容器里面,我们就可以通过这些按钮操控servlet容器,从而管理我们自己的Servlet实例。
这一点很重要。所以阅读Servlet源码其实就是了解他的基本结构和API,我们真正要读的是Tomcat的源码!
Servlet的运行结构和API:
首先看下一次Http请求-响应的过程:
A,首先客户端通过浏览器向服务器发送Http请求;
B,Tomcat监听服务器的8080端口,当有Http请求发过来之后,解析出项目名称,然后到webapps目录下搜索到该项目文件夹。
C,Tomcat作为servlet的容器,实例化第一次请求调用的的servlet实例(以后再有相同的servlet的请求,使用第一次的实例)。
D,调用init()方法,初始化工作。
E,调用HttpServlet的service方法,中间会更加请求,调用doGet或doPost方法,执行核心逻辑代码。
F,执行完servlet后,返回响应,客户端浏览器根据响应呈现效果。
从图上可以看出,不同的用户请求并发使用同一个Servlet实例,这是一个比较重要的基础机制。
Container解析Http请求后,实例化Servlet,因为是Http请求,会执行HttpServlet的代码:
首先会执行HttpServlet中的service(ServletRequest req, ServletResponse res)方法:
- public void service(ServletRequest req, ServletResponse res)
- throws ServletException, IOException {
- HttpServletRequest request;
- HttpServletResponse response;
- try {
- request = (HttpServletRequest) req;//请求转换成Http请求
- response = (HttpServletResponse) res;//响应转换成Http响应
- } catch (ClassCastException e) {
- throw new ServletException("non-HTTP request or response");
- }
- service(request, response);//调用处理Http的service方法
- }
然后会调用service(HttpServletRequest req, HttpServletResponse resp)方法:
- protected void service(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- String method = req.getMethod();//取得req中的方法类型
- if (method.equals(METHOD_GET)) {//根据方法类型来决定执行后续的方法,我们只关注doGet和doPost
- long lastModified = getLastModified(req);
- if (lastModified == -1) {
- doGet(req, resp);
- } else {
- long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
- if (ifModifiedSince < (lastModified / 1000 * 1000)) {
- maybeSetLastModified(resp, lastModified);
- doGet(req, resp);//如此我们就能执行到自己写的doGet方法,从而执行自己的业务逻辑。
- } 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 {//不属于http的方法类型,返回501错误
- 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);
- }
- }
我们自己实现的Servlet,我们只要继承HttpServlet,实现doGet就ok了:
- public class HelloWorld extends HttpServlet{
- private static final long serialVersionUID = 1L;
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- System.out.println("test");
- getServletContext().getRequestDispatcher("/jsp/test.html").forward(req, resp);
- }
- }
来关注下Servlet运行时需要注意的:
A,Servlet生命周期:
servlet类加载--->实例化--->服务--->销毁
B,其中牵涉到3个方法代表了Servlet的生命周期:
1、init方法:负责初始化Servlet对象。
2、service方法:负责响应客户的请求。
3、destroy方法:当Servlet对象退出生命周期时,负责释放占用的资源。
C,执行自己Servlet时需要用到的几个重要参数:
1,HttpSession:一次连结到客户端关闭,从客户端连接的层面来管理。
2,ServletConfig:从一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对本servlet 有效,一个servlet的ServletConfig对象不能被另一个servlet访问。 从单个servlet的层面来管理。
3,ServletContext:对任何servlet,任何人在任何时间都有效,这才是真正全局的对象。从全部的servlet的层面来管理
4,HttpServletRequest,HttpServletResponse:从单个servlet的单次响应侧面来管理
- Servlet 分析
- servlet线程安全问题分析
- Servlet过滤器原理分析
- servlet多线程分析
- Servlet细节分析
- servlet线程安全问题分析
- Servlet源码分析
- servlet 原理分析
- JSP Servlet性能分析
- Servlet分析(1)
- Servlet分析(2)
- Servlet 运行过程分析
- servlet源码分析--转
- servlet工作原理分析
- Servlet源码分析【转】
- Servlet系统架构分析
- Servlet处理流程分析
- Servlet使用分析
- ORA-01480 trailing null missing from STR bind value
- php对象serialize、unserialize时与sleep、wakeup的关系
- C语言:编程实现从键盘上输入一组数据,用冒泡排序进行排序输出
- Android音频系统之音频框架
- 在IIS中启用父路径,不被黑客利用
- Servlet 分析
- No8.面向对象
- 深入理解C语言指针奥秘系列文章(全)
- 好文章——Web应用的组件化开发(一)
- 2013-线程同步的使用
- Linux Debugging(四): 使用GDB来理解C++ 对象的内存布局(多重继承,虚继承)
- Tomcat 工作原理【转】
- 笔记:《Agile software Development》第1章 敏捷实践
- excel导出传入datatable,计算运行时间