JSP、EL、JSTL、MVC软件结构
回顾
Cookie对象
与Cookie操作相关的方法
Cookie类的方法 | 作用 |
---|---|
Cookie(String name,String value) | 构造方法,通过键和值创建一个对象 |
void setMaxAge(int expiry) | 设置Cookie过期的时间 1. 正数:秒为单位 2. 零:删除 3. 负数:浏览关闭就失效 |
void setPath(String path) | 设置获取Cookie的访问路径 |
服务器写入到浏览器端的Cookie方法
response的方法 |
---|
addCookie(Cookie对象) |
浏览器读取到服务器的Cookie的方法
request的方法 |
---|
Cookie[] getCookies() 返回一个数组,如果没有就返回NULL |
Session对象
得到Session对象的方法
request的方法 |
---|
HttpSession getSession() 第一次是创建一个会话,以后是获取会话对象 |
HttpSession类的API
HttpSession接口方法 | 作用 |
---|---|
String getId() | 获取会话的ID |
long getCreationTime() | 获取会话创建的时间,返回毫秒。 java.sql.Timestamp 包含日期和时间 java.sql.Date 只包含日期 java.sql.Time 只包含时间 它们共同的父类是:java.util.Date |
boolean isNew() | 判断这个会话是否是新的 |
修改会话过期的三种方式
- setMaxInactiveInterval(秒)
- web.xml中配置session-config 子元素 session-timeout 分钟
- invalidate() 马上过期
学习目标
- JSP
- 能够说出jsp的优势
- 能够编写jsp代码片段、声明、脚本表达式
- EL:
- 能够说出el表达式的作用
- 能够使用el表达式获取javabean的属性
- JSTL
- 能够使用jstl标签库的if标签
- 能够使用jstl标签库的foreach标签
- 能够使用jstl标签库的choose标签
- MVC
- 能够说出开发模式的作用
- 能够使用三层架构模式完成显示用户案例
学习内容
1. JSP的特点:初体验
目标
- 了解JSP的特点
- 体验第1个JSP的编写
概念
JSP:Java Server Page (Java服务器端的页面,运行在服务器上的页面)
用户在浏览器端看到的页面,其实是JSP运行的结果。
JSP的第1个案例
需求
在浏览器上输出服务器当前的时间,并且设置样式
运行效果
代码
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>第一个JSP页面</title>
</head>
<body>
<!-- HTML的注释 -->
<%--
JSP其实就是在网页中可以编写Java代码,Java代码与网页并存
需求:在浏览器上输出服务器当前的时间,并且设置样式
所有的Java代码写在 <% 中间 %>
--%>
<h1 style="color: darkgreen">
<%
//创建现在的时间
Date date = new Date();
//指定格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = dateFormat.format(date);
//输出到浏览器,在JSP中Servlet常用的9个内置对象可以直接使用:out就是其中一个
out.print(format);
%>
</h1>
</body>
</html>
小结
-
JSP上可以同时编写:
1. HTML 2. Java代码
-
Java代码写以下格式中:
<% %>
-
在浏览器上能否看到Java代码?
不能,在浏览器上看到的只是JSP运行的结果
2. JSP与Servlet之间的关系
目标
了解JSP与Servlet之间是什么关系
JSP的执行过程
- JSP代码由Tomcat翻译成Servlet
- 由JVM将Servlet编译成字节码文件,再运行
疑问
-
Servlet生成在哪个位置?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KFhraQIV-1599043147013)(assets/image-20200902090649910.png)]
C:\Users\Administrator\.IntelliJIdea2019.1\system\tomcat\Tomcat_8_5_51_JavaEE143_9\work\Catalina\localhost\day30_01_jsp_war_exploded\org\apache\jsp\
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EJJNhZmw-1599043147027)(assets/image-20200902090733773.png)]
-
JSP和Servlet是什么关系?
public final class demo1_jsp extends org.apache.jasper.runtime.HttpJspBase public abstract class HttpJspBase extends HttpServlet JSP本质上就是一个Servlet
小结
-
JSP的执行过程有哪两个阶段?
- 把JSP翻译成Servlet
- 把Servlet编译成字节码文件
-
JSP与Servlet是什么关系?
JSP本质上就是一个Servlet
3. JSP的3种脚本元素【了解】
目标
学习使用JSP的三种脚本元素
- 代码片段
- 表达式
- 声明
三种脚本元素就是在JSP页面中编写Java代码的方式,以后不建议在JSP上写过多的Java代码。
3.1 表达式
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP的三种脚本元素</title>
</head>
<body>
<h1>表达式</h1>
<%--
语法: <%=变量名%>
作用:在页面上输出变量的值,本质上相当于这句话:out.print(变量名)
--%>
<%
//定义一个变量
String name = "孙悟空";
%>
姓名: <%=name%>
</body>
</html>
生成的Servlet的代码:
out.print和out.write有什么区别?
print的方法重载比较多,可以输出任意类型的数据都可以。
out.write()输出的类型相对比较少
out.print()底层其实是调用了out.write()方法
public void print(int i) {
write(String.valueOf(i));
}
3.2 代码片段
<h1>代码片段</h1>
<%--
语法:<% Java代码 %>
作用:在JSP中编写任何的Java代码,只要符合Java语法规则都可以
--%>
<%
//注释:符合Java的语法规则
for (int i = 0; i < 5; i++) {
out.print("Hello JSP <br/>");
}
%>
3.3 声明
<h1>声明</h1>
<%--
语法: <%! 声明变量或方法 %>
作用: 在JSP中声明全局变量,本质上是一个类中成员变量
--%>
<%!
String name = "白骨精";
%>
输出局部变量: <%=name%> <br/>
输出全局变量: <%=this.name%> <br/>
</body>
</html>
效果
完整的代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP的三种脚本元素</title>
</head>
<body>
<h1>表达式</h1>
<%--
语法: <%=变量名%>
作用:在页面上输出变量的值,本质上相当于这句话:out.print(变量名)
--%>
<%
//定义一个变量,定义在方法_jspService()中,这个变量是一个局部变量
String name = "孙悟空";
%>
姓名: <%=name%>
<h1>代码片段</h1>
<%--
语法:<% Java代码 %>
作用:在JSP中编写任何的Java代码,只要符合Java语法规则都可以
--%>
<%
//注释:符合Java的语法规则
for (int i = 0; i < 5; i++) {
out.print("Hello JSP <br/>");
}
%>
<h1>声明</h1>
<%--
语法: <%! 声明变量或方法 %>
作用: 在JSP中声明全局变量,本质上是一个类中成员变量
--%>
<%!
String name = "白骨精";
%>
输出局部变量: <%=name%> <br/>
输出全局变量: <%=this.name%> <br/>
</body>
</html>
小结
JSP三种脚本元素 | 功能 | 语法 |
---|---|---|
代码片段 | 编写Java代码的 | <% Java代码 %> |
表达式 | 相当于out.print(变量名) | <%= 变量名 %> |
JSP声明 | 声明的是全局变量,类中成员变量 | <%! 声明变量 %> |
4. JSP中九个内置对象
目标
了解JSP的内置对象
什么是JSP的内置对象
概念
JSP本质上就是一个Servlet,在Servlet中常用的一些对象可以直接在JSP上使用,不需要自己去创建。这些对象称为内置对象。一共有9个
JSP生成的Servlet源码
这个9个对象我们以前都学过,知道是哪9个就可以了
//每次请求都会执行,我们在JSP上写的所有的代码都是在这个方法中,对象名是固定的。
public void _jspService(HttpServletRequest request, HttpServletResponse response) {
PageContext pageContext;
HttpSession session = null;
ServletContext application;
ServletConfig config;
JspWriter out = null; //类似于PrintWriter,带缓存的,速度更快
Object page = this;
Throwable exception;
小结
JSP的内置对象
对象名 | 对应的类型 | 功能描述 |
---|---|---|
request | HttpServletRequest | 请求对象 |
response | HttpServletResponse | 响应对象 |
pageContext | PageContext | 页面上下文,马上就要讲了 |
session | HttpSession | 会话对象 |
application | ServletContext | 上下文对象 |
config | ServletConfig | 读取web.xml中init-param配置参数 |
out | JspWriter | 类似于PrintWriter,带缓存的,速度更快 |
page | Object | 表示this,代表当前JSP生成的Servlet对象 |
exception | Throwable | 出现在异常的页面中,表示异常对象 |
5. PageContext对象的作用
目标
- pageContext的介绍
- pageContext中方法
介绍
-
页面上下文,也是一个作用域,它的作用范围是:只在当前JSP页面起作用。到今天为止,我们一共学习了四个作用域。
-
因为JSP本质上就是一个Servlet,所以页面域的作用范围只在一个Servlet中起作用。
-
页面域中在JSP中才有用,Servlet中没有页面域这个对象。
-
作用域大小比较:
页面域 < 请求域 < 会话域 < 上下文域
-
所有的作用域,它的底层数据结构都是Map结构
页面域有关的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8ycUnFWP-1599043147040)(assets/1552907105674.png)]
效果
代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>页面上下文PageContext的方法</title>
</head>
<body>
<h2>页面上下文PageContext的方法</h2>
<h3>作用一:页面上下文是一个作用域对象</h3>
<%
//向页面域添加键和值
pageContext.setAttribute("name", "牛魔王");
//向请求域添加键和值
request.setAttribute("name", "红孩儿");
//向会话域添加键和值
session.setAttribute("name", "铁扇公主");
//向上下文域添加键和值
application.setAttribute("name", "太上老君");
//删除四个作用域中同名的键和值
//pageContext.removeAttribute("name");
//只删除其中一个作用域的键和值
//PageContext.PAGE_SCOPE = 1 页面域
//PageContext.REQUEST_SCOPE = 2 请求域
//PageContext.SESSION_SCOPE = 3 会话域
//PageContext.APPLICATION_SCOPE = 4 上下文域
pageContext.removeAttribute("name", PageContext.PAGE_SCOPE);
%>
页面域 :<%=pageContext.getAttribute("name")%> <br/>
请求域 :<%=request.getAttribute("name")%> <br/>
会话域 :<%=session.getAttribute("name")%> <br/>
上下文域 :<%=application.getAttribute("name")%> <hr/>
自动查找作用域 :<%=pageContext.findAttribute("name")%> <br/>
<h3>作用二:可以获取其它8个内置对象</h3>
<%--只要有这个对象,就可以得到页面上所有的内置对象了--%>
请求对象: <%=pageContext.getRequest()%><br/>
会话对象: <%=pageContext.getSession()%><br/>
上下文对象: <%=pageContext.getServletContext()%><br/>
</body>
</html>
小结
- pageContext中不同于其它作用域的方法:
1. removeAttribute("键") 删除所有四个作用域中键和值
2. findAttribute("键") 通过键按从小到大的顺序去查找每个使用域的值
- PageContext主要有2个功能:
- 是一个作用域对象
- 通过它可以获取其它的8个内置对象
6. JSP的指令:include
三大指令是
- include 用来包含另一个页面
- page 指定JSP页面的属性
- taglib 导入第三方标签库
指令的格式
<%@指令名 属性名="属性值"%>
include指令演示
作用
一个JSP页面包含另一个JSP页面
语法
<%@include file="被包含的页面"%>
需求
一个index.jsp和login.jsp包含另一个head.jsp
代码
<div id="header">
<%--相当于把header.jsp中原代码复制到这个位置--%>
<%@include file="header.jsp"%>
</div>
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EXH5srMl-1599043147133)(assets/image-20200902105258477.png)]
小结
include指定的语法是:
<%@include file="被包含的文件名"%>
7. JSP的指令:page
page指令概述
-
作用:设置JSP页面上功能,告诉tomcat将JSP翻译成Servlet的时候有哪些限制
-
位置:通常放在页面的最前面,但其实可以放在页面的任意位置
导包的属性
language="java" 指JSP页面上使用的编程语言,默认是Java
import="java.util.*"
如果JSP页面上使用了其它的类,需要导入包,使用这个属性导包,有两种格式:
1. 每个import属性导入一个包
2. 一个import属性导入多个包,使用逗号隔开
代码:
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date,java.text.SimpleDateFormat" %>
与编码相关的属性
contentType="text/html; charset=utf-8"
相当于servlet中这句话:
response.setContentType("text/html; charset=utf-8");
JSP页面上必须加上这句话,如果没有的话,整个页面是欧洲码表,默认是使用iso-8859-1的编码
是否会创建会话
session="true|false"
默认是true,如果设置为false,在页面上就不能使用会话对象。
是否可以使用EL
isELIgnored="true|false"
在JSP页面上默认是可以使用EL表达式语言,默认是false
如果设置为true,页面禁用表达式语言,EL表达式会原样输出。
扩展:错误页面的跳转
指定错误码
<!--指定错误码跳转到不同的页面-->
<error-page>
<error-code>500</error-code>
<!--必须以/开头, /表示web页面-->
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<!--必须以/开头, /表示web页面-->
<location>/404.jsp</location>
</error-page>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<img src="<%=request.getContextPath()%>/images/404.jpg">
</body>
</html>
指定错误的类型
<h1 style="color: darkgreen">
<%
//System.out.println(1 / 0);
String str = null;
out.print(str.length());
%>
</h1>
<error-page>
<!--只有这种错误类型,才会跳转到指定的页面-->
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/500.jsp</location>
</error-page>
小结
Page指令的属性 | 作用 |
---|---|
language=“java” | 指定JSP页面编程语言 |
import="{package.class | package.*}" | 指定要导的包,有2种格式: 1. 每个import导入一个包 2. 一个import导入多个包,使用逗号来分隔 |
contentType=“mimeType [ ;charset=characterSet ]” | 指定响应的类型和编码 |
isELIgnored=“true | false” | 设置EL表达式是否可用,true表示不可用 |
session=“true|false” | 设置会话是否可用 |
8. JSP的动作:include
三个动作
<jsp:include>
-
作用:用来包含另一个JSP页面或Servlet
-
语法:
<jsp:include page="被包含的页面"/> 必须加结束标记
include动作与指令的区别
静态包含 | 动态包含 | |
---|---|---|
语法格式 | <%@include file=“被包含的页面”%> | <jsp:include page=“被包含的页面”/> |
包含的方式 | 如果A页面包含了B页面,相当于把B页面的代码先复制到A页面中,再去翻译成Servlet | 如果A页面包含了B页面,先将B页面翻译成Servlet执行,A页面包含的是B页面执行的结果 |
生成Servlet个数 | 最终只会生成1个Servlet | 最终会生成2个Servlet |
写代码的注意什么?
如果使用静态包含,A和B页面中不能出现同名的变量定义
案例演示
需求
- 使用动态包含和静态包含分别实现index.jsp中包含header.jsp
- 观察tomcat的work目录下生成几个Servlet
代码
index.jsp
<%
int m = 4;
%>
<!--引入头部-->
<div id="header">
<%--相当于把header.jsp中原代码复制到这个位置--%>
<%--<%@include file="header.jsp"%>--%>
<jsp:include page="header.jsp"/>
</div>
header.jsp
<%
int m = 10;
%>
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0gYEaYgA-1599043147135)(assets/image-20200902114726978.png)]
小结
静态包含 | 动态包含 | |
---|---|---|
语法格式 | <%@include file=“URL”%> | <jsp:include page=“URL”/> |
包含的方式 | 包含的是页面的内容 | 包含的是页面的执行结果 |
生成Servlet个数 | 1个 | 2个 |
9. JSP的动作:forward和param
目标
- forward作用
- param的功能
案例演示
- 从demo1.jsp转发到demo2.jsp
- demo1在请求域中添加键和值,demo2看能够得到值并且输出
- demo1转发的时候带两个参数,user和age,在demo2中获取并且输出
- 汉字乱码问题的解决
注:forward下不能写注释
代码
转发前
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>forward动作</h2>
<%--
作用:相当于转发
转发的同时还可以带参数
使用jsp:param这个标签来指定参数,可以带多个参数
name参数名
value参数值
--%>
<%
//设置请求的编码,而且放在转发前的页面上
request.setCharacterEncoding("utf-8");
%>
<jsp:forward page="demo5_result.jsp">
<jsp:param name="user" value="NewBoy"/>
<jsp:param name="age" value="23"/>
<jsp:param name="job" value="搬砖"/>
</jsp:forward>
</body>
</html>
转发后
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
转发到的demo5<hr/>
接收传递过来的参数:<br/>
<%=request.getParameter("user")%><br/>
<%=request.getParameter("age")%><br/>
<%=request.getParameter("job")%><br/>
</body>
</html>
效果
小结
- forward作用:实现转发的功能
- param的功能:转发的时候带参数
10. EL的概念和它的两个作用
目标
什么是EL?
它有什么作用?
EL表达式的作用
什么是EL
Expression Language 表达式语言,是运行在JSP上一种表达式。只能运行在JSP中,不能运行HTML中。
EL本质上也是一些Java代码
作用
- 用来输出作用域中值
- 可以进行简单运算
语法
${作用域中键}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式</title>
</head>
<body>
<%--作用1:输出使用域中值--%>
<%
//向页面域添加键和值
pageContext.setAttribute("name", "牛魔王");
%>
<%--
语法:${作用域范围对象.键}
EL中对象,一共有11个对象可以使用
--%>
${pageScope.name}
<%--作用2:可以进行计算--%>
${3 * 5}
</body>
</html>
小结
EL有哪两个作用?
- 取出作用域中值
- 用于计算
11. EL取出作用域中的值【重点】
目标
使用EL从作用域中取数据
为什么要使用EL
因为JSP页面上过多的Java代码会导致页面很难维护,页面代码比较混乱。使用EL的目标是为了减少页面Java代码,甚至不写Java代码。要实现的功能代码全部放在Servlet中,JSP只做为显示数据的功能。
如果Servlet中存入数据放在作用域中,JSP从作用域中显示数据。通过EL来获取数据,显示出来
代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL取出作用域中的值</title>
</head>
<body>
<%
//向页面域添加键和值
pageContext.setAttribute("name", "牛魔王");
//向请求域添加键和值
request.setAttribute("name", "红孩儿");
//向会话域添加键和值
session.setAttribute("name", "铁扇公主");
//向上下文域添加键和值
application.setAttribute("name", "太上老君");
%>
使用EL取出作用域中值<hr/>
${pageScope.name} <br/>
${requestScope.name} <br/>
${sessionScope.name} <br/>
${applicationScope.name} <br/>
<%--相当于pageContext.findAttribute("name"),从小到大的范围自己去查找--%>
${name} <br/>
</body>
</html>
小结
作用域 | EL的写法 |
---|---|
页面域 | ${pageScope.name} |
请求域 | ${requestScope.name} |
会话域 | ${sessionScope.name} |
上下文域 | ${applicationScope.name} |
自动查找 | ${name} |
12. 使用EL取出不同数据类型的值【重点】
目标
使用EL,分别从JavaBean(实体类的属性值),Map,集合List,数组中取出它们的值
效果
代码
<%@ page import="com.itheima.entity.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>取出不同的数据类型</title>
</head>
<body>
<h2>得到JavaBean中的属性值</h2>
<%
Student student = new Student(1, "嫦娥", false, 98);
//数据必须放在作用域中
pageContext.setAttribute("stu", student);
%>
<%--使用EL取出数据,语法:${对象名键.属性名} EL支持三元运算 --%>
姓名:${stu.name} 性别:${stu.gender?"男":"女"} 成绩:${stu.score}
<hr>
<h2>得到List集合中的值</h2>
<%
ArrayList<String> names = new ArrayList<>();
names.add("牛魔王");
names.add("猪八戒");
names.add("白骨精");
request.setAttribute("names", names);
%>
<%--
${对象名[索引号]}
如果没有值,不会显示NULL,也不会报错
单独使用EL是不能遍历元素的,如果要遍历必须结合JSTL来使用
--%>
${names[0]} ${names[1]} ${names[2]} ${names[3]}
<hr>
<h2>得到数组中的值</h2>
<%
int[] arr = {50, 23, 17, 34};
session.setAttribute("arr",arr);
%>
<%--
在EL中取出数组的值,与List集合的语法是一样的
${arr[5]} 如果没有这个元素,也不会报错
--%>
${arr[0]} ${arr[3]} ${arr[5]}
<hr>
<h2>得到Map中的值</h2>
<%
HashMap<String, String> map = new HashMap<>();
map.put("stu1", "孙悟空");
map.put("stu2", "孙悟天");
map.put("stu3-stu4", "孙悟饭");
//放在作用域中
request.setAttribute("map", map);
%>
<%--
语法:${map对象.键}
map.stu3 没有这个值,默认EL认为是0
stu4 没有这个值,默认EL认为是0
0-0=0
注:如果键中包含了特殊的字符,可以写成:["键名"]
--%>
${map.stu1} ${map.stu2} ${map.stu3-stu4} 写成 ${map["stu3-stu4"]}
</body>
</html>
键名中有特殊字符的写法
["键名"]
小结
使用EL中从域中取出不同数据类型的写法,前提:对象一定要放在作用域中
数据类型 | 写法 |
---|---|
JavaBean | ${对象名.属性名} |
List | ${对象名[索引号]} |
数组 | ${对象名[索引号]} |
Map集合 | ${对象名.Map键} 或 ${对象名[“Map键”]} |
13. EL中内置对象【了解】
目标
- 在EL中获取表单的参数值
- 在EL中得到Cookie的值
概述 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eu9Kc7mb-1599043147138)(assets/image-20191121145351500.png)]
得到Cookie中的值
要点:先通过EL得到指定cookie的对象,再通过name和value得到具体的名字和值
JSP使用EL取出Cookie
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL中内置对象</title>
</head>
<body>
<%
//创建一个Cookie对象
Cookie man = new Cookie("user", "张三");
//向浏览器发送Cookie
response.addCookie(man);
%>
<%--
语法:${cookie.cookie的名字},返回的是Cookie对象,获取它的名字和值,还要调用getName和getValue的方法
第一次访问将Cookie写到浏览器端,第二次才发送给服务器。
EL中可以直接调用get开头的方法
--%>
使用EL取出Cookie的名字:${cookie.user.name} 值:${cookie.user.value}
</body>
</html>
param和paramValues使用
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WZ394APA-1599043147140)(assets/image-20200902151853843.png)]
代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>与参数相关的对象</title>
</head>
<body>
JSP表达式取出值:<br/>
<%=request.getParameter("user")%><br>
<%=request.getParameter("age")%><br>
<%--通过名字获取一组值--%>
<%=request.getParameterValues("hobby")[0]%><br>
<%=request.getParameterValues("hobby")[1]%><br>
<hr/>
EL的对象取出值:<br/>
${param.user}<br/>
${param.age}<br/>
${paramValues.hobby[0]}<br/>
${paramValues.hobby[1]}<br/>
</body>
</html>
header
得到客户端浏览器的类型:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL中获取请求头中值</title>
</head>
<body>
获取浏览器的类型:<%=request.getHeader("user-agent")%> <br/>
获取浏览器的类型:${header.user-agent} <br/>
获取浏览器的类型:${header["user-agent"]} <br/>
</body>
</html>
小结
EL内置对象 | 功能 |
---|---|
pageScope | 获取页面域中值 |
requestScope | 获取请求域中值 |
sessionScope | 获取会话域中值 |
applicationScope | 获取上下文域中值 |
param | 相当于getParameter() |
paramValues | 相当于getParameterValues() |
header | 相当于getHeader() |
cookie | c o o k i e . c o o k i e 的 名 字 . n a m e 获 取 键 < b r / > {cookie.cookie的名字.name} 获取键<br /> cookie.cookie的名字.name获取键<br/>{cookie.cookie的名字.value} 获取值 |
14. EL中各种运算符
目标
学习EL中各种运算符
算术运算符
算术运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
+ | 加 | ${1+1} | 2 |
- | 减 | ${2-1} | 1 |
* | 乘 | ${1*1} | 1 |
/或div | 除 | ${5 div 2} | 2.5 |
%或mod | 取余 | ${5 mod 2} | 1 |
比较运算符
关系运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
==或 eq | 等于(equal) | ${1 eq 1} | true |
!= 或 ne | 不等于(not equal) | ${1 != 1} | false |
< 或 lt | 小于(Less than) | ${1 lt 2} | true |
<=或 le | 小于等于(Less than or equal) | ${1 <= 1} | true |
> 或 gt | 大于(Greater than) | ${1 > 2} | false |
>=或 ge | 大于等于(Greater than or equal) | ${1 >=1} | true |
逻辑运算符 :
逻辑运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
&& 或 and | 交集(与) | ${true and false} | false |
|| 或 or | 并集(或) | ${true || false } | true |
! 或 not | 非 | ${not true} | false |
三元运算符:
判断前面的表达式,如果为真,则输出真的值,否则输出假的值
${条件表达式?真值:假值}
判空运算符:
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL中各种运算符</title>
</head>
<body>
在EL中两个整数相除,结果可能是一个小数:
${5 div 2} ${5 / 2}
<hr/>
判断运算<br/>
<%--
语法:
${empty 变量名}
1. 如果变量名在四个作用域中都不存在,返回true
2. 如果变量名是一个字符串,并且是空串,返回true
3. 如果变量名是一个集合,集合中没有元素,返回true
--%>
<%
ArrayList<String> list = new ArrayList<>();
request.setAttribute("list", list);
%>
${empty list}<br/>
${empty aaa}<br/>
${empty ""}<br/>
${empty "abc"}<br/>
${empty null}<br/>
</body>
</html>
小结
在EL中支持以下运算符的:
- 算术运算
- 比较运算
- 逻辑运算
- 三元运算
- 判空运算
15. JSTL的概念和作用
目标
- 什么是JSTL
- 它的作用是什么
什么是JSTL
JSP Standard Tag Library (JSP标准标签库),是JSP自带的一组标签,为了减少JSP上Java代码,让EL的功能变得更加强大。JSTL通常要结合EL一起使用。
使用核心标签
首先要在JSP页面上使用taglib指令,三个指令
- include
- page
- taglib语法
prefix:表示标签的前缀,通常写成c(core), uri是一个固定的标识
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
以后标签库中所有的标签语法:
<c:标签名/>
16. JSTL的标签:if标签
目标
在JSP页面上使用if标签
作用
在页面上起到判断的作用,如果条件为真,就会显示标签体中的内容,如果为假,就什么也不做。
语法
<c:if test="${判断条件}">
代码
</c:if>
JSTL的使用步骤
-
导入jstl的jar包,复制到WEB-INF/lib目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QuBLLfUI-1599043147142)(assets/image-20200902155546574.png)]
-
在JSP的页面上使用taglib标签
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
使用核心标签库中标签
<c:if test="${判断条件}"> 代码 </c:if>
示例:if标签的案例
需求:
如果用户提交的age值大于18,则显示你已经成年,否则显示未成年。
执行效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pa9FyG07-1599043147144)(assets/image-20200902155953438.png)]
代码
注:如果输入的年龄不能转换,会出现异常。不能将字符串a转成long类型
Cannot convert [a] of type [class java.lang.String] to [class java.lang.Long]
EL中自动进行类型的转换
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>if标签的使用</title>
</head>
<body>
<%--输入了c:if,按alter+enter idea会自动导入--%>
<c:if test="${param.age < 18}">
未成年人请勿访问此网站
</c:if>
<c:if test="${param.age >= 18}">
会员才可以访问
</c:if>
</body>
</html>
小结
使用JSTL标签的步骤:
- 导入2个jar包到WEB-INF/lib
- 在页面上使用taglib指令
- 在页面中使用c:标签名
17. JSTL的标签:choose标签
目标
学习使用choose,when,otherwise三个标签的使用
作用
如果要使用两个以上的多分支判断就必须使用choose标签,类似于java中switch语句
语法
choose标签是一个容器,包含两个子标签
<c:choose>
满足这个条件就执行它下面的代码,没有break,也不会穿透,类似于case
<c:when test="${判断条件}">
代码
</c:when>
<c:when test="${判断条件}">
代码
</c:when>
<c:otherwise> 类似于default
如果上面所有的条件都不满足就执行这个代码段
</c:otherwise>
</c:choose>
案例:通过输入分数,得到评级
需求
在一个表单输入一个分数,提交给自己。然后在同一个页面中根据分数输出相应的等级,80~100优秀 60~80及格 0~60不及格 其它输出分数不正确。
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W9b8LyDb-1599043147146)(assets/1544411428657.png)]
代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>多分支判断的语句</title>
</head>
<body>
<form action="demo09_choose.jsp" method="get">
分数:<input type="text" name="score">
<input type="submit" value="等级">
</form>
<%--如果分数不为空,才进行多分支的判断--%>
<c:if test="${not empty param.score}">
<c:choose>
<c:when test="${param.score >=80 && param.score<=100}">
优秀
</c:when>
<c:when test="${param.score >=60 && param.score<80}">
及格
</c:when>
<c:when test="${param.score >=0 && param.score<60}">
不及格
</c:when>
<c:otherwise>
分数有误
</c:otherwise>
</c:choose>
</c:if>
</body>
</html>
小结
- choose:容器,相当于switch
- when: 相当于case,每个判断的条件
- otherwise:相当于default
18. JSTL的标签:forEach标签【重点】
目标
循环遍历标签的使用
forEach的作用
- 类似于fori循环
- 类似于增强for循环,遍历一个集合或数组,集合或数组要放在作用域中
需求
输出1到100所有的奇数
效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pAGuhol8-1599043147148)(assets/image-20200902161709657.png)]
代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>forEach标签</title>
</head>
<body>
输出1到100所有的奇数
<hr/>
<%--
forEach标签的属性:
var 变量名,变量的值保存在页面域中
begin 循环的起始值
end 循环的结束值
step 步长,每次跨2步
--%>
<c:forEach var="i" begin="1" end="100" step="2">
${i}
</c:forEach>
</body>
</html>
属性
varStatus属性
案例:遍历集合
需求:
学生信息:包含编号,姓名,性别,成绩。
在Servlet中得到所有的学生信息,转发到JSP页面,在JSP页面上使用forEach标签,从List中输出所有的学生信息。
流程图
代码
Student.java
package com.itheima.entity;
/**
* 学生对象
*/
public class Student {
private int id; //编号
private String name; //名字
private boolean gender; //true男
private double score; //成绩
public Student(int id, String name, boolean gender, double score) {
this.id = id;
this.name = name;
this.gender = gender;
this.score = score;
}
public Student() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isGender() {
return gender;
}
public void setGender(boolean gender) {
this.gender = gender;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
Servlet代码
package com.itheima.servlet;
import com.itheima.entity.Student;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/student")
public class StudentServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 得到所有的学生信息,以后是从数据库中查询
List<Student> studentList = new ArrayList<>();
//按alt选中多行,可以一次直接输入多行代码
studentList.add(new Student(1000, "猪八戒", true, 65));
studentList.add(new Student(2000, "白骨精", false, 85));
studentList.add(new Student(3000, "嫦娥", true, 90));
studentList.add(new Student(4000, "唐僧", true, 87));
studentList.add(new Student(5000, "蜘蛛精", false, 85));
//2. 将学生信息集合放在请求域中
request.setAttribute("studentList", studentList);
//3. 转发到JSP页面上显示
request.getRequestDispatcher("demo11_for.jsp").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
JSP代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>显示学生列表</title>
</head>
<body>
<h2>学生信息列表</h2>
<table border="2" width="600">
<tr>
<th>状态</th>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>成绩</th>
</tr>
<%--
每个学生是一行信息
forEach的属性:
items:要遍历的信息,提前放在作用域中
var:遍历中每个元素,这里表示每个学生对象,是放在页面域中的
varStatus: 每次遍历元素的状态对象,需要指定对象的变量名字
有四个属性:
index: 这个元素的索引号,从0开始
count:第几个元素,从1开始
first:如果是第1个元素,返回true
last:如果是最后1个元素,返回true
--%>
<c:forEach items="${studentList}" var="student" varStatus="row">
<tr>
<td>${row.index} ${row.count} ${row.first} ${row.last}</td>
<td>${student.id}</td>
<td>${student.name}</td>
<td>${student.gender?"男":"女"}</td>
<td>${student.score}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
效果
小结
- forEach标签的作用是:
- for-i循环
- forEach遍历一个集合或数组
- 以下两个属性的作用是:
- items:要遍历的集合
- var:表示每个集合中元素,变量名放在页面域
19. 什么是MVC【重点】
目标
什么是MVC,并且使用MVC开发自己项目
概念
MVC是一种软件架构的模式,与编程语言无关
组成 | 说明 | JavaWeb中的实现 |
---|---|---|
Model | 模型:访问或存储数据 | JavaBean,业务层类,DAO层的类 |
View | 视图:显示数据 | JSP,JSTL,EL |
Controller | 控制器三大作用: 1. 获取视图层提交的数据 2. 调用模型层获取数据得到结果 3. 选择将哪个页面展示给用户 | Servlet 1. getParameter() 2. userService.login() 3. 重定向或转发代码 |
流程图
用户的所有操作都是围绕MVC来进行的,用户的首先访问的是控制器
JavaWeb中MVC实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HYKCx2U1-1599043147149)(assets/image-20200902165422452.png)]
访问流程说明
- 用户发送请求,访问控制器Servlet
- Servlet调用业务层,业务层再调用DAO层获取数据
- 将获取到的数据回到Servlet
- Servlet把数据存在作用域中,转发到JSP
- JSP上使用JSTL和EL显示数据
小结
MVC是哪三个单词缩写:
- M: Model模型层=业务层+数据访问层+JavaBean
- V: View = JSP + JSTL + EL
- C: Controller = Servlet
20. 案例part1:数据访问层、业务层【作业】
目标
- 搭建MVC和三层架构
- 编写数据访问层和业务层
案例需求
使用三层架构和MVC模式开发代码,完成首页旅游精选
案例效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Etc5O8pl-1599043147150)(assets/image-20200426160616211.png)]
实现步骤
导入jar包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G4WZxuxK-1599043147151)(assets/image-20200902170529089.png)]
SQL语句
-- 创建线路表
CREATE TABLE IF NOT EXISTS route(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(100) COMMENT '线路名',
image VARCHAR(200) COMMENT '线路图',
price DOUBLE COMMENT '价格'
);
-- 插入记录
INSERT INTO route VALUES (NULL,'【宁夏银川 双飞4天】 银川中华回乡文化园 中卫沙坡头 宁夏回族自治区博物馆 西关清真寺','images/m3a0b210f47a778170efe260bd75a2fd01.jpg', 2888),
(NULL,'【春节 莽山+东江湖+冰雪森林温泉 高铁3天 贵宾团】年夜欢迎晚宴+温泉养身宴+特色火锅+湘南风味餐+莽山农家菜','images/m3a1c3be962560ab5e4bc39146f4749973.jpg', 4666),
(NULL,'【越南下龙湾+巡洲岛+吉婆岛+河内 高铁5天 纯玩贵宾团】0购物0自费 尊享1晚国际品牌超豪华酒店+1晚巡洲岛豪华海边度假酒店海景房','images/m3a02b93b97f0764d6a3ac4fc75a30b495.jpg', 999),
(NULL,'【海南三亚+兴隆+海口+蜈支洲岛+西岛+亚龙湾+天涯海角双飞4天 超贵团】海口/三亚进 三亚/海口出 不走回头路【经典皇牌 至尊双岛】','images/m3a4a779ae66c256ebb6c4409d6f5d6ca2.jpg', 1689),
(NULL,'【湘西360°全景 张家界高铁5天】韶山 天子山 袁家界 天门山 玻璃栈道 大峡谷景区玻璃桥 凤凰古城',
'images/m3a6e5b5ba8ef83b3057c1ac58cb0a51a9.jpg', 5888),
(NULL,'【品味江西双飞4天纯玩】三清山 夜宿庐山 婺源篁岭晒秋 瓷都景德镇',
'images/m3a68de1243ad26c7e25dc5d43a0f1d5fa.jpg', 8768);
-- 查询记录
SELECT * FROM route;
表中的记录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-54fr0hFc-1599043147152)(assets/image-20200817075724519.png)]
实体类
package com.itheima.entity;
/**
* 线路对象
*/
public class Route {
private int id; //编号
private String name; //线路名
private String image; //线路图
private double price; //价格
public Route() {
}
public Route(String name, String image, double price) {
this.name = name;
this.image = image;
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Route{" +
"id=" + id +
", name='" + name + '\'' +
", image='" + image + '\'' +
", price=" + price +
'}';
}
}
mybaits核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--在控制台显示SQL语句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--定义实体类别名-->
<typeAliases>
<package name="com.itheima.entity"/>
</typeAliases>
<environments default="default">
<!--环境变量-->
<environment id="default">
<!--事务管理器-->
<transactionManager type="JDBC"/>
<!--数据源-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/day30"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--加载其它映射文件-->
<mappers>
<package name="com.itheima.dao"/>
</mappers>
</configuration>
获取会话对象的工具类
package com.itheima.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
* 会话工具类
*/
public class SqlSessionUtils {
//会话工厂的创建类->会话工厂->会话
private static SqlSessionFactory factory;
static {
//1.会话工厂的创建类
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//2.得到配置文件的输入流
try (InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml")) {
//3.创建会话工厂
factory = builder.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 得到会话对象
* @return
*/
public static SqlSession getSession() {
return factory.openSession();
}
}
编写DAO代码
package com.itheima.dao;
import com.itheima.entity.Route;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface RouteDao {
/**
* 查询所有的线路
*/
@Select("SELECT * FROM route")
List<Route> findAll();
}
package com.itheima.dao.impl;
import com.itheima.dao.RouteDao;
import com.itheima.entity.Route;
import com.itheima.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class RouteDaoImpl implements RouteDao {
@Override
public List<Route> findAll() {
//1.获取会话对象
SqlSession session = SqlSessionUtils.getSession();
//2.得到接口的代理对象
RouteDao routeDao = session.getMapper(RouteDao.class);
//3.调用接口中方法
List<Route> routes = routeDao.findAll();
//4.关闭会话
session.close();
//5.返回查询的结果
return routes;
}
}
编写业务层代码
package com.itheima.service;
import com.itheima.entity.Route;
import java.util.List;
public interface RouteService {
/**
* 查询所有的线路
*/
List<Route> findAll();
}
package com.itheima.service.impl;
import com.itheima.dao.RouteDao;
import com.itheima.dao.impl.RouteDaoImpl;
import com.itheima.entity.Route;
import com.itheima.service.RouteService;
import java.util.List;
/**
* 业务层
*/
public class RouteServiceImpl implements RouteService {
//依赖于DAO层
private RouteDao routeDao = new RouteDaoImpl();
@Override
public List<Route> findAll() {
return routeDao.findAll();
}
}
21. 案例part2:Web层
目标
-
使用Servlet来调用业务层,得到所有的书籍
-
在JSP上使用JSTL显示请求域中数据
流程图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xJZGh4xA-1599043147154)(assets/image-20200902171951762.png)]
步骤
Servlet代码
package com.itheima.servlet;
import com.itheima.entity.Route;
import com.itheima.service.RouteService;
import com.itheima.service.impl.RouteServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/route")
public class RouteServlet extends HttpServlet {
//依赖于业务层
private RouteService routeService = new RouteServiceImpl();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 调用业务层来获取所有的线路数据
List<Route> routes = routeService.findAll();
//2. 将数据放在请求域
request.setAttribute("routes", routes);
//3. 转发给list.jsp显示
request.getRequestDispatcher("/list.jsp").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
页面
index.jsp 一开始就访问Servlet
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>黑马旅游首页</title>
</head>
<body>
<%--一开始就访问route这个servlet--%>
<jsp:forward page="/route"></jsp:forward>
</body>
</html>
list.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>黑马旅游网</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/common.css">
<link rel="stylesheet" type="text/css" href="css/index.css">
</head>
<body>
<div id="header">
<!--引入头部-->
<jsp:include page="header.jsp"/>
</div>
<!-- banner start-->
<section id="banner">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel" data-interval="2000">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
<li data-target="#carousel-example-generic" data-slide-to="2"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="images/banner_1.jpg" alt="">
</div>
<div class="item">
<img src="images/banner_2.jpg" alt="">
</div>
<div class="item">
<img src="images/banner_3.jpg" alt="">
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</section>
<!-- banner end-->
<!-- 旅游 start-->
<section id="content">
<!-- 国内游 start-->
<section class="hemai_jx">
<div class="jx_top">
<div class="jx_tit">
<img src="images/icon_6.jpg" alt="">
<span>国内游</span>
</div>
</div>
<div class="heima_gn">
<div class="guonei_l">
<img src="images/guonei_1.jpg" alt="">
</div>
<div class="guone_r">
<div class="row">
<%--routes是要遍历的集合, var表示每条线路--%>
<c:forEach items="${routes}" var="route">
<div class="col-md-4">
<a href="route_detail.html">
<img src="${route.image}" alt="">
<div class="has_border">
<h3>${route.name}</h3>
<div class="price">网付价<em>¥</em><strong>${route.price}</strong><em>起</em></div>
</div>
</a>
</div>
</c:forEach>
</div>
</div>
</div>
</section>
</section>
<!-- 旅游 end-->
<!--导入底部-->
<div id="footer"></div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="js/jquery-3.3.1.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
<!--导入布局js,共享header和footer-->
</body>
</html>
小结
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JHdk70Fu-1599043147156)(assets/image-20200902172812527.png)]
学习总结
-
能够说出jsp的优势
- 既可以写java代码
- 也可以写HTML代码
-
能够编写jsp代码片段、声明、脚本表达式
组成部分 | 功能 | 语法 |
---|---|---|
JSP代码片段 | 编写Java代码 | <% Java代码 %> |
JSP脚本表达式 | 输出变量out.print() | <%=变量名 %> |
JSP声明 | 声明成员变量,全局变量 | <%!声明全局变量 %> |
JSP注释 | <%-- --%> |
- 能够说出el表达式的作用
- 获取作用域中值
- 计算
- 能够使用el表达式获取javabean的属性
${对象名.属性名}
-
能够使用jstl标签库的if标签
<c:if test="${判断条件}"> </c:if>
-
能够使用jstl标签库的choose标签
<c:choose> <c:when test="${条件}"> </c:when> <c:when test="${条件}"> </c:when> <c:otherwise> </c:otherwise> </c:choose>
-
能够使用jstl标签库的foreach标签
属性名 | 属性描述 |
---|---|
items | 要遍历的集合或数组 |
var | 每次遍历的元素 |
varStatus | 状态对象,有四属性:index,count,first,last |
begin | 从哪个元素开始 |
end | 到哪个元素结束 |
step | 步长 |
-
能够说出开发模式的作用
MVC开发模式:
M: Model = JavaBean + Service + DAO
V: View = JSP +JSTL+EL
C: Controller =Servlet
-
能够使用三层架构模式完成显示线路显示案例