1.scriptlet : <% %> ,百分号之间添加java代码块,例如<%out.print(Counter.getCount())%>
2.指令:<%@ %> 主要用于导入所需要的java文件,比如 <%@ page import ="java.util.*"%>
3.表达式:<%= %>表达式内容写在=后边,需要有返回值,不需要";" ,因为表达式是以参数的形式传递out.print()
<%=Counter.getCount()%> 会转换为<%out.print(Counter.getCount())%>
4.申明:<%! int count = 0;%> JSP声明用于申明所生成的servlet类的成员,所以可以申明方法和变量,即所有申明都会添加到类中
因此以下的代码,不能统计页面访问量,因为scriptlet中的变量会被定义在生成的servlet的方法中,每次访问count重新定义为0
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
this page count is:
<%
int cpunt = 0;
%>
<%= count++%>
</body>
</html>
需要达到统计的效果,可以将count放到申明中,代码如下
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
this page count is:
<%!
int count = 0;
%>
<%= count++%>
</body>
</html>
那么容器如何处理JSP文件的呢
1.查看指令,得到转换时可能需要的信息
2.创建HttpServlet子类
3.如果page指令有import属性,会在类文件的最上边,package下面写import语句
4.如果有申请,容器将这些申明写到类文件中,通常在类申明洗下面,服务方法前面
5.简历服务方法,服务方法的具体名为_jspService(),所生成的servlet会覆盖servlet超类的service方法,_jspService方法就由service方法调用,需要接受HttpServletRequest和HttpServletResponse参数,建立这个方法是,容器会申明并初始化所有隐式对象,
6.将普通的HTML,scriptlet和表达式放到服务方法中,完成格式化,并写入PrintWriter响应输出
除了以上四个元素之外,还有一种称为动作,
5.标准动作
<jsp:useBean id="person" class="foo.Person" scope="request"/>
person is <jsp:getProperty name="person" property="name"/>
思考:动作<jsp:include page="Header.jsp"/>和指令<%@ include file="Header.jsp"%>都可以为页面添加制定的JSP内容,有何不同呢?
1.生成的servlet代码不同,指令会在servlet中将jsp的内容和jsp页面的内容拼装成新的html,而标准动作则不会,它只是运行时调用。即指令在转换时发生,动作在运行时发生。指令是在生成servlet时合并引进来的html代码,之后如果有改动,必须重新生成,而动作是每次在运行时合并两个servlet。
2.需要注意的是指令在合并的时候需要将重用jsp的html和body标记去掉,否则这两个标记会嵌入到新的html中间
6.EL表达式
EL表达式对于显示属性的属性变得非常容易,比如Person类中有Dog属性,dog中有name属性,需要打印dog的name时,只需要如下
${person.dog.name}
这条EL表达式相当于下面
<%= ((foo.person)request.getAttribute("person")).getDog().getname() %>
${A.B}也可以表示为${A[B]},其中[]可以是数组,bean以及list
除此之外,EL表达式可以直接读取隐式对象中的属性,同时可以处理null值(参见head first servlet&JSP第八章)