脚本段
脚本段就是JSP代码片段或脚本片段,嵌在“<%%>”标记中。在脚本段可以定义变量、调用方法和进行各种表达式运算,每行语句后面加入分号(因为在<%%>里面嵌入的Java代码和我们一般的Java代码没有什么区别,这和表达式是不同的)。使用JSP脚本元素可以将Java代码嵌入到JSP页面里,这些Java代码将出现在由当前JSP页面生成的Servlet中,使JSP将静态内容与动态内容分离出来。这种Java代码在Web服务器响应请求时会运行。在脚本段周围可以是原始的HTML或XML语句,在这些地方,代码段可以创建条件执行代码,或调用另一段代码。
脚本段使用格式如下:
<% Java代码 %>
Eg4:<%intcount=100;%>
<%%>是脚本段,它是在请求处理期间要执行的java代码段。脚本段可以产生输出,并把输出发送到客户端,也可以是一些流程控制语句。在脚本段中可以声明本地变量,在后面的脚本段中一样可以使用该变量。
Eg5:
<%@ page language=“java” contentType=“text/html;charset=utf-8”
pageEncoding=“utf-8”%>
Insert title here <%! //int number =0;//声明计数变量number
【结果】
每次访问都是1次,刷新网页没变化;关闭Tomcat服务器再重启仍然没变化。
<!% %>与<% %>的比较
二者的差异在于作用域和生存期:
①jsp声明中创建的名字有类范围的作用域和生存期
②jsp脚本中创建的名字有局限于方法的作用域和生存期。
二者的作用域就像是java中在类中定义一个属性A和在类的方法中定义一个属性B,类中不能引用属性B,但是在方法中可以引用属性A。
二者的生存期:
①jsp声明,例如:<%!int count=100;%><%=count++%>。 脚本中的变量生存期存在于第一个用户延续到第二个用户。。。。,如果第一个用户第一次访问时100,第二个用户访问就101,第三个用户访问时102,以此类推。。。如果服务器停止而重新启动后,则count值就返回到100。
②jsp脚本,例如:<%int count=100;%><%=count++%>。 脚本中的变量生存期存在于每个用户的访问期间,所以每次用户访问都是100。
无论声明和脚本放置的位置不同,jsp容器都是首先进行初始化声明,再执行脚本的。
【总结】
①不能在脚本中定义方法,但可以在jsp声明中定义自己的方法,因为脚本程序是局限于jspService方法中的,如果在jspservice方法中再次定义方法是不允许的。
②不能在jsp声明中使用out等隐藏对象,因为out等隐藏对象,是作用域jspservice方法中定义的。
③脚本中定义变量,不能在jsp声明中引用此变量。
④如果变量定义在方法中,则不能在方法之前使用此变量。
⑤脚本的本质就是将代码插入到Servlet的service()方法中。声明的本质其实就是将声明的变量加入到Servlet类(在任何方法之外),方法就成了Servlet()的方法。
【后台原理】
利用<%!%>声明的变量,在JSP容器转换JSP页面为Servlet类时,将作该类的实例变量或者类变量(声明时使用了static关键字),在多用户并发访问时,将导致线程安全的问题,除非你确认是单用户访问或者变量是只读的。(这里不讨论线程安全的问题)
而 <%%>,在JSP容器转换JSP页面为Servlet类时,页面中的代码会按照代码段中出现的次序,依次被转换为_jspService()方法中的代码,在脚本段生命的变量,将作为_jspService()方法中的本地变量,因此脚本段中的变量是线程安全的
表达式
JSP表达式用来把Java数据向页面直接输出信息,其使用格式如下:
<%=Java变量或返回值的方法名称%>
Eg6:<%=newjava.util.Date()%> //通过JSP表达式实现Date类对象,并输出当前的系统时间
Eg7:<%=a+b%> //输出a+b的值
Eg8:<%=user.getName()%> //输出getName()这个方法的返回值
表达式的本质:在将JSP页面转换成Servlet后,使用out.print()将表达式的值输出。这样如果user.getName()的返回值是"liky", 那么实际上在servlet中就将转换成out.print(“liky”);
注意:因此这里要注意以下两点:
①如果表达式是调用一个方法,那么这个方法必须要有返回值,而不应是void。例如:void getName(),这样的方法是不能被调用的。
②在方法的后面不能有分号。例如<%=getName();%>这是不允许的。
<%= %> 和 <% %>的比较
<%= %>中的内容会被直接打印出来,且不允许多行和分号。而<% %>中间可以写java代码段,与java语法相同。
<%= %> 会被解析成out.print();而<% %>中间的内容会直接解析成对应的代码段。
Eg9:
对应的java文件代码如下图所示:
上图中并没有看到关于i的声明,i在声明标签中会被声明成一个全局变量,如下图所示:
而且在servlet在服务器中是单实例,实例被创建要等到服务停掉才会销毁,而每次请求会执行其中的_jspService函数,这就意味如果用声明脚本声明了一个变量,那么在所有的服务请求中都会是同一个变量。