1:需要使用el表达式,专门替代 <%= %>
2:使用jstl技术专门替代 <% 这里的循环和判断 %>
1 el
1.1 el表达式概述
EL(Expression Language) 是为了使JSP写起来更加简单。是独立的语言。
在jsp页面可以直接编写el表达式的代码,用于获取jsp4大域中的数据或其他地方的数据。
1.2 el表达式的基本语法
在jsp页面上直接使用
${ 4大域中的属性名 };
取值之后,会自动将数据值输出到浏览器。
注意:
如果取不到值,则会返回一个空字符串。
1.3 el表达式的内置对象(红色为常用,但是面试建议全背下来)
就是在${在这里可以直接写的对象名就是el的内置对象}
el的内置对象一共有11个,每一个内置对象都有不同的作用:
具体的:
pageScope
requestScope
sessionScope
applicationScope
上面这4个分别与jsp中的4大域对象相对应
param 就是将浏览器传递过来的所有参数,封装成了一个param对象。使用格式: ${ param.参数名 }
paramValues
Header
headerValues
initParam 获取web.xml中的配置的全局参数
cookie 获取浏览器携带过来的cookie 格式: ${ cookie.cookie的名称 }
pageContext 就是jsp中的pageContext,在el表达式中,通常会使用这个对象来获取jsp中的其他8个对象。
例如: ${ pageContext.request.contextPath } 获取工程的绝对路径!!!(通过内置对象pageContext拿request对象,通过request对象拿getContestPath方法)
1.3.1 内置对象param的使用
目录结构
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<font color="red" size="7">${msg }</font>
<form action="${pageContext.request.contextPath }/LoginServlet" method="get">
用户名:<input type="text" value="${param.username }" name="username">
<br>
<input type="submit">
</form>
</body>
</html>
LoginServlet.java
package com.itheima.demo01_El练习;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 模拟用户登录失败,进行数据回显的效果
*/
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//提示不对 ......
request.setAttribute("msg","用户名或密码错误");
request.getRequestDispatcher("/el/login.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
1.3.2 内置对象cookie的使用
cookie.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>练习获取cookie</title>
</head>
<body>
<!-- 根据cookie名称获取cookie对象,进一步获取cookie保存的值 -->
用户请求中的cookie值是:${ cookie.remember.value }
<br>
<!-- 了解即可,因为本身就是根据cookie的名称获取的cookie对象 -->
用户请求中的cookie的名是:${ cookie.remember.name }
</body>
</html>
CookieServlet.java
package com.itheima.demo01_El练习;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 创建cookie的servlet
*/
public class CookieServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1:创建cookie
Cookie c = new Cookie("remember","helloworld.......................");
//2:设置cookie的路径
c.setPath("/");
//3:添加cookie到响应对象中
response.addCookie(c);
response.getWriter().print("ok..");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
1.4 EL表达式的运算符
支持的运算符:
算术运算符 注意: 这里面的加号,仅仅是数学上的加法运算,不存在字符串的连接运算!!!
如果字符串进行连接运算的时候,el会自动将字符串转成数字进行运算,如果转换失败,则会抛异常!!!且不区分单双引号。
逻辑运算符
比较运算符
三元运算符
empty关键字运算符 判断空的格式:
${ empty 变量名 }
通常用于判断集合或数组,如果集合不存在或者存在但是长度为0都会返回true。
判断不为空的判断格式:
${ not empty 变量名 }
通常用于判断集合或数组,必须集合存在且长度大于0才会返回true。
1.5 el表达式获取引用数据类型的值
引用数据类型:
${属性名.引用数据类型中的成员变量名} 实质上找的是getName方法
特殊情况取值:
1:集合取值
2:数组取值
3:如果属性名中包含了特殊符号的值,例如:User-Agent
使用通用的取值格式:(了解)
${ el的4个域对象名[“属性名”] }
[] 与 . 取值的区别:
[]是任意时候都能用,建议在获取数组或集合中的数据时使用。
.是名称不包含特殊符号的时候可以使用,因为格式简单,建议优先考虑使用 .
试验代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
import="java.util.ArrayList,com.itheima.demo01_El练习.User"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>引用数据类型取值</title>
</head>
<body>
<%
ArrayList<User> li = new ArrayList<User>();
li.add(new User("马尔扎哈",3));
li.add(new User("古力娜扎",30));
request.setAttribute("lii",li);
request.setAttribute("u1",new User("马尔扎哈",3));
%>
user对象的名称:${ u1.name },年龄是:${u1.age }
<br>
获取用户的浏览器相关信息:${ header["User-Agent"] }
<br>
获取集合中的0索引元素值:${ lii[0]['name'] }
<br>
获取集合中的1索引元素值:${ lii[1]['name'] }
</body>
</html>
2 jstl
2.1 jstl概述
JSTL(JavaServer Pages Standard Tag Library,JSP标准标签库)
可以在jsp页面上,编写其他的标签,实现相应的功能。
例如:使用jstl标签完成逻辑判断,循环操作等。
2.2 jstl的使用步骤
1: 需要从网上下载并解压zip文件,得到两个jar包。
2: 将两个jar包引入到工程的WEB-INF/lib目录下。
3: 在jsp页面上使用taglib指令引入jstl的核心标签库即可。
这个格式是固定死的,一点不能变(<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core“ %>)
4: 使用固定的标签格式,完成相关的效果。
2.3 jstl的判断语句
格式:
如果el运算的结果为true,则会显示这里的代码,否则不显示
扩展:(了解)
在c:if的开头标签中,有一个可选属性:var
var 可以保存el表达式判断的结果,默认会将判断的结果保存到page域中。(是true或者false)
2.4 jstl的循环语句
在jstl中可以使用c:forEach语句完成循环的操作;
格式1:(专门用于操作数字)
循环体
其中:
begin 代表开始的数字值(包含这个值)
end 代表结束的数字值(包含这个值)
step 代表步进的数字值(相当于 += )
var 代表迭代出来的每一个数字值变量名,可以通过el表达式根据变量名获取每一个元素值。
varStatus 代表循环的状态对象,在该对象中有4个常用属性:
1: first 当前是第一次循环吗
2: last 当前是最后一次循环吗
3: count 当前循环的次数
4: index 当前循环的索引是(注意:在操作数字的时候,索引与元素值是一样的)
格式2:(专门用于操作数组或集合)(包含map集合)
循环体
其中:
items 代表的就是使用el表达式从域中获取的集合或数组,也可以是map集合,如果是map默认采用entrySet的方式进行迭代。
2.5 试验代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
import="java.util.HashMap"
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>jstl的核心标签库练习---循环--判断</title>
</head>
<body>
<%
request.setAttribute("username","旺财");
%>
<h1>jstl的判断语句</h1>
<c:if test="${username==null}" var="a">
<font color="red">亲,数据空空如也...</font>
</c:if>
<c:if test="${username!=null}" var="b">
域中的username是:<div style="font-size: 50px;color: red">${username }</div>
</c:if>
<hr>
第一个if语句的表达式判断的结果是:${a } <!-- false -->
<br>
第二个if语句的表达式判断的结果是:${b } <!-- true -->
<h1>forEach循环的第一种方式(操作数字)</h1>
<c:forEach begin="1" end="50" step="7" var="i" varStatus="st">
<br>
当前这一次循环的元素值是:${i}
<br>
当前是第一次循环吗:${st.first}
<br>
当前是最后一次循环吗:${st.last}
<br>
当前循环的次数是:${st.count}
<br>
当前循环的索引是(注意:在操作数字的时候,索引与元素值是一样的):${st.index}
<hr>
</c:forEach>
<%
//保存数组
String[] arr = {"小明","小花","小强"};
request.setAttribute("myArr",arr);
//保存map集合
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("程程",28);
map.put("文强",29);
map.put("阿力",27);
request.setAttribute("myMap",map);
%>
<h1>迭代数组</h1>
<c:forEach items="${myArr }" var="s">
${s}
</c:forEach>
<h1>迭代map</h1>
<c:forEach items="${myMap }" var="en" >
${en.key}===>${en.value } <%-- 此处的en.value也可以写成en.getValue()不过没有必要,这种写法一般都是在调取不是get开头的方法时使用 --%>
</c:forEach>
</body>
</html>
3 MVC与三层架构的开发模式
3.1 mvc思想-站在模型视图和控制的角度来说的
1:jsp的model1时代,一个jsp把所有的事情做完。
缺点:
维护非常困难,扩展很不方便。
2:jsp的model2时代,把jsp用于页面数据展示,数据收集,逻辑处理,数据库操作,把数据模型类分离出来了。
缺点:
jsp的事情太多了,代码的耦合度太高了。
3:现在使用的开发模式—-MVC架构模式
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,是一个通用的软件设计思想。
好处:
可以让功能与数据和界面展示分离开,分别开发,便于维护和扩展。
流程示意图:
3.2 三层架构思想-站在整个业务流程来说的
软件开发的3层架构模式:
三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了“高内聚低耦合”的思想。
一高一低三可:
高内聚: 一个模块应该做完自己相关的事情。
低耦合:不同模块不应该有太多的紧密联系,可以分别开发,同时进行,最后结合在一起即可。
可扩展
可维护
可重用
说明:个人感觉好像这个图不太对。
4 案例—重写昨天的商品列表展示
4.1 需求
将昨天使用脚本标签展示的商品信息,采用el和jstl技术,实现即可;
4.2 技术分析
1:需要使用el表达式,专门替代 <%=%>
2:使用jstl技术专门替代 <% 这里的循环和判断 %>
4.3 案例代码步骤
1:将昨天完成的案例复制一份;
2:修改jsp页面的技术为el和jstl即可;
4.4 部分参考代码
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
import="java.util.*,com.itheima.anli04_domain.Product"
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>商品列表页面</title>
</head>
<body>
<table border="1px" width="100%">
<tr>
<th>编号</th>
<th>名称</th>
<th>市场价</th>
<th>商城价</th>
<th>图片</th>
<th>上架日期</th>
<th>描述</th>
</tr>
<c:forEach items="${li}" var="p">
<tr>
<td>${p.pid }</td>
<td>${p.pname }</td>
<td>${p.market_price }</td>
<td>${p.shop_price }</td>
<td>
<img alt="" width="50px" height="50px" src="${pageContext.request.contextPath }/${p.pimage}">
</td>
<td>${p.pdate }</td>
<td>${p.pdesc }</td>
</tr>
</c:forEach>
</table>
</body>
</html>