Jsp在某种程度上就是一种servelt。

来看看tomcat容器如何将jsp页面翻译成一个”servlet”。

一、

F:\apache-tomcat-6.0.51\work\Catalina\localhost\day0416\org\apache\jsp

这个路径是容器翻译后的java代码和字节码文件的存放路径,当然必须在访问了这个jsp页面后才会生成,大家都知道jsp页面在第一次被访问的时候会被翻译成“类servlet”文件。

但是,如果你写一个servlet,然后部署访问后,这个路径是不会有相应字节码文件的。

二、

首先看引入的包

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

引入了servlet相关的几个包,说明这个“类servlet”文件和原始的servlet类有很大的联系。但是又有些细微差别。

public final class jsp1_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent{}

这个地方继承了apache的一个什么类,还实现了个接口,都是和jsp运行环境有关的。

三、与原生servlet的几个异同点

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

原生的servlet中有初始化方法Init(),在翻译后的“类servlet”文件,变成了_jspInit()方法。

类似的还有_jspDestroy()等方法。实现的与原生servlet类似的功能。

四、_jspService()方法

与原生servlet的类似,_jspService()也传入了HttpServletRequest request, HttpServletResponse response两个对象,这样就能与容器良好的适配了。

异常也同样的跑出了ServletException,如果有输出还会抛出IOException。

(测试了一下,如果jsp里是一个空页面,任何内容都没有,仍然会抛出IO异常,并且response.setContentType(“text/html”),默认还是个页面,然后后面的的异常处理也是完整的,不会因为你内容少而减少处理)

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;

在这里声明了8个对象,其实是10个,包括传进来的请求对象、响应对象。

其中很有意思的是JspWriter _jspx_out = null; JspWriter其实就相当于PrintWriter对象,而且它还会和OutputStream对象争宠,两者在一个页面中总能用一个。

五、响应的正文内容

response.setContentType(“text/html; charset=UTF-8”)会将jsp页面中使用page指令的相关设置写进了,最重要的就是这个charset编码了。

后面异常处理语句写的非常经典,简直是异常处理的典范,值得多读几遍。

try {
      response.setContentType("text/html; charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

    out.print("</br>这里是jsp1");
    out.flush();
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else log(t.getMessage(), t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
        }

下面是源代码:

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class jsp1_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;

    try {
      response.setContentType("text/html; charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write('\r');
      out.write('\n');
      out.write("\r\n");
      out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
      out.write("<title>Insert title here</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");

    out.print("</br>这里是jsp1,引入了jsp2.jsp");
    out.flush();

      out.write("\r\n");
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else log(t.getMessage(), t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

Web学习-jsp实现servlet过程赏析的更多相关文章

  1. java web 学习总结之 Servlet/JSP 编码问题

    Servlet和JSP编码问题 字节流: 1.得到OutputStream  字节流 OutputStream os = response.getOutputStream();   用默认编码输出数据 ...

  2. java web学习总结(五) -------------------servlet开发(一)

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...

  3. java web学习总结(六) -------------------servlet开发(二)

    一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些 ...

  4. java web 学习六(servlet开发2)

    一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些 ...

  5. java web 学习五(servlet开发1)

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...

  6. 如何在java代码中调用一个web项目jsp或者servlet

    有时候需要调用一个web项目的jsp或者servlet,但是执行内部的代码,并不是打开jsp,例如需要在一段java代码中清除一个web项目中的缓存,那么可以把清除缓存的代码放在该web项目的一个se ...

  7. 【WEB】jsp向servlet传参中文乱码问题解决

    传参方式:POST.GET.link方式 servlet向jsp传中文参数msg if(username.equals("") || password.euqals("& ...

  8. [Java Web学习]JSP中uri="http://java.sun.com/jsp/jstl/core"报红错误

    在官网下载jstl.jar和standard.jar,问题解决.

  9. JSP和Servlet那些事儿系列--HTTPS

    原文:http://qingkangxu.iteye.com/blog/1614053 <JSP和Servlet那些事儿 >系列文章旨在阐述Servlet(Struts和Spring的MV ...

随机推荐

  1. nyoj_16:矩形嵌套

    DAG上的动态规划 小技巧:max_element(a, a+n)返回的是数组a从下标0的位置到下标n-1的位置中的n个元素中最大元素的地址. 题目链接: http://acm.nyist.net/J ...

  2. nyoj_5:Binary String Matching

    简单字符串匹配 题目链接 #include<iostream> #include<cstring> using namespace std; int fun(char*aa,c ...

  3. Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)

    在上一篇文章中主要写了关于爬虫过程的分析,下面是代码的实现,完整代码在:https://github.com/pythonsite/spider items中的代码主要是我们要爬取的字段的定义 cla ...

  4. 最近任务 && react文章列表

    最近任务 读书 数据分析 react深入学习 可视化大图 移动端入门 [React学习] 入门学习-文本渲染 http://www.cnblogs.com/huxiaoyun90/p/4783663. ...

  5. Linux常用命令和常见问题解决<------>第一章

    查看文件下面所有的隐藏目录:ls -al ~ ls -al ~ls -a -l ~可以发现三条命令执行结果是一致的,原因:因为ls为命令 后面的参数要以空格来区分,不论几个空格 shell都会视为一体 ...

  6. net 将手机号码中间的数字替换成星号

    Regex.Replace(link.user_tel, "(\\d{3})(\\d{5})(\\d{3})", "$1*****$3")

  7. js一些重点知识总结(二)

    第一部分:数据类型转换 1) 数据类型的种类: 数值型number.布尔型(true(1) /false (0)).字符串型(String).空类型(null)(object) 2) 数据类型自动转换 ...

  8. wampserver集成包的配置

    1.修改www/index.php    修改如下:                    $projectContents .= '<li><a href="';     ...

  9. HTML5使用Canvas来绘制图形

    一.Canvas标签: 1.HTML5<canvas>元素用于图形的绘制,通过脚本(通常是javascript)来完成. 2.<canvas>标签只是图形容器,必须使用脚本来绘 ...

  10. 花了一年时间开发的TTF2FNT字库转换软件

    TTF(True Type Font)字库是微软定义的基于windows的标准字库格式.但其由于专利保护以及无法跨平台导致TTF字库在实际应用中无法有效使用. 为此我开发了TTF2FNT字库转换软件, ...