# JSTL與EL表達式
[TOC]
## 導學
在之前的學習中,我們發現雖然可以在Jsp中使用Java語言,但是HTML和Java的結合好像不是那么緊密,而且操作HTML元素好像也不是那么方便。那么有沒有一種簡單的方式,來獲取值并操作HTML元素呢?
## EL表達式
EL表達式是一種非常簡單的數據表達方式,EL(Expression Language)表達式語言的出現就是為了簡化JSP的輸出。在早期的Jsp中,沒有EL表達式,所有的程序都要使用out對象來一行行的輸出。
語法:
~~~
${表達式}
~~~
實例:
~~~
public class Student {
private String name;
private String mobile;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String toString() {
return name + ":" + mobile;
}
}
~~~
~~~
@WebServlet("/info")
public class StudentServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public StudentServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Student stu = new Student();
stu.setName("子墨");
stu.setMobile(null);
String grade = "A";
request.setAttribute("grade", grade);
request.setAttribute("stu", stu);
request.getRequestDispatcher("/info.jsp").forward(request, response);
}
}
~~~
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import = "com.dodoke.el.Student"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Student stu = (Student)request.getAttribute("student");
String grade = (String)request.getAttribute("grade");
out.println("<h1>姓名:" + stu.getName() + "</h1>");
out.println("<h2>手機:" + stu.getMobile() + "</h2>");
out.println("<h2>評級:" + grade + "</h2>");
%>
</body>
</html>
~~~
EL表達式版
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>姓名:${requestScope.student.name }</h1>
<h2>手機:${requestScope.student.mobile }</h2>
<h2>評級:${requestScope.grade }</h2>
</body>
</html>
~~~
通過以上的例子,我們可以看出EL表達式的應用非常簡單,而且還不需要導入要使用的類,下面我們就來看看EL表達式的使用細節。
### EL的作用域對象
EL表達式包含四種不同的作用域:
* pageScope:從當前頁面取值
* requestScope:從當前請求中獲取屬性值
* sessionScope:從當前會話中獲取屬性值
* applicationScope:從當前應用獲取全局屬性值
這四種作用域,作用范圍從小到大,而且這四種作用域也對應了我們四種取值范圍。當我們忽略書寫這四種作用域時,el表達式將按作用域從小到大的順序依次嘗試獲取。
~~~
@WebServlet("/info")
public class StudentServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public StudentServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Student stu = new Student();
stu.setName("子墨");
stu.setMobile(null);
String grade = "A";
HttpSession session = request.getSession();
session.setAttribute("grade", grade);
session.setAttribute("stu", stu);
//request.setAttribute("grade", grade);
//request.setAttribute("stu", stu);
request.getRequestDispatcher("/info.jsp").forward(request, response);
}
}
~~~
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>姓名:${sessionScope.student.name }</h1>
<h2>手機:${sessionScope.student.mobile }</h2>
<h2>評級:${sessionScope.grade }</h2>
</body>
</html>
~~~
問:代碼修改為這樣以后該如何,得到的結果是多少?
~~~
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Student stu = new Student();
stu.setName("子墨");
stu.setMobile(null);
String grade = "A";
request.setAttribute("grade","B");
request.getServletContext().setAttribute("grade","C");
HttpSession session = request.getSession();
session.setAttribute("grade", grade);
session.setAttribute("stu", stu);
//request.setAttribute("grade", grade);
//request.setAttribute("stu", stu);
request.getRequestDispatcher("/info.jsp").forward(request, response);
}
~~~
### EL表達式輸出
語法:
~~~
${[作用域].屬性名.[子屬性名]}
~~~
el表達式支持將運算結果輸出,也支持絕大多數對象的輸出,本質是執行toString方法,也就是我們可以嘗試重寫toString方法,輸出對象的信息。

