JavaWeb基础学习笔记13——JSP
目录
1、JSP的概念
JSP(Java Server Pages,Java服务器端页面),可以理解为一个特殊的页面,其中既可以直接定义html标签,又可以定义Java代码。可用于简化书写。
2、JSP原理
JSP本质上就是一个Servlet。
3、JSP的脚本
注意:若出现问题:
org.apache.jasper.JasperException: 无法为JSP编译类:
JSP文件:[/index.jsp] 的第 [16] 行发生了一个错误
System.out cannot be resolved to a type
...
可以依次点击File -> Project Structure -> 修改Project SDK为1.8版本,以及Project Language Level为以8 -开头的选项。如下所示:
然后重新启动Tomcat。
JSP的脚本:JSP定义Java代码的方式。
JSP的脚本定义方式:
1、<% 代码 %>
定义的Java代码在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
2、<%! 代码 %>
定义的Java代码在JSP转换后的Java类的成员位置。如:代码块、成员变量、成员方法。
3、<%= 代码 %>
定义的Java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
4、JSP的内置对象
内置对象:在JSP页面中不需要获取和创建,可以直接使用的对象。
JSP一共有9个内置对象。
变量名 | 真实类型 | 作用 |
---|---|---|
pageContext | PageContext | 当前页面共享数据,还可以获取其它8个内置对象。 |
request | HttpServletRequest | 一次请求访问的多个资源(转发)。 |
session | HttpSession | 一次会话的多个请求间。 |
application | ServletContext | 所有用户间共享数据。 |
response | HttpServletResponse | 响应对象。 |
page | Object | 当前页面(Servlet)的对象。 |
out | JspWriter | 输出对象,把数据输出到页面上。 |
config | ServletConfig | Servlet的配置对象。 |
exception | Throwable | 异常对象。 |
4.1、pageContext对象
4.2、request对象
4.3、session对象
4.4、application对象
4.5、response对象
4.6、page对象
4.7、out对象
注意:若出现out.write()标红,需要导入jsp-api.jar包。给项目添加该包:File -> Project Structure -> Labraries -> +号 。
out对象:字符输出流对象,可以将数据输出到页面上。
out对象和response.getWriter()类似,二者的区别:
response.getWriter():
在Tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
response.getWriter()数据输出永远在out.write()之前。
out.write():
一般使用out输出。
4.3.1、案例:改造Cookies
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.net.URLDecoder" %><%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/23
Time: 18:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页</title>
</head>
<body>
<%
// //jsp已经设置好了,不用再设置
// //设置响应的消息体的数据格式以及编码
// response.setContentType("text/html;charset=utf-8");
//1、获取所有的Cookie
Cookie[] cookies = request.getCookies();
boolean flag = false; //没有cookie为lastTime则为false
//2、遍历Cookies数组
if(cookies != null && cookies.length > 0) {
for(Cookie cookie : cookies) {
//3、获取cookie名称
String name = cookie.getName();
//4、判断名称是否是:lastTIme
if("lastTime".equals(name)) {
//有该Cookie,不是第一次访问
flag = true;
//获取Cookie的value:时间
String value = cookie.getValue();
//设置Cookie的value
//获取当前时间的字符串,重新设置Cookie的值,重新发送Cookie
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
//URL编码
str_date = URLEncoder.encode(str_date, "utf-8");
//重新设置时间
cookie.setValue(str_date);
//设置cookie的存活时间
cookie.setMaxAge(60*60*24*30); //一个月
response.addCookie(cookie);
//响应数据
//URL解码
value = URLDecoder.decode(value,"utf-8");
out.write("<h1>欢迎回来,您上次访问时间为:"+value+"</h1>");
break;
}
}
}
if(cookies == null || cookies.length == 0 || flag == false ) {
//没有,第一次访问
//设置Cookie的value
//获取当前时间的字符串,重新设置Cookie的值,重新发送Cookie
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
Cookie cookie = new Cookie("lastTime",str_date);
//URL编码
str_date = URLEncoder.encode(str_date, "utf-8");
cookie.setValue(str_date);
//设置cookie的存活时间
cookie.setMaxAge(60*60*24*30); //一个月
response.addCookie(cookie);
out.write("<h1>您好,欢迎您首次访问。</h1>");
}
%>
</body>
</html>
4.8、config对象
4.9、exception对象
5、指令
1、指令的作用:
用于配置JSP页面,导入资源文件。
2、指令的格式:
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
3、指令分类:
page:配置JSP页面的。
contentType:等同于response.setContentType();
① 设置响应体的mime类型以及字符集;
② 设置当前JSP页面的编码,只能是高级的IDE才能生效。
pageEncoding:如果使用低级工具,则需要设置pageEncoding来设置页面字符集编码。
import:导包。
errorPage:当前页面发生异常后会自动跳转到指定的错误页面。
isErrorPage:标识当前页面是否是错误页面。
true:是。可以使用内置对象exception。
false:否,默认值。不可以使用对象exception。
incldue:页面包含的。导入页面的资源文件。
用法:<%@include file="top.jsp" %>
taglib:导入资源。
用法:<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
*prefix:前缀,可以自定义。
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/20
Time: 15:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page errorPage="500.jsp" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
List list = new ArrayList();
int i = 3/0;
%>
</body>
</html>
/**************************************************************************/
<%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/24
Time: 13:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isErrorPage="true" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>服务器正忙...</h1>
<%
String message = exception.getMessage();
out.print(message);
%>
</body>
</html>
top.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>页面logo页面标题</h1>
/****************************************************************************/
index.jsp:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/20
Time: 15:52
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="top.jsp"%>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h3>主体信息</h3>
</body>
</html>
6、注释
1、html注释:
<!-- -->:只能注释html代码片段
2、jsp注释(推荐使用):
<%-- --%>:可以注释所有。包括html代码片段和java代码。
7、MVC开发模式
7.1、JSP演变历史
- 早期只有servlet,只能使用response输出标签数据,非常麻烦;
- 后来有了jsp,简化了servlet的开发,但如果过度使用jsp,在jsp中既写大量的java代码,又写html表,造成难于分工写作。;
- 再后来,java的web开发,借鉴mvc开发模式,使得程序的设计更加合理。
7.2、MVC开发模式
MVC(Model View Controller):
- M(Model):模型。完成具体的业务操作,如查询数据库,封装对象。使用JavaBean。
- V(View):视图。展示数据。使用JSP。
- C(Controller):① 获取用户的输入;② 调用模型;③ 将数据交给视图进行展示。使用Servlet。
MVC的优缺点:
- 优点:① 耦合性低,方便维护,可以利于分工协作。② 重用性高。
- 缺点:使得项目架构变得复杂,对开发人员要求高。
8、EL表达式
8.1、EL的概念
EL(Expression Language,表达式语言)。
8.2、EL的作用
可以替换和简化JSP中Java代码的编写。
8.3、EL语法
语法:${表达式}
注意:JSP默认支持EL表达式。如果要忽略EL表达式,可以:
1、设置JSP中page指令中:isELIgnored="true" ,忽略当前JSP页面中所有的EL表达式;
2、\${表达式}:忽略当前这个El表达式。
8.4、EL的使用
EL的使用方式:
1、运算;
*算术运算符: + - * /(div) %(mod) ..
*比较运算符: > < >= <= == !=
*逻辑运算符:&&(and) ||(or) !(not)
*空运算符:empty
功能:用于判断字符串、集合、数组对象是否为null,或者长度是否为0。
如:${empty list}(为null或长度为0)、${not empty list}(不为null且长度>0)
2、获取值。
*EL表达式只能从域对象中获取值。
*语法:
1)${域名称.键名}:从指定域中获取指定键的值。
域名称:
① pageScope --> pageContext
② requestScope --> request
③ sessionScope --> session
④ applicationScope --> application (ServletContext)
举例:在request域中存储了name=张三
获取:${requestScope.name}
2)${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
3、获取对象、List集合、Map集合的值
1)对象:${域名称.键名.属性名}
本质上会去调用对象的getterXxx()方法。
2)List集合:${域名称\键名[索引]}
3)Map集合:写法1:${域名称.键名.key名称};写法2:${域名称\键名["key名称"]}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--<%@ page isELIgnored="true" %>--%>
<html>
<head>
<title>Title</title>
</head>
<body>
${3 > 4}
\${3 > 4}
<hr>
<h3>算术运算符</h3>
$(3+4)<br />
${3/4}<br />
${3 div 4}<br />
${3 % 4}<br />
${3 mod 4}<br />
<hr>
<h3>比较运算符</h3>
${3 == 4}
<hr>
<h3>逻辑运算符</h3>
${3 > 4 && 3 < 4}<br />
<hr />
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/24
Time: 14:35
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el获取域中的数据</title>
</head>
<body>
<%
//在域中存储数据
session.setAttribute("name","李四");
request.setAttribute("name","zhangsan");
session.setAttribute("age","23");
%>
<h3>EL获取值</h3>
${requestScope.name}
${sessionScope.age}
${name}
</body>
</html>
<%@ page import="java.util.Map" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>获取数据</title>
</head>
<body>
<%
User user = new User();
user.setUsername("张三");
user.setPassword("123");
user.setId(1);
request.setAttribute("u",user);
List list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add(user);
request.setAttribute("list",list);
Map map = new HashMap<>();
map.put("sname","李四");
map.put("sgender","male");
map.put("suser",user);
request.setAttribute("map",map);
%>
<h3>EL获取对象中的值</h3>
${requestScope.u}<br /><br />
通过的是对象的属性来获取<br />
${requestScope.u.username}<br />
${requestScope.u.password}<br />
<hr />
<h3>EL获取List值</h3>
${requestScope.list}<br />
${requestScope.list[0]}<br />
${requestScope.list[1]}<br />
${requestScope.list[2]}<br />
${requestScope.list[2].username}<br />
<hr />
<h3>EL获取Map值</h3>
${requestScope.map["sgender"]}<br />
${requestScope.map.suser.username}<br />
<h4>empty运算符</h4>
<%
String str = "abc";
request.setAttribute("str",str);
%>
${empty str}
</body>
</html>
8.4、EL的隐式对象
EL表达式中有11个隐式对象。
8.4.1、pageContext隐式对象
pageContext的功能:
1、获取JSP其它8个内置对象;
${pageContext.request.contextPath}:动态获取虚拟目录
<%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/24
Time: 15:15
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL隐式对象</title>
</head>
<body>
${pageContext.request}<br />
<h4>在JSP页面动态获取虚拟目录</h4>
${pageContext.request.contextPath}
</body>
</html>
9、JSTL标签
9.1、JSTL概念
JSTL(JavaServer Pages Tag Library,JSP标准标签库):是Apache组织提供的开源的免费的JSP标签。
9.2、JSTL作用
JSTL用于简化和替换JSP页面上的Java代码。
9.3、使用步骤
- 导入JSTL相关jar包;
- 引入标签库:taglib指令:<%@ taglib uri="" %>
- 使用标签。
9.4、常用的JSTL标签
常用的JSTL标签:
1、if :相当于Java代码的if语句。
1、属性:
test:必须属性,接收boolean表达式
如果表达式为true,则显示if标签体内容;
如果为false,则不显示if标签体内容
一般情况下,test属性值会结合El表达式一起使用
2、注意:
c:if标签没有else情况,想要else情况,可以再定义一个c:if标签
2、choose :相当于Java代码的switch语句。
1、使用choose标签声明 相当于switch声明
2、使用when标签做判断 相当于case
3、使用otherwise标签做其它情况的声明 相当于default
3、foreach :相当于Java代码的for语句。
1、完成重复的操作;
*属性:
begin:开始值
end:结束值
var:临时变量
step:步长
varStatus:循环状态对象
index:容器中元素的索引,从0开始
count:循环次数,从1开始
2、遍历容器。
*属性:
items:容器对象。
var:容器中元素的临时变量。
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %><%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/24
Time: 15:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>if标签</title>
</head>
<body>
<%--c:if标签
1、属性:
test:必须属性,接收boolean表达式
如果表达式为true,则显示if标签体内容;
如果为false,则不显示if标签体内容
一般情况下,test属性值会结合El表达式一起使用
2、注意:
c:if标签没有else情况,想要else情况,可以再定义一个c:if标签
--%>
<c:if test="true">我是真</c:if><br />
<%
//判断request域中的一个list集合是否为空,如果不为null则显示遍历集合
List list = new ArrayList<>();
list.add("aaa");
request.setAttribute("list",list);
request.setAttribute("number",3);
%>
<c:if test="${not empty list}">
遍历集合...
</c:if><br />
<c:if test="${number % 2 != 0}">
${number}为奇数
</c:if><br />
<c:if test="${number % 2 == 0}">
${number}为偶数
</c:if>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/24
Time: 15:56
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>choose标签</title>
</head>
<body>
<%--完成数字编号对应星期几的案例
1、域中存储袷数字;
2、使用choose标签取出数字(相当于switch声明);
3、使用when标签做数字判断(相当于case);
4、使用otherwise标签做其它情况的声明(相当于default)。
--%>
<%
request.setAttribute("number",3);
%>
<c:choose>
<c:when test="${number == 1}">星期一</c:when>
<c:when test="${number == 2}">星期二</c:when>
<c:when test="${number == 3}">星期三</c:when>
<c:when test="${number == 4}">星期四</c:when>
<c:when test="${number == 5}">星期五</c:when>
<c:when test="${number == 6}">星期六</c:when>
<c:when test="${number == 7}">星期日</c:when>
<c:otherwise>数字输入有误</c:otherwise>
</c:choose>
</body>
</html>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: Chen Lipeng
Date: 22/02/24
Time: 16:02
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>foreach标签</title>
</head>
<body>
<%--foreach:相当于java代码的for语句
1、完成重复的操作;
*属性:
begin:开始值
end:结束值
var:临时变量
step:步长
varStatus:循环状态对象
index:容器中元素的索引,从0开始
count:循环次数,从1开始
2、遍历容器。
*属性:
items:容器对象。
var:容器中元素的临时变量。
--%>
<c:forEach begin="1" end="10" var="i" step="2" varStatus="s">
${i}
${s.index} <%--容器中元素的索引,从0开始--%>
${s.count} <%--循环次数--%>
<br />
</c:forEach>
<hr />
<%
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list",list);
%>
<c:forEach items="${list}" var="str" varStatus="s">
${s.index}
${s.count}
${str}
<br />
</c:forEach>
</body>
</html>
9.5、练习
需求:在request域中有一个存有User对象的List集合,需要使用jstl+el将list集合数据展示到jsp页面的表格table中。
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="domain.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>test</title>
</head>
<body>
<%
List list = new ArrayList();
list.add(new User(1,"zhangsan","123"));
list.add(new User(2,"lisi","456"));
list.add(new User(3,"wangwu","789"));
request.setAttribute("list",list);
%>
<table border="1" width="500" align="center">
<tr>
<th>索引</th>
<th>id</th>
<th>姓名</th>
<th>密码</th>
</tr>
<%--数据行--%>
<c:forEach items="${list}" var="user" varStatus="s">
<c:if test="${s.count % 2 == 0}">
<tr bgcolor="red">
<td>${s.index}</td>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.password}</td>
</tr>
</c:if>
<c:if test="${s.count % 2 != 0}">
<tr bgcolor="green">
<td>${s.index}</td>
<td>${user.id}</td>
<td>${user.username}</td>
<td>${user.password}</td>
</tr>
</c:if>
</c:forEach>
</table>
</body>
</html>