什么是jsp
-
jsp是动态网络开发技术
-
jsp本质是一个servlet
-
jsp=html+java
-
jsp是在html中添加java代码
jsp原理
jsp最终会生成sevlet的java类
jsp语法和指令
注释
jsp注释格式:<%-- 注释内容–%>
html注释格式:
区别:jsp的注释不会在客户端显示,而html的注释会在客户端显示
jsp代码:
<body>
<%= new String("hahaha")%>
<%-- 注释内容--%>
<!-- 这是HTML的注释-->
</body>
客户端开发者模式会显示html注释
jsp脚本
格式:<% java代码%>
jsp会将脚本片段插入到_jspService方法中,也就是servlet的service方法中
用法:
1、java代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<% int sum=0;
for (int i=0 ;i<=100 ; i++)
{
sum+=i;
}
out.println("<h1>sum="+sum+"</h1>");%>
</body>
</html>
2、在java代码中嵌入html元素
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%for (int i = 0; i < 5; i++) {%>
<h1>hello word !!!<%=i%>
</h1>
<%}%>
</body>
</html>
表达式
格式:<%= 表达式%>
JSP 表达式可以把变量或者表达式输出到网页上,不需要 out.print() 就能输出数据。通常用于打印变量和方法的值。
<%= new String("hahaha")%>
结果:
声明语句
格式:<%! 声明语句 %>
声明语句会生成在java类中,比如声明变量和方法则相当于成员变量,成员方法,这样可以提高作用域,而脚本则会放在service方法中,因此在脚本中定义的变量则相当于局部变量。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>demo1</title>
</head>
<body>
<%!
//静态代码块
static {
System.out.println("jsp loading...");
}
//成员变量
private String name;
//成员方法
private String show(String data) {
return data;
}
%>
<% name = "ld";
out.println(show(name));%>
</body>
</html>
其中声明语句会生成在java类中:
public final class demo1_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
//静态代码块
static {
System.out.println("jsp loading...");
}
//成员变量
private String name;
//成员方法
private String show(String data) {
return data;
}
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
jsp指令
服务器会根据 JSP 指令来编译 JSP,生成 Java 文件。JSP 指令不产生任何可见输出,在生成的 Java 文件中,不存在 JSP 指令。
JSP 指令以<%@
开始,以%>
结束
指令分为3中类型:
指令 | 说明 |
---|---|
<%@page 参数… %> | 定义与页面相关的属性,例如脚本语言、错误页面和缓冲要求 |
<%@include 参数… %> | 引入其他jsp文件 |
<%@ taglib 参数… %> | 声明并导入标签库 |
常见应用
1、定制错误页面
-
<%@page 参数… %>
-
方式一在jsp中定制错误页面
错误页面jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--显示声明是否是错误页面 --%> <%@page isErrorPage="true" %> <html> <head> <title>error</title> </head> <body> <h1>出错啦</h1> </body> </html>
测试代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--指定错误页面--%> <%@page errorPage="/page/error.jsp" %> <html> <head> <title>Test</title> </head> <body> <% int i=1/0; %> </body> </html>
测试结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NoosARBj-1627483796484)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210717192143563.png)]
-
方式二 也可以指定错误页面为某张图片
错误页面jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <img src="../img/500error.png" alt="500" width="100%" height="100%"/> </body> </html>
测试jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@page errorPage="img-error.jsp" %> <html> <head> <title>Title</title> </head> <body> <% int i=1/0; %> </body> </html>
测试结果:
-
-
方式三 在web.xml中定制错误页面(修改web.xml后需要重启tomcat服务)
<error-page> <!-- 指定错误码500服务器错误--> <error-code>500</error-code> <location>/test/img-error.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/test/404error.jsp</location> </error-page>
-
include
引入其他jsp文件,一般引入共通的内容。比如很多网站的页眉页尾都是相同的,就可以将页眉页尾提取出来作为共通jsp给其他页面进行引用。
-
taglib
导入标签库,格式:<%@ taglib prefix=“自定义前缀” uri=“uri” %>
应用
共通header.jsp (虽然不是一个完整的页面,但是其他页面通过include可以将这个共通页面内容嵌入进去)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<header>这是一个页眉</header>
共通footer.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<footer>这是一个页脚</footer>
其他引入共通页面jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>include</title>
</head>
<body>
<%--引入共通的页眉内容--%>
<%@ include file="../common/header.jsp"%>
<p>这是一个段落</p>
<%--引入共通的页脚内容--%>
<%@include file="../common/footer.jsp"%>
</body>
</html>
结果:
jsp内置对象
九大内置对象
- PageContext pageContext (存东西)保存的数据只在当前页面中有效,还可以获取其他八个内置对象
- HttpSession session (存东西)保存的数据在一次会话中有效,从浏览器打开到关闭浏览器
- ServletContext application (存东西)保存的数据在整个服务器中有效,从开启服务到关闭服务
- ServletConfig config
- JspWriter out (用于输出)
- Object page 代表当前页面对象,相当于this
- HttpServletRequest request (存东西)保存的数据只在一次请求中有效,因此请求转发会携带这个数据
- HttpServletResponse response
- Throwable exception 只有声明了isErrorPage =true的时候才能使用这个对象
应用1:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--存数据--%>
<%
pageContext.setAttribute("name1", "luodan1"); //保存的数据只在当前页面中有效
request.setAttribute("name2", "luodan2"); //保存的数据只在一次请求中有效,因此请求转发会携带这个数据
session.setAttribute("name3", "luodan3"); //保存的数据在一次会话中有效,从浏览器打开到关闭浏览器
application.setAttribute("name4", "luodan4");//保存的数据在整个服务器中有效,从开启服务到关闭服务
%>
<%--取数据--%>
<%--getAttribute:查找page作用域的属性值--%>
<h2>${pageContext.getAttribute("name1")}</h2>
<%--findAttribute:查找page,session,application为优先级的作用域设置的属性值--%>
<h2>${pageContext.findAttribute("name2")}</h2>
<h2>${pageContext.findAttribute("name3")}</h2>
<h2>${pageContext.findAttribute("name4")}</h2>
</body>
</html>
结果:
jsp标签
MVC
在jsp中即写大量java代码又写大量html,虽然开发过程方便,但后期维护极其难,代码阅读性极低。
MVC开发模式:
- M: Module,模型 完成具体的业务操作,比如操作数据库 (javaBean)
- V:View,视图 展示数据 (jsp)
- C:Controller,控制器 接收请求,调用模型,将数据交给展示层进行数据展示 (Servlet)
EL表达式
jsp默认是支持EL表达式的
语法
格式:${表达式}
注意:如果想忽略EL表达式有以下两种作法:
- 在page指令中设置 isELIgnored=“true” ,注意整个jsp页面中所有的EL表达式都会被忽略
- 使用:\${表达式} 会将当前这个EL表达式进行忽略。
示例:
<body>
${3>4}
<br>
\${3>4}
</body>
结果:
运算符
-
算术运算符:+,-,*,/(div),%(mod)
-
比较运算符:>,<,==,>=,<=,!=
-
逻辑运算符:&&(and),||(or),!(not)
-
空运算符:empty 用于判断字符串,集合,数组对象是否为null或者长度是否为0
${empty list} 判断list是否为null,或者长度是否是0
${not empty list}
<% ArrayList<Object> list = new ArrayList<>(); ArrayList<Object> list2 = new ArrayList<>(); list2.add("haha"); String str1=""; String str2=null; String str3="hehe"; request.setAttribute("list",list); request.setAttribute("list2",list2); request.setAttribute("str1",str1); request.setAttribute("str2",str2); request.setAttribute("str3",str3); %> <h3>list:${empty list}</h3> <h3>list2:${empty list2}</h3> <h3>str1:${empty str1}</h3> <h3>str2:${empty str2}</h3> <h3>str3:${empty str3}</h3> <h3>非空或长度非0判断:${not empty str3}</h3>
结果:
获取值
EL表达式只能从域对象中获取值(jsp中有四个域对象)
-
语法1:${域名称.健名}
域名称:
1. pageScope (pageContext) 2. requestScope (request) 3. sessionScope (session) 4. applicaScope (applic (ServletContext))
-
语法2:${健名} :会先从最小域(pageScope<sessionScope<applicationScope)开始查找该键对应的值,直到找到为止。
示例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
pageContext.setAttribute("name2", "luodan1"); //保存的数据只在当前页面中有效
request.setAttribute("name2", "luodan2"); //保存的数据只在一次请求中有效,因此请求转发会携带这个数据
// session.setAttribute("name2", "luodan3"); //保存的数据在一次会话中有效,从浏览器打开到关闭浏览器
// application.setAttribute("name4", "luodan4");//保存的数据在整个服务器中有效,从开启服务到关闭服务
%>
<%--<h3>${pageScope.name1}</h3>--%>
<%--<h3>${requestScope.name2}</h3>--%>
<h3><${sessionScope.name2}/h3>
<%--<h3>${applicationScope.name4}</h3>--%>
<h3>${name2}</h3>
</body>
</html>
-
获取对象值 本质是去调用对象的getter方法
语法 :${域名称.健名.对象属性}
对象属性: getter方法去掉get后首字母小写
示例:
对象类:
public class User {
private String name;
private int age;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
/***
* 逻辑视图:用于展示数据用 ,只需写get方法即可被EL表达式调用
* @return
*/
public String getBirStr(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return dateFormat.format(birthday);
}
}
jsp代码:
<%@ page import="com.ld.po.User" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>getObject</title>
</head>
<body>
<%
User user=new User();
user.setName("ld");
user.setAge(23);
user.setBirthday(new Date());
pageContext.setAttribute("u",user);
%>
<h3>${u.name}</h3>
<h3>${u.age}</h3>
<h3>${u.birthday}</h3>
<h3>${u.birStr}</h3>
</body>
</html>
结果:
-
获取List集合
取出list指定下标某元素语法:${域名称.健名[索引]}
<% ArrayList<Object> list = new ArrayList<>(); list.add("hello"); list.add("jsp"); // 添加一个对象 list.add(user); request.setAttribute("list", list); %> <h3>获取list</h3> <%--获取list元素--%> <h3>${list}</h3> <h3>${list[0]}</h3> <h3>${list[1]}</h3> <h3>${list[2].name}</h3>
结果
-
获取Map
取出Map某个键对应的键值:${域名称.键名.key名}
<% HashMap<Object, Object> map = new HashMap<>(); map.put("name","bob"); map.put("age","18"); map.put("user",user); request.setAttribute("map",map); %> <h3>获取map</h3> <h3>${map.name}</h3> <h3>${map.age}</h3> <h3>${map.user.name}</h3>
结果:
隐式对象
-
EL表达式中有11个隐式对象
-
常用的隐式对象:pageContext:可以获取jsp其他八个内置对象
由于虚拟目录可以随意更改,因此可以使用EL中的隐式对象动态获取虚拟目录:${pageContext.getRequest}
<%--通过EL表达式动态获取虚拟目录--%> ${pageContext.request.contextPath}
JSTL
jstl :jsp标准标签库,是由Apache阻止提供的 免费开源的jsp标签
使用步骤
1、导入jstl的jar包
2、引入标签库:使用taglib指令
常用标签
if标签
1.导入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
其中prefix属性值可以自定义,一般定义成c
-
if标签必须属性test, test的属性值是一个boolean类型的表达式,如果表达式为true 则显示if标签体的内容,否则不显示
-
一般if标签的test属性结合EL表达式使用
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/7/19
Time: 15:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入jstl标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>IF</title>
</head>
<body>
<%--if标签,必须属性test:接收一个boolean类型的表达式,如果表达式为true则执行标签体里面的内容,否则不执行
一般if标签结果EL表达式使用--%>
<c:if test="true">
<h3>true显示啦</h3>
</c:if>
<c:if test="false">
<h3>false显示啦</h3>
</c:if>
<%
ArrayList<Object> list = new ArrayList<>();
list.add("haha");
request.setAttribute("list",list);
%>
<%--集合EL表达式--%>
<c:if test="${not empty list}">
遍历list集合
</c:if>
</body>
</html>
choose标签
choose标签相当于java中的switch
choose标签构成:
choose … 相当于switch
when … 相当于case
otherwise…相当于defaul
判断用户输入值
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>dataCollect</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/jstl/chooseTag2.jsp" method="post">
<input type="text" name="weekday" placeholder="请输入周一到周五的数字">
<input type="submit" value="提交">
</form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--使用taglib指令导入标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>chooseTag</title>
</head>
<body>
<c:choose>
<c:when test="${pageContext.request.getParameter('weekday').equals('1')}">
<c:out value="星期一"/>
</c:when>
<c:when test="${pageContext.request.getParameter('weekday').equals('2')}">
<c:out value="星期二"/>
</c:when>
<c:when test="${pageContext.request.getParameter('weekday').equals('3')}">
<c:out value="星期三"/>
</c:when>
<c:when test="${pageContext.request.getParameter('weekday').equals('4')}">
<c:out value="星期四"/>
</c:when>
<c:when test="${pageContext.request.getParameter('weekday').equals('5')}">
<c:out value="星期五"/>
</c:when>
<c:otherwise>无效输入</c:otherwise>
</c:choose>
</body>
</html>
foreach标签
两种使用模式:
-
做重复性操作
属性:
- begin:循环下标开始值
- end:循环下标结束值(包含)
- var:临时变量 ,相当于for语句中的i
- step: 步长,临时变量每次循环递增的值
- varStatus:循环状态对象
- index:索引值,也就是临时变量的值
- count:循环次数,从1开始
<c:forEach begin="0" end="10" var="i" step="1" varStatus="status"> <p>${i} ${status.index} ${status.count}</p> </c:forEach>
-
遍历数组
属性:
-
item 数组容器
-
var 临时变量
-
varStatus:
- index:数组索引值
- count:循环次数
<%--使用jstl标签遍历数组--%> <c:forEach items="${list}" var="i" varStatus="status"> ${i} ${status.index} ${status.count} <br> </c:forEach>
-
}">
<c:out value=“星期五”/>
</c:when>
<c:otherwise>无效输入</c:otherwise>
</c:choose>
foreach标签
两种使用模式:
-
做重复性操作
属性:
- begin:循环下标开始值
- end:循环下标结束值(包含)
- var:临时变量 ,相当于for语句中的i
- step: 步长,临时变量每次循环递增的值
- varStatus:循环状态对象
- index:索引值,也就是临时变量的值
- count:循环次数,从1开始
<c:forEach begin="0" end="10" var="i" step="1" varStatus="status"> <p>${i} ${status.index} ${status.count}</p> </c:forEach>
-
遍历数组
属性:
-
item 数组容器
-
var 临时变量
-
varStatus:
- index:数组索引值
- count:循环次数
<%--使用jstl标签遍历数组--%> <c:forEach items="${list}" var="i" varStatus="status"> ${i} ${status.index} ${status.count} <br> </c:forEach>
-