### 輸出參數
要求:查找并總結getParameter()方法和getAttribute()方法的區別
在Servlet中我們可以通過getParameter()方法來實現獲取前端瀏覽器的參數,那么如何使用el表達式來接收其他頁面傳遞的參數呢?
EL表達式內置param對象來簡化參數的輸出,它的語法:
~~~
${param.參數名}
~~~
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>姓名:${sessionScope.student.name }</h1>
<h2>手機:${sessionScope.student.mobile }</h2>
<h2>${param.teacher}</h2>
<h2>評級:${sessionScope.grade }</h2>
</body>
</html>
~~~
## JSTL標簽庫
* JSTL(JSP Standard Tag Library),JSP標準標簽庫
* JSTL用于簡化JSP開發,提高代碼的可讀性和可維護性
* JSTL由SUN(Oracle)定義規范,由Apache Tomcat團隊實現
JSTL可以幫助我們實現表格的循環,判斷,數據的迭代等功能。
### JSTL下載與安裝
el表達式,不需要下載任何的Jar包,這是因為現版本的jsp內置el表達式的實現,但是JSTL就需要下載Jar包并安裝到項目中。
下載地址:[http://tomcat.apache.org/](http://tomcat.apache.org/)
JSTL 1.2.5組件介紹:

需要下載的是一個spec的包,一個是impl包,剩下的包,el的包是為了支持el表達式,現在el已經內置標簽庫了,所以不需要下載導入即可使用。第四個jar包是為了兼容1.0以下的包而使用的 我們現在使用的是1.2.5因此無需引入。


**安裝JSTL**
JSTL的兩種安裝方式:
1. 將Jar文件復制到工程的/WEB-INF/lib目錄下(對單體項目進行設置-推薦)
2. 將Jar文件復制到Tomcat安裝目錄的lib目錄(全局設置)
### JSTL的標簽庫
JSTL按功能劃分,可分為五類標簽庫:

除了頭兩種,剩下的已經不使用了,因為在Java中提供了更好的支持。
**引用JSTL核心庫**
核心標簽庫,提供了JSTL的基礎功能,引用時需要在頁面上引入該核心庫
~~~
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
~~~
### JSTL判斷標簽
JSTL核心庫提供了兩組判斷的標簽:
* `<c:if>`用于單分支判斷
* `<c:choose>`、`<c:when>`、`<c:otherwise>`用于多分支判斷
~~~
@WebServlet("/jstl")
public class JstlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public JstlServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("score", 58);
request.setAttribute("grade", "B");
request.getRequestDispatcher("/core.jsp").forward(request, response);
}
}
~~~
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 在Java或者JSP文件中輸入 Alt + / 可出現智能提示 -->
<!-- uri指定使用哪個標簽庫,prefix指定使用時的前綴,prefix屬性的值是可以改變的,只不過我們一般習慣用c表示。 -->
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>${requestScope.score}</h1>
<!-- 簡單判斷:test屬性中填寫true或false,用于決定c:if中的HTML語句是否輸出 -->
<c:if test = "${score >= 60 }">
<h1 style = "color:green">恭喜,你已通過測試</h1>
</c:if>
<c:if test = "${score < 60 }">
<h1 style = "color:red">對不起,再接再厲</h1>
</c:if>
<!-- 復雜判斷:choose when otherwise -->
${grade }
<c:choose>
<!-- 注意單引號,在JSTL中可以使用等號進行字符串的判斷 -->
<c:when test="${grade == 'A'}">
<h2>你很優秀</h2>
</c:when>
<c:when test="${grade == 'B' }">
<h2>不錯呦</h2>
</c:when>
<c:when test="${grade == 'C' }">
<h2>水平一般,需要提高</h2>
</c:when>
<c:when test = "${grade == 'D'}">
<h2>需要努力啦,不要氣餒</h2>
</c:when>
<c:otherwise>
<h2>一切隨緣吧</h2>
</c:otherwise>
</c:choose>
</body>
</html>
~~~
### JSTL遍歷標簽
`<c:forEach>`標簽用于遍歷集合(Collection)中的每一個對象。
~~~
public class Company {
private String cname;
private String url;
public Company(String cname , String url) {
this.cname = cname;
this.url = url;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
~~~
~~~
@WebServlet("/jstl")
public class JstlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public JstlServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("score", 58);
request.setAttribute("grade", "B");
List list = new ArrayList();
list.add(new Company("騰訊" , "www.tencent.com"));
list.add(new Company("百度" , "www.baidu.com"));
list.add(new Company("渡課網" , "www.dodoke.com"));
request.setAttribute("companys", list);
request.getRequestDispatcher("/core.jsp").forward(request, response);
}
}
~~~
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 在Java或者JSP文件中輸入 Alt + / 可出現智能提示 -->
<!-- uri指定使用哪個標簽庫,prefix指定使用時的前綴,prefix屬性的值是可以改變的,只不過我們一般習慣用c表示。 -->
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>${requestScope.score}</h1>
<!-- test屬性中填寫true或false,用于決定c:if中的HTML語句是否輸出 -->
<c:if test = "${score >= 60 }">
<h1 style = "color:green">恭喜,你已通過測試</h1>
</c:if>
<c:if test = "${score < 60 }">
<h1 style = "color:red">對不起,再接再厲</h1>
</c:if>
<!-- choose when otherwise -->
${grade }
<c:choose>
<!-- 注意單引號,在JSTL中可以使用等號進行字符串的判斷 -->
<c:when test="${grade == 'A'}">
<h2>你很優秀</h2>
</c:when>
<c:when test="${grade == 'B' }">
<h2>不錯呦</h2>
</c:when>
<c:when test="${grade == 'C' }">
<h2>水平一般,需要提高</h2>
</c:when>
<c:when test = "${grade == 'D'}">
<h2>需要努力啦,不要氣餒</h2>
</c:when>
<c:otherwise>
<h2>一切隨緣吧</h2>
</c:otherwise>
</c:choose>
<!-- forEach標簽用于遍歷集合
List companys = (List)request.getAttribute("companys")
for(Company c : companys){
out.print("...")
}
items 代表循環的數據源
var = c 指的是每一次循環得到的變量都會賦值給c
idx = index 循環的索引,但是索引值還是需要通過以下的index屬性來獲取
idx.index屬性代表循環的索引值(0開始)
-->
<c:forEach varStatus="idx" items = "${requestScope.companys }" var = "c">
<h2 style="color:green">${idx.index + 1}-${c.cname }-${c.url }</h2>
</c:forEach>
</body>
</html>
~~~
### fmt格式化標簽庫
fmt格式化標簽庫可以使數據按照我們設想的格式進行輸出。
它的引用地址為:
~~~
http://java.sun.com/jsp/jstl/fmt
~~~
在這個標簽庫中,主要學習兩種格式化語句:
**格式化日期標簽**
`<fmt:formateDate value="" pattern="">`
**格式化數字標簽**
`<fmt:formatNumber value="" pattern="">`
~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
//就在當前頁面設置數據源,不再創建servlet了
request.setAttribute("amt", 1987654.326);
request.setAttribute("now", new java.util.Date());
request.setAttribute("html", "<a href='index.html'>index</a>");
request.setAttribute("nothing", null);
%>
<h2>${now }</h2>
<!--
formatDate pattern
yyyy - 四位年
MM - 兩位月
dd - 兩位日
HH - 24小時制
hh - 12小時制
mm - 分鐘
ss - 秒數
SSS - 毫秒
-->
<h2>
<!-- value指原始的數據值,pattern表示轉換的格式 -->
<fmt:formatDate value="${requestScope.now }" pattern="yyyy年MM月dd日 HH時mm分ss秒 SSS毫秒" />
</h2>
<h2>${amt }</h2>
<h2>¥<fmt:formatNumber value = "${amt }" pattern="0,000.00"></fmt:formatNumber>元</h2>
<!-- 設置輸出方式 -->
<h2>null默認值:<c:out value="${nothing }" default="無"></c:out> </h2>
<!-- 設置輸出時是否轉義 -->
<h2><c:out value="${ html}" escapeXml="true"></c:out></h2>
</body>
</html>
~~~
## 綜合訓練
通常在進行實際項目的開發時,前端工程師會發送給我們一個靜態的頁面,而我們要做的就是將這樣的靜態頁面變為動態頁面。
靜態演示Demo下載地址:鏈接: https://pan.baidu.com/s/1HFMuCGeg5tox-1MWzGs_vQ 提取碼: 2j2z
實例:
~~~
public class Employee {
private Integer empno;
private String ename;
private String department;
private String job;
private Float salary;
public Employee(Integer empno, String ename, String department, String job, Float salary) {
super();
this.empno = empno;
this.ename = ename;
this.department = department;
this.job = job;
this.salary = salary;
}
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Float getSalary() {
return salary;
}
public void setSalary(Float salary) {
this.salary = salary;
}
}
~~~
~~~
@WebServlet("/list")
public class ListServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public ListServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = request.getServletContext();
if(context.getAttribute("employees") == null) {
List list = new ArrayList();
Employee emp = new Employee(7731 , "劉志敏" , "市場部" , "客戶代表" , 10000f);
list.add(emp);
list.add(new Employee(8871 , "張倩" , "研發部" , "運維工程師" , 8000f));
context.setAttribute("employees", list);
}
request.getRequestDispatcher("/employee.jsp").forward(request, response);
}
}
~~~
~~~
<%@ page contentType="text/html;charset=utf-8"%>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/fmt" prefix = "fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>員工列表</title>
<link href="css/bootstrap.css" type="text/css" rel="stylesheet"></link>
<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<style type="text/css">
.pagination {
margin: 0px
}
.pagination > li > a, .pagination > li > span {
margin: 0 5px;
border: 1px solid #dddddd;
}
.glyphicon {
margin-right: 3px;
}
.form-control[readonly] {
cursor: pointer;
background-color: white;
}
#dlgPhoto .modal-body{
text-align: center;
}
.preview{
max-width: 500px;
}
</style>
<script>
$(function () {
$("#btnAdd").click(function () {
$('#dlgForm').modal()
});
})
</script>
</head>
<body>
<div class="container">
<div class="row">
<h1 style="text-align: center">dodoke員工信息表</h1>
<div class="panel panel-default">
<div class="clearfix panel-heading ">
<div class="input-group" style="width: 500px;">
<button class="btn btn-primary" id="btnAdd"><span class="glyphicon glyphicon-zoom-in"></span>新增
</button>
</div>
</div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>序號</th>
<th>員工編號</th>
<th>姓名</th>
<th>部門</th>
<th>職務</th>
<th>工資</th>
<th> </th>
</tr>
</thead>
<tbody>
<c:forEach items = "${applicationScope.employees}" var = "emp" varStatus="idx" >
<tr>
<td>${idx.index + 1}</td>
<td>${emp.empno }</td>
<td>${emp.ename }</td>
<td>${emp.department }</td>
<td>${emp.job }</td>
<td style="color: red;font-weight: bold">¥<fmt:formatNumber value = "${emp.salary }" pattern="0,000.00" ></fmt:formatNumber></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
<!-- 表單 -->
<div class="modal fade" tabindex="-1" role="dialog" id="dlgForm">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">新增員工</h4>
</div>
<div class="modal-body">
<form action="/employee/create" method="post" >
<div class="form-group">
<label >員工編號</label>
<input type="text" name="empno" class="form-control" id="empno" placeholder="請輸入員工編號">
</div>
<div class="form-group">
<label >員工姓名</label>
<input type="text" name="ename" class="form-control" id="ename" placeholder="請輸入員工姓名">
</div>
<div class="form-group">
<label>部門</label>
<select id="dname" name="department" class="form-control">
<option selected="selected">請選擇部門</option>
<option value="市場部">市場部</option>
<option value="研發部">研發部</option>
<option value="后勤部">后勤部</option>
</select>
</div>
<div class="form-group">
<label>職務</label>
<input type="text" name="job" class="form-control" id="sal" placeholder="請輸入職務">
</div>
<div class="form-group">
<label >工資</label>
<input type="text" name="salary" class="form-control" id="sal" placeholder="請輸入工資">
</div>
<div class="form-group" style="text-align: center;">
<button type="submit" class="btn btn-primary">保存</button>
</div>
</form>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body>
</html>
~~~
~~~
@WebServlet("/create")
public class CreateServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public CreateServlet() {
super();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String empno = request.getParameter("empno");
String ename = request.getParameter("ename");
String department = request.getParameter("department");
String job = request.getParameter("job");
String salary = request.getParameter("salary");
System.out.println(empno);
Employee emp = new Employee(Integer.parseInt(empno) , ename , department , job , Float.parseFloat(salary));
ServletContext context = request.getServletContext();
List employees = (List)context.getAttribute("employees");
employees.add(emp);
context.setAttribute("employees", employees);
request.getRequestDispatcher("/employee.jsp").forward(request, response);
}
}
~~~