面幾個小節,已經把JSP程序的創建以及運行原理都介紹完了,這一小節開始介紹具體的JSP語法。JSP本質上是Servlet,Servlet是采用Java語言編寫的,所以JSP語法也是要滿足Java語法。
JSP是經過JSP引擎渲染成Servlet程序,那么渲染過程中,就需要知道渲染的規則,這些規則也就是我們需要學習的JSP基礎語法,這一小節學習JSP聲明的語法。
JSP聲明,是指:在JSP文件中,使用JSP的聲明語法,定義Java成員變量、定義Java方法。也就是說,JSP聲明是在編譯之后的JSP程序源代碼的類里面,嵌入定義的Java變量、嵌入定義的Java方法。語法規則如下所示:
<%!
在這里定義變量、定義方法
%>
注意:必須先定義JSP聲明,后續才能使用定義的JSP聲明。
案例代碼如下所示:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP基礎語法之JSP聲明</title>
</head>
<body>
<h3>JSP基礎語法之JSP聲明</h3>
<%!
// 在這里定義Java變量
int i=0;
// 在這里定義Java方法
public void demoMethod() {
System.out.println("JSP基礎語法之JSP聲明");
}
%>
<%
// 使用定義的變量
System.out.println("JSP基礎語法之JSP聲明的變量i=" + i);
// 使用定義的方法
demoMethod();
%>
</body>
</html>
啟動工程,瀏覽器訪問http://localhost:8080/servlet/demo.jsp,IDEA控制臺可以看到如下日志:
JSP聲明,你可以理解成:就是在JSP編譯之后的Servlet程序中,在該類里面定義Java變量、定義Java方法、定義代碼塊。JSP聲明中的代碼,最終會被嵌入到JSP編譯生成的Servlet類里面。查看上面JSP文件編譯之后的源代碼:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/8.5.98
* Generated at: 2024-02-24 11:31:26 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package com.gitcode.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class demo_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
// 在這里定義Java變量
int i=0;
// 在這里定義Java方法
public void demoMethod() {
System.out.println("JSP基礎語法之JSP聲明");
}
private static final JspFactory _jspxFactory= JspFactory.getDefaultFactory();
private static java.util.Map<String, Long> _jspx_dependants;
private static final java.util.Set<String> _jspx_imports_packages;
private static final java.util.Set<String> _jspx_imports_classes;
static {
_jspx_imports_packages=new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes=null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<String, Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory==null) {
synchronized (this) {
if (_el_expressionfactory==null) {
_el_expressionfactory=_jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager==null) {
synchronized (this) {
if (_jsp_instancemanager==null) {
_jsp_instancemanager=org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final HttpServletRequest request, final HttpServletResponse response)
throws java.io.IOException, ServletException {
final String _jspx_method=request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允許 GET、POST 或 HEAD。Jasper 還允許 OPTIONS");
return;
}
final PageContext pageContext;
HttpSession session=null;
final ServletContext application;
final ServletConfig config;
JspWriter out=null;
final Object page=this;
JspWriter _jspx_out=null;
PageContext _jspx_page_context=null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext=_jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context=pageContext;
application=pageContext.getServletContext();
config=pageContext.getServletConfig();
session=pageContext.getSession();
out=pageContext.getOut();
_jspx_out=out;
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>JSP基礎語法之JSP聲明</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write(" <h3>JSP基礎語法之JSP聲明</h3>\r\n");
out.write(" ");
out.write("\r\n");
out.write("\r\n");
out.write(" ");
// 使用定義的變量
System.out.println("JSP基礎語法之JSP聲明的變量i=" + i);
// 使用定義的方法
demoMethod();
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out=_jspx_out;
if (out !=null && out.getBufferSize() !=0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context !=null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
通過上面源代碼可以看到,JSP聲明中定義的代碼,最終會被嵌入到類的最前面位置,如下所示:
到此,JSP聲明的語法就介紹完啦。
今天就到這里,未完待續~~
JavaBean是特殊的Java類,使用J ava語言書寫,并且遵守JavaBean API規范。
接下來給出的是JavaBean與其它Java類相比而言獨一無二的特征:
提供一個默認的無參構造函數。
需要被序列化并且實現了Serializable接口。
可能有一系列可讀寫屬性。
可能有一系列的"getter"或"setter"方法。
JavaBean屬性
一個JavaBean對象的屬性應該是可訪問的。這個屬性可以是任意合法的Java數據類型,包括自定義Java類。
一個JavaBean對象的屬性可以是可讀寫,或只讀,或只寫。JavaBean對象的屬性通過JavaBean實現類中提供的兩個方法來訪問:
方法 | 描述 |
---|---|
getPropertyName() | 舉例來說,如果屬性的名稱為myName,那么這個方法的名字就要寫成getMyName()來讀取這個屬性。這個方法也稱為訪問器。 |
setPropertyName() | 舉例來說,如果屬性的名稱為myName,那么這個方法的名字就要寫成setMyName()來寫入這個屬性。這個方法也稱為寫入器。 |
一個只讀的屬性只提供getPropertyName()方法,一個只寫的屬性只提供setPropertyName()方法。
JavaBean 程序示例
這是StudentBean.java文件:
package com.runoob;
public class StudentsBean implements java.io.Serializable
{
private String firstName=null;
private String lastName=null;
private int age=0;
public StudentsBean() {
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public int getAge(){
return age;
}
public void setFirstName(String firstName){
this.firstName=firstName;
}
public void setLastName(String lastName){
this.lastName=lastName;
}
public void setAge(int age) {
this.age=age;
}
}
編譯 StudentBean.java 文件(最后一個實例會用到):
$ javac StudentsBean.java
編譯后獲得 StudentBean.class 文件,將其拷貝到 <JSP 項目>/WebContent/WEB-INF/classes/com/runoob,如下圖所示:
訪問JavaBean
<jsp:useBean> 標簽可以在JSP中聲明一個JavaBean,然后使用。聲明后,JavaBean對象就成了腳本變量,可以通過腳本元素或其他自定義標簽來訪問。<jsp:useBean>標簽的語法格式如下:
<jsp:useBean id="bean 的名字" scope="bean 的作用域" typeSpec/>
其中,根據具體情況,scope的值可以是page,request,session或application。id值可任意只要不和同一JSP文件中其它<jsp:useBean>中id值一樣就行了。
接下來給出的是 <jsp:useBean> 標簽的一個簡單的用法:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>useBean 實例</title>
</head>
<body>
<jsp:useBean id="date" class="java.util.Date" />
<p>日期為:<%=date %>
</body>
</html>
它將會產生如下結果:
日期為:Tue Jun 28 15:22:24 CST 2016
訪問 JavaBean 對象的屬性
在 <jsp:useBean> 標簽主體中使用 <jsp:getProperty/> 標簽來調用 getter 方法,使用 <jsp:setProperty/> 標簽來調用 setter 方法,語法格式如下:
<jsp:useBean id="id" class="bean 編譯的類" scope="bean 作用域">
<jsp:setProperty name="bean 的 id" property="屬性名"
value="value"/>
<jsp:getProperty name="bean 的 id" property="屬性名"/>
...........
</jsp:useBean>
name屬性指的是Bean的id屬性。property屬性指的是想要調用的getter或setter方法。
接下來給出使用以上語法進行屬性訪問的一個簡單例子:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>get 和 set 屬性實例</title>
</head>
<body>
<jsp:useBean id="students"
class="com.runoob.StudentsBean">
<jsp:setProperty name="students" property="firstName"
value="小強"/>
<jsp:setProperty name="students" property="lastName"
value="王"/>
<jsp:setProperty name="students" property="age"
value="10"/>
</jsp:useBean>
<p>學生名字:
<jsp:getProperty name="students" property="firstName"/>
</p>
<p>學生姓氏:
<jsp:getProperty name="students" property="lastName"/>
</p>
<p>學生年齡:
<jsp:getProperty name="students" property="age"/>
</p>
</body>
</html>
訪問以上 JSP,運行結果如下:
學生名字: 小強
學生姓氏: 王
學生年齡: 10
如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!
SP指令是指:用于設置JSP頁面相關屬性的一個語法命令,例如:設置頁面編碼字符集、導入其他包等等。JSP中提供了三個指令,分別是:page指令、include指令、taglib指令。其中page指令用于設置JSP頁面屬性,include指令用于引入其他的JSP文件,taglib指令用于引入標簽庫。這一小節內容介紹include指令的使用。
include指令作用:將指定的文件引入到當前JSP頁面里面。include指令會將引入的文件內容嵌入到當前JSP頁面中的對應位置。
<%@ include file="文件的相對路徑" %>
案例代碼:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>這是HTML頭部</title>
</head>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 引入頭部文件 --%>
<%@ include file="header.jsp" %>
<body>
<div style="background-color: cadetblue">
這是正文內容區域
</div>
<%-- 引入底部文件 --%>
<%@ include file="footer.html" %>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div style="background-color: antiquewhite;">
這是footer底部內容區域
</div>
啟動Tomcat容器,瀏覽器訪問http://localhost:8080/servlet/include.jsp,結果如下:
include指令的本質是什么呢???我們來查看下編譯之后的Java源代碼,找到上面include.jsp文件編譯之后的源文件,如下所示:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/8.5.98
* Generated at: 2024-02-25 05:06:41 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package com.gitcode.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class include_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory= javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
static {
_jspx_dependants=new java.util.HashMap<java.lang.String,java.lang.Long>(2);
_jspx_dependants.put("/footer.jsp", Long.valueOf(1708837593266L));
_jspx_dependants.put("/header.jsp", Long.valueOf(1708837593271L));
}
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages=new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes=null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory==null) {
synchronized (this) {
if (_el_expressionfactory==null) {
_el_expressionfactory=_jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager==null) {
synchronized (this) {
if (_jsp_instancemanager==null) {
_jsp_instancemanager=org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method=request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允許 GET、POST 或 HEAD。Jasper 還允許 OPTIONS");
return;
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session=null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out=null;
final java.lang.Object page=this;
javax.servlet.jsp.JspWriter _jspx_out=null;
javax.servlet.jsp.PageContext _jspx_page_context=null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext=_jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context=pageContext;
application=pageContext.getServletContext();
config=pageContext.getServletConfig();
session=pageContext.getSession();
out=pageContext.getOut();
_jspx_out=out;
out.write('\r');
out.write('\n');
out.write('\r');
out.write('\n');
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>這是HTML頭部</title>\r\n");
out.write("</head>");
out.write("\r\n");
out.write("<body>\r\n");
out.write("\r\n");
out.write("<div style=\"background-color: cadetblue\">\r\n");
out.write(" 這是正文內容區域\r\n");
out.write("</div>\r\n");
out.write("\r\n");
out.write('\r');
out.write('\n');
out.write("\r\n");
out.write("<div style=\"background-color: antiquewhite;\">\r\n");
out.write(" 這是footer底部內容區域\r\n");
out.write("</div>");
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out=_jspx_out;
if (out !=null && out.getBufferSize() !=0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context !=null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
通過上面源代碼,可以看到,使用include指令引入的兩個文件,最終都會將兩個文件中的內容直接嵌入到當前include.jsp文件里面,如下所示:
所以include指令的本質就是將引入文件中的內容,直接拼接到當前JSP頁面的對應位置。這里也就會存在一個問題,引入的JSP文件中,不能存在和當前JSP頁面相同的變量名稱,因為變量名稱相同會導致編譯失敗。另外,使用include指令引入其他的JSP文件時候,只會生成訪問的那個JSP文件的源代碼,被引入的JSP文件不會生成對應的源代碼。
以上,就是include指令的使用及其本質。
今天就到這里,未完待續~~
*請認真填寫需求信息,我們會在24小時內與您取得聯系。