在本章中我们将学习JSP的一些基础语法。
在我们正式开始之前,我们需要先在原来的基础之上再导入两个依赖:
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
其中JSTL
全称为Java Server pages Standarded Tag Library
,意为JSP标准标签库,主要是给我提供一个标准通用的标签库。其中包含了一系列的标签和函数。至于后面的taglibs依赖一般是和JSTL依赖一起导入,Taglibs Standard是一个标准的JSP标签集合,其中包含了一系列常用的JSP标签。
这两个标签我们做一个了解即可。
JSP中的基础语法
1.JSP表达式
JSP表达式的基本语法
<%= 变量或者表达式%>
作用:在JSP页面上输出数据
常见用法:
1.直接输出字符串
<%--1.输出字符串--%>
<%= "直接通过JSP表达式输出的对象"%>
JSP转换结果:
out.print( "直接通过JSP表达式输出的对象");
2.输出对象
<%--2.输出字符串对象--%>
<%= new String("先创建String类型后,输出此字符串")%>
<br>
<%--3.获取前端数据输出--%>
获取request中的username:
<%= request.getAttribute("username")%>
<br>
JSP转换结果:
out.print( new String("先创建String类型后,输出此字符串"));
out.write("\r\n");
out.write("<br>\r\n");
out.write("\r\n");
out.write("获取request中的username:\r\n");
out.print( request.getAttribute("username"));
out.write("\r\n");
3.通过表达式输出对象
<%--4.表达式输出--%>
根据username的值来输出不同的内容:
<%= "123".equals(request.getAttribute("username")) ? "用户名正确" : "用户名错误" %>
JSP转换结果:
out.write("根据username的值来输出不同的内容:\r\n");
out.print( "123".equals(request.getAttribute("username")) ? "用户名正确" : "用户名错误" );
我在此编写了一个简单的Servlet,其主要的功能是在request中添加参数,并且请求转发给JSP页面。
Servlet代码:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 此Servlet主要是在req中添加username的值来传递给JSP页面
req.setAttribute("username","123");
// 使用请求转发来访问页面
req.getRequestDispatcher("/JSTLLearn.jsp").forward(req,resp);
}
测试结果:
JSP表达式对Java代码的转换是使用out.print()
直接输出,而对于字符串是使用out.write("")
作为字符串输出。
2.JSP脚本片段(不能编写全局变量和方法)
JSP脚本片段的基本语法
<% Java代码 %>
我们可以直接在脚本片段中填写Java语言,这段语言可以在页面中被执行。在这段java代码中我们可以声明变量、调用方法、进行表达式运算。
我们可以写一段简单的JSP脚本片段来理解:
<%-- JSP脚本片段 --%>
<%
int x = 0;//1.声明变量
for (x = 0;x < 20 ; x++ ){
if (x % 2 == 0){
//2.进行表达式运算
x +=x;
}
}
out.write("x :" + x); //3.调用方法
%>
运行结果:
JSP转换结果:
int x = 0;//声明变量
for (x = 0;x < 20 ; x++ ){
if (x % 2 == 0){
//进行表达式运算
x +=x;
}
}
out.write("x :" + x); //调用方法
我们可以看到其中的代码在转换时没有任何改变。
3.JSP声明(可以编写全局变量和方法)
语法:
<%! 全局变量和方法%>
之前我们使用<% %>
在JSP页面中嵌入Java代码,来完成一些HTML很难完成的逻辑运算,但是我们发现其中不能编写方法,而且我们编写的代码都只会被转换到_jspService()
方法之中,对我们的使用还时有些不便。因此我们可以使用<%! %>
来在JSP页面中嵌入全局变量和方法(以及包含静态的代码块),我们称之为JSP声明。
比如:
<%!
public String name = "BugMaker2000";
static {
System.out.println("!!!");
}
public void fun(){
System.out.println("这是通过JSP定义的方法");
}
%>
JSP转换结果:
public String name = "BugMaker2000";
static {
System.out.println("!!!");
}
public void fun(){
System.out.println("这是通过JSP定义的方法");
}
目前为止我们学习了JSP中的三个基础语法:表达式<%= %>
,脚本片段<% %>
,声明<%! %>
。通过这三个语法我们可以在JSP中编写各样的Java代码,以方便我们的动态页面编写。
JSP指令
JSP指令
一般用于设置整个JSP页面的属性。
JSP指令格式:
<%@ %>
此处仅介绍两个使用频率比较高的JSP指令
,其余指令我们会在日后学习。
自定义异常页面
语法:
<%@page errorPage="自定义页面目录" %>
我们首先编写一个简单的页面:
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%@page errorPage="error/500.jsp" %>
<html>
<body>
<h2>Hello World!</h2>
<%;
int i = 1/0;
%>
</body>
</html>
很明显,页面中的int i = 1/0
这句程序是错误的,我们运行时会触发500(服务器程序错误)
的异常。此外,我们也可以使用JSP指令设置如果页面错误时显示的页面。
我们只需要添加<%@page errorPage="error/500.jsp" %>
,这个指令便是设置如果页面错误的话,错误页面是**error目录下的500.jsp页面。**而error目录下的500.jsp页面便是我们自己编写的页面,我们可以任意编辑:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>500错误页面</title>
</head>
<body>
<h1>服务器代码错误...</h1>
</body>
</html>
那么我们现在尝试访问之前的错误页面就可以得到以下结果:
我们可以看到页面自动跳转到了我们设置的错误页面了。
那么以上就是针对一个页面的错误页面自定义显示,如果我们需要修改整个服务器显示的错误页面,使用这个方法就需要在每个页面中添加这句话,这样就非常不利于日后的维护和管理,针对这个情况更好的办法便是在web.xml
中添加错误异常页面的设置。
在web.xml
中添加:
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
这个便是设置整个浏览器中遇到错误异常时显示的页面,此处为了和上面异常区分开来,我们设置404
页面无法访问时的异常。
我们编写的404.jsp
页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>404</title>
</head>
<body>
<h1>404</h1>
<hr>
<h2>您访问的页面没有找到...</h2>
</body>
</html>
测试结果:
通用页面组件设置
语法:
<%@ include file="模块页面目录" %>
在我们访问的大部分网站中,页面的导航部分和底部部分都是一样,也就是说我们可以把导航和底部作为组件,给网站的每个页面使用。
我们先编写头部以及底部页面的模块:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>
页面Header通用模块
</h1>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>页面底部组件</h1>
编写一个页面引用模块:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--引用页面头部模块--%>
<%@ include file="common/Header.jsp" %>
<h1>页面主题</h1><%-- 页面内容--%>
<%--引用页面底部模块--%>
<%@include file="common/Bottomer.jsp"%>
</body>
</html>
结果:
另外除了这个方法,我们也可以使用JSP标签
来实现这个功能。
语法:
<jsp:include page="引用页面目录">
我们可以将上述代码修改为:
<jsp:include page="common/Header.jsp"/><%--引用页面头部模块--%>
<h1>页面主题</h1><%-- 页面内容--%>
<jsp:include page="common/Bottomer.jsp"/><%--引用页面头部模块--%>
结果:
我们可以看到,<@page include="">
和<jsp:include page="">
实现出来的效果是一致的,但是实现的方法不同。
<@page include="">
是将引用的页面组合在一起合并成为一个页面,本质是一个页面,其被JSP转换之后的结果是:
out.write("<h1>\r\n");
out.write(" 页面Header通用模块\r\n");
out.write("</h1>\r\n");
out.write("\r\n");
out.write("<h1>页面主题</h1>");
out.write('\r');
out.write('\n');
out.write('\r');
out.write('\n');
out.write("\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("<h1>页面底部组件</h1>");
<jsp:include page="">
是直接将页面拼接,本质上还是三个页面,JSP转换的结果:
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "common/Header.jsp", out, false);
out.write("\r\n");
out.write("<h1>页面主题</h1>");
out.write('\r');
out.write('\n');
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "common/Bottomer.jsp", out, false);
我们可以看到<@page include="">
直接将页面的代码拼接过来而<jsp:include page="">
则是将页面通过include()
使用。