1.生命周期
JSP与Servlet是一体的两面。基本上Servlet能实现的功能,使用JSP也能做到,因为JSP最后还是会被容器转译为Servlet源代码,编译为.class文件,加载然后生成Servlet对象。
<%@page contentType="text/html" pageEncoding="UTF-8" %>
<html>
<head>
<title>SimpleJSP</title>
</head>
<body>
<h1><%= new java.util.Date() %></h1>
</body>
</html>
由容器转移后的Servlet如下:
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implments org.apache.jasper.runtime.JspSourceDependent {
//...
public void _jspInit() {
//...
}
public void _jspDestroy() {
}
public void _jspService(HttpServletRequest request,
HttpServletResponse, response)
throws java.io.IOException, ServletException {
//...
}
}
在编写Servlet时,可以重写init()方法进行Servlet的初始化,重写destroy()进行Servlet销毁前的收尾工作。JSP在转译为Servlet并加载生成对象之后,会调用_jspInit()方法进行初始化工作,而销毁前则是调用_jspDestroy()方法进行善后工作。请求的到来则是调用_jspService()方法。至于为何是分别调用这三个方法,如果是在Tomcat中,由于转译后的Servlet是继承自HttpJspBase类,查看该类的源码会发现为什么。
package org.apache.jasper.runtime;
//...
public abstract class HttpJspBase extends HttpServlet implments HttpJspPage {
//...
public final void init(ServletConfig config) throws ServletException{
super.init(config);
jspInit();
_jspInit()
}
//...
public final void destroy() {
jspDestroy();
_jspDestroy();
}
public final void service(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException {
_jspService(request, response);
}
public void jspInit(){};
public void _jspInit(){};
public void jspDestroy(){};
protected void _jspDestroy(){};
public abstract void _jspService(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException{};
}
名称中带下划线的方法表示这些方法是由容器转译是维护的,我们不应该重写这些方法。如果想要做些JSP初始化或者收尾工作,则应定义jspInit()或者jspDestroy()方法。
2.页面元素
JSP页面中的元素包括指令,声明,Scriptlet,表达式,注释等。
指令的主要目的是指示容器在转译时必须遵守的一些信息。JSP常用的指令有3种:page,include,taglib。
page指令告诉容器如何转移目前的JSP,最常用的属性有:import,cotentType,pageEncoding。
<%@page import="java.util.Date" %>
<%@page contentType="text/html" pageEncoding="UTF-8" %>
include指令告诉容器将别的JSP包括进来进行转译:
<%@page contentType="text/html" pageEncoding="UTF-8" %>
<%@include file="WEB-INF/jspf/header.jspf" %>
<h1>include 示例</h1>
<%@include file="WEB-INF/jspf/footer.jspf" %>
转译后的Servlet类具有哪些成员或方法,在编写JSP时,可以由声明元素,Scriptlet元素和表达式元素指定。
声明元素的语法:<%! 类成员或方法%>
在<%!与%>之间声明的代码,都将转译为Servlet中的类成员或方法。声明jspInit()与jspDestroy()就是在<%!与%>之间的。
Scriptlet元素语法:<% Java语句%>
<%与%>之间包括的内容将被转译为Servlet源码中_jspService()方法中的内容。
<%
String name = request.getParameter("name");
String password = request.getParameter("password");
if(checkUser(name, password)) {
%>
<h1>登录成功</h1>
<%
}
else {
%>
<h1>登录失败</h1>
<%
}
%>
这段JSP中的Scriptlet,转移后,会有如下源码:
package org.apache.jsp;
//...
public final class login_jsp
extends org.apache.jasper.runtime.HttpJspBase
implments org.apache.jasper.runtime.JspSourceDependent {
//...
public void _jspService(HttpServletRequest request,
HttpServletResponse reponse)
throws java.io.IOException, ServletException {
//...
String name = request.getParameter("name");
String password = request.getParameter("password");
if(checkUser(name, password)) {
out.write("\n");
out.write(" <h1>登录成功</h1>\n");
}
else {
out.write("\n");
out.write(" <h1>登录失败</h1>\n");
}
//...
}
}
表达式元素语法:<%= Java表达式%>
注意表达式元素中不要加分号。
下面的例子综合使用了声明,Scriptlet和表达式元素:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%!
String name = "hopestar";
String password = "863230";
boolean checkUser(String name, String password) {
return this.name.equals(name) && this.password.equals(password);
}
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页面</title>
</head>
<body>
<%
String name = request.getParameter("name");
String password = request.getParameter("password");
if(checkUser(name, password)) {
%>
<h1><%= name %> 登录成功</h1>
}
else {
%>
<h1>登录失败</h1>
<%
}
%>
</body>
</html>
在JSP中要输出<%或者%>需要使用替换字符,要输出<%,可以使用<%,输出%>。可以使用%>。
注释元素有两种:
<!-- 注释内容 -->
在转译后会产生out.write("<!-- 注释内容 -->");这样一条语句,所以这个注释会输出到浏览器成为HTML注释,查看HTML源码时会看到这行注释。
<%-- 注释内容 --%>
生成的Servlet中不会包括注释文字,不会输出值浏览器。