注:以下内容可能不完全准确,仅供参考。

2008-09-28 00:25 

 <%! 定义 %>与 <% 定义 %>区别如下,一切尽在代码中。 


Jsp: 


<%@ page contentType="text/html; charset=GBK" %> 

<!--定义方式1 --> 

<% int j=1;%> 

<!--定义方式2 --> 

<%! int j=0;%> 

<html> 

<head> 

<title> 

jsp1 

</title> 

</head> 

<body bgcolor="#ffffff"> 

<h1> 


<!-- 

调用定义方式1的变量 

--> 

<%=j%> 

<br> 

<!-- 

调用定义方式2的变量 

--> 

<%=this.j%> 

</h1> 

</body> 

</html> 


反编译的Java jsp1_0002ejsp_jsp.class: 


import java.io.IOException; 

import javax.servlet.*; 

import javax.servlet.http.*; 

import javax.servlet.jsp.*; 

import org.apache.jasper.runtime.HttpJspBase; 

import org.apache.jasper.runtime.JspException; 


public class jsp1_0002ejsp_jsp extends HttpJspBase 

{ 


 public jsp1_0002ejsp_jsp() 

 { 

 j = 0; 

 } 


 public final void _jspx_init() 

 throws JspException 

 { 

 } 


 public void _jspService(HttpServletRequest request, HttpServletResponse response) 

 throws ServletException, IOException 

 { 

 JspFactory _jspxFactory = null; 

 PageContext pageContext = null; 

 HttpSession session = null; 

 ServletContext application = null; 

 ServletConfig config = null; 

 JspWriter out = null; 

 Object page = this; 

 String _value = null; 

 try 

 { 

 if(!_jspx_inited) 

 synchronized(this) 

 { 

 if(!_jspx_inited) 

 { 

 _jspx_init(); 

 _jspx_inited = true; 

 } 

 } 

 _jspxFactory = JspFactory.getDefaultFactory(); 

 response.setContentType("text/html; charset=GBK"); 

 pageContext = _jspxFactory.getPageContext(this, request, response, "", true, 8192, true); 

 application = pageContext.getServletContext(); 

 config = pageContext.getServletConfig(); 

 session = pageContext.getSession(); 

 out = pageContext.getOut(); 

 out.write("\r\n<!--\u5B9A\u4E49\u65B9\u5F0F1 -->\r\n"); 

 //定义方式1,这里定义的只能作用在_jspService成员函数的定义之后,如果想引用定 

 //义方式2的变量只能用this应用 

 int j = 1; 

 out.write("\r\n<!--\u5B9A\u4E49\u65B9\u5F0F2 -->\r\n"); 

 out.write("\r\n<html>\r\n<head>\r\n<title>\r\njsp1\r\n</title>\r\n</head>\r\n<body bgcolor=\"#ffffff\">\r\n<h1>\r\n\r\n<!--\r\n\u8C03\u7528\u5B9A\u4E49\u65B9\u5F0F1\u7684\u53D8\u91CF\r\n-->\r\n"); 

 out.print(j); 

 out.write("\r\n<br>\r\n<!--\r\n\u8C03\u7528\u5B9A\u4E49\u65B9\u5F0F2\u7684\u53D8\u91CF\r\n-->\r\n"); 

 out.print(this.j); 

 out.write("\r\n</h1>\r\n</body>\r\n</html>\r\n"); 

 } 

 catch(Throwable t) 

 { 

 if(out != null && out.getBufferSize() != 0) 

 out.clearBuffer(); 

 if(pageContext != null) 

 pageContext.handlePageException(t); 

 } 

 finally 

 { 

 if(_jspxFactory != null) 

 _jspxFactory.releasePageContext(pageContext); 

 } 

 } 


 //定义方式2 ,<%! xxxx >就是声明一个类的成员变量,如果我们在这个jsp文件定义一个 

 //成员函数,那么只能调用此种方式的变量了 

 int j; 

 private static boolean _jspx_inited = false; 


} 


===========================================



使用jsp页面中<%! %>全局变量声明遇到的问题

一般喜欢把页面里多处要用到的变量设置成全局变量,如:

当把该变量赋值后,再次访问该页面时,该变量的值依然保存。这使得想通过用全局变量接受提交的参数时会受到一些迷惑:

if(request.getParameter("operation")!=null) 

 ID = request.getParameter("operation").trim();




当ID在前一次赋过初值后,因为另一种原因而再次访问该页面但‘operation'参数为空时,本来希望ID也为空,但实际上ID的值为上次访问该页面时赋的值。当希望通过ID的值做不同的操作时可能引起操作类型的混乱。

原因:使用<%! %>定义的变量编译成servlet后成为servlet的私有成员变量,在servlet环境中,对于一个JSP页只允许有一个结果servlet的实例在运行和响应所有的页面请求。因此,在结果servlet中所有的成员变量可以被所有的请求所共享,所以只要成员变量没有重新赋值,下次访问该页面时仍然不变。而在<% %>中定义的变量编译成servlet后成为service()方法的一个本地变量,而service()方法中的本地变量只能每响应一次请求就重建一
次。

解决的办法是将ID用<% %>定义,或在判断ID的操作后重新对ID初始化。

自己添加的内容为:

<%! 

//设置全局变量 

int i=0; 

%> 

<% 

response.setHeader("refresh","1"); 

%> 

<h1><%=++i%></h1>



该页面若编译成功后生成Servlet文件,全局变量i就会被所有客户的请求所共享,即客户端每进行一次请求,变量i就会加1。

当修改了*.jsp文件后,再次在客户端进行访问,这时全局变量i就又从0开始变化了。

全局变量和 page,request,session.application中的application变量类似。