一道练习题引发的思考

    在一个JSP页面中,有如下代码,请问最终的输出结果为:

1     <%! int i = 1;%>
2     <%! int getNumber(){
3         return i;
4     }%>
5     <% int i = 10;
6         out.println("first i = "+i);%>
7     <% out.println("second i = "+i);%>
8     <% out.println("third i = "+getNumber());%>

    其输出结果为:first i = 10  second i = 10 third i = 1

   这道题容易出错的原因是在于分不清在<%! %>声明语句中声明的变量和在<% %>小脚本中声明的变量的区别,它们两个区别具体如下:JSP声明语句中声明的变量在生成Servlet后位于类的成员变量部分,属于全局变量;而JSP脚本段声明的变量在生成Servlet后位于service方法中,属于局部变量,当方法运行完后就被销毁了。Servlet是一个单实例对象,成员变量只有一个,每个用户都可访问到它,所以会污染全局变量,在多用户访问时,也不利于维护数据的正确性和安全性。

   其实 我们可以从jsp生成的.java文件看出区别,从源代码可以看出这个jsp页面程序到底是怎么执行的:

  1 package org.apache.jsp;
  2 
  3 import javax.servlet.*;
  4 import javax.servlet.http.*;
  5 import javax.servlet.jsp.*;
  6 
  7 public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
  8     implements org.apache.jasper.runtime.JspSourceDependent {
  9  //JSP声明语句声明的变量和方法,在全局部分
 10  int i = 1;
 11  int getNumber(){
 12         return i;
 13     }
 14   private static final javax.servlet.jsp.JspFactory _jspxFactory =
 15           javax.servlet.jsp.JspFactory.getDefaultFactory();
 16 
 17   private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
 18 
 19   private volatile javax.el.ExpressionFactory _el_expressionfactory;
 20   private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
 21 
 22   public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
 23     return _jspx_dependants;
 24   }
 25 
 26   public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
 27     if (_el_expressionfactory == null) {
 28       synchronized (this) {
 29         if (_el_expressionfactory == null) {
 30           _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
 31         }
 32       }
 33     }
 34     return _el_expressionfactory;
 35   }
 36 
 37   public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
 38     if (_jsp_instancemanager == null) {
 39       synchronized (this) {
 40         if (_jsp_instancemanager == null) {
 41           _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
 42         }
 43       }
 44     }
 45     return _jsp_instancemanager;
 46   }
 47 
 48   public void _jspInit() {
 49   }
 50 
 51   public void _jspDestroy() {
 52   }
 53   //JSP页面生成的Service方法,小脚本语句位于这个方法中
 54   public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
 55         throws java.io.IOException, javax.servlet.ServletException {
 56 
 57     final javax.servlet.jsp.PageContext pageContext;
 58     javax.servlet.http.HttpSession session = null;
 59     final javax.servlet.ServletContext application;
 60     final javax.servlet.ServletConfig config;
 61     javax.servlet.jsp.JspWriter out = null;
 62     final java.lang.Object page = this;
 63     javax.servlet.jsp.JspWriter _jspx_out = null;
 64     javax.servlet.jsp.PageContext _jspx_page_context = null;
 65 
 66 
 67     try {
 68       response.setContentType("text/html;charset=UTF-8");
 69       pageContext = _jspxFactory.getPageContext(this, request, response,
 70                   null, true, 8192, true);
 71       _jspx_page_context = pageContext;
 72       application = pageContext.getServletContext();
 73       config = pageContext.getServletConfig();
 74       session = pageContext.getSession();
 75       out = pageContext.getOut();
 76       _jspx_out = out;
 77 
 78       out.write("\r\n");
 79       out.write("\r\n");
 80       out.write("<html>\r\n");
 81       out.write("<head>\r\n");
 82       out.write("    <title>test</title>\r\n");
 83       out.write("</head>\r\n");
 84       out.write("<body>\r\n");
 85       out.write("    ");
 86       out.write("\r\n");
 87       out.write("    ");
 88       out.write("\r\n");
 89       out.write("    ");
 90       //JSP小脚本中声明的变量
 91       int i = 10;
 92       //JSP小脚本中的语句
 93         out.println("first i = "+i);
 94       out.write("\r\n");
 95       out.write("    ");
 96       //JSP小脚本中的语句
 97  out.println("second i = "+i);
 98       out.write("\r\n");
 99       out.write("    ");
100       //JSP小脚本中的语句
101  out.println("third i = "+getNumber());
102       out.write("\r\n");
103       out.write("</body>\r\n");
104       out.write("</html>\r\n");
105     } catch (java.lang.Throwable t) {
106       if (!(t instanceof javax.servlet.jsp.SkipPageException)){
107         out = _jspx_out;
108         if (out != null && out.getBufferSize() != 0)
109           try {
110             if (response.isCommitted()) {
111               out.flush();
112             } else {
113               out.clearBuffer();
114             }
115           } catch (java.io.IOException e) {}
116         if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
117         else throw new ServletException(t);
118       }
119     } finally {
120       _jspxFactory.releasePageContext(_jspx_page_context);
121     }
122   }
123 }
View Code

 

posted @ 2017-06-30 16:47  守明  阅读(121)  评论(0编辑  收藏  举报