1. EL表達式
1.1 介紹
- EL全稱Expression Language,表達式語言
- EL表達式主要用于代替jsp頁面中的表達式腳本在jsp頁面中進行資料的輸出
- EL表達式的格式:${表達式}
- jsp腳本輸出null值時,顯示的是null字元串;EL表達式輸出null值時,輸出的是空串
- EL表達式主要是輸出域對象中的資料,當4個域中都有相同key的資料時,EL表達式會按4個域從小到大的順序進行搜尋,找到就輸出
1.2 EL表達式輸出Bean對象
<%
Person person = new Person();
----對person對象進行初始化----
pageContext.setAttribute("p",person);
%>
輸出Person:${p}<br/>
輸出name字元串:${p.name}<br/>
輸出phones數組:${p.phones}<br/>
輸出cities集合:${p.cities[1]}<br/>
輸出map集合:${p.map.key1}<br/>
1.3 EL表達式中的運算
EL表達式支援多種運算符,文法:${運算表達式}
- 關系運算:① ==或eq:等于;② !=或ne:不等于;③ <或lt:小于;④ >或gt:大于;⑤ <=或le:小于等于;⑥ >=或ge:大于等于
- 邏輯運算:① &&或and:與運算;② ||或or:或運算;③ !或not:取反運算
- 算術運算:① +:加法;② -:減法;③ *:乘法;④ /或div:除法;⑤ %或mod:取模
- empty運算:用于判斷一個資料是否為空。文法:${empty 對象}
- 點運算和中括号運算:點運算可以輸出Bean對象中某個屬性的值,中括号運算可以輸出有序集合中某個元素的值和map集合中某個key的value
1.4 EL表達式中11個隐含對象
EL表達式中11個隐含對象,是EL表達式自己定義的,可以直接使用:
變量 | 類型 | 作用 |
---|---|---|
pageContext | PageContextImpl | 可以擷取jsp中的九大内置對象 |
pageScope | Map<String,Object> | 可以擷取pageContext域中的資料 |
requestScope | Map<String,Object> | 可以擷取Request域中的資料 |
sessionScope | Map<String,Object> | 可以擷取Session域中的資料 |
applicationScope | Map<String,Object> | 可以擷取ServletContext域中的資料 |
param | Map<String,String> | 可以擷取請求參數的值 |
paramValues | Map<String,String[]> | 可以擷取多個請求參數的值 |
header | Map<String,String> | 可以擷取請求頭的資訊 |
headerValues | Map<String,String[]> | 可以擷取多個請求頭的資訊 |
cookie | Map<String,Cookie> | 可以擷取目前請求的Cookie資訊 |
initParam | Map<String,String> | 可以擷取在web.xml中配置的<context-param>上下文參數u |
擷取協定:${pageContext.request.scheme}<br>
擷取伺服器ip:${pageContext.request.serverName}<br>
擷取伺服器端口:${pageContext.request.serverPort}<br>
擷取工程路徑:${pageContext.request.contextPath}<br>
擷取請求方法:${pageContext.request.method}<br>
擷取用戶端ip位址:${pageContext.request.remoteHost}<br>
擷取會話id編号:${pageContext.session.id}<br>
2. JSTL
2.1 介紹
- JSTL全稱JSP Standard Tag Library——JSP标準标簽庫
- EL表達式主要是為了替換jsp中的表達式腳本,而标簽庫則是為了替換代碼腳本
- JSTL由五個不同功能的标簽庫組成
功能範圍 | URI | 字首 |
---|---|---|
核心标簽庫(重點) | http://java.sun.com/jsp/jstl/core | c |
格式化 | http://java.sun.com/jsp/jstl/fmt | fmt |
函數 | http://java.sun.com/jsp/jstl/functions | fn |
資料庫(不使用) | http://java.sun.com/jsp/jstl/sql | sql |
XML(不使用) | http://java.sun.com/jsp/jstl/xml | x |
2.2 标簽庫的使用步驟
- 導入jstl所需要的jar包,或導入maven依賴(需導入jstl和标簽庫兩個依賴)
- 使用taglib指令引入标簽庫
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2.3 使用core核心庫
2.3.1 set标簽
- 作用:往域中儲存資料,等同于:域對象.setAttribute(key,value)
- scope屬性:設定儲存到哪個域,page表示PageContext域(預設值)
- var屬性:設定key
<c:set scope="request" var="abc" value="123"/>
${requestScope.abc}
2.3.2 if标簽
- 作用:用于判斷
- test屬性:設定判斷的條件,使用EL表達式輸出
<c:if test="${10==10}">
<h1>10等于10</h1>
</c:if>
2.3.3 choose、when、otherwise标簽
- 作用:多路判斷,等同于switch - case - default
- 注意:标簽中要使用jsp注釋,不能使用html注釋
<%
request.setAttribute("abc", 123);
%>
<c:choose>
<c:when test="${requestScope.abc>150}">
<h2>no.1</h2>
</c:when>
<c:when test="${requestScope.abc>120}">
<h2>no.2</h2>
</c:when>
<c:otherwise>
<h2>no.3</h2>
</c:otherwise>
</c:choose>
2.3.4 forEach标簽
- 作用:周遊輸出使用
- begin和end屬性:表示周遊的開始和結束索引,可以和items屬性結合使用
- step屬性:周遊的步長
//普通周遊
<c:forEach begin="1" end="10" var="i">
${i}
</c:forEach>
//周遊對象類型的數組
<%
request.setAttribute("arr",new String[]{"123","456","789"});
%>
<c:forEach items="${requestScope.arr}" var="item">
${item}
</c:forEach>
//周遊Map集合
<%
HashMap<String, Object> map = new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
request.setAttribute("map",map);
%>
<c:forEach items="${requestScope.map}" var="entry">
${entry}
${entry.key}
${entry.value}
</c:forEach>
3. 檔案的上傳和下載下傳
3.1 檔案的上傳要求
- 要有一個form标簽,method=post請求
- form标簽的encType屬性值必須為multipart/form-data值
- 在form标簽中使用input type=file添加上傳的檔案
- 編寫伺服器代碼接收、處理上傳的資料
<form action="/EL_JSTL/uploadServlet" method="post" enctype="multipart/form-data">
使用者名:<input type="text" name="username"/><br>
頭像:<input type="file" name="photo"> <br>
<input type="submit" value="上傳">
</form>
3.2 檔案上傳的Http協定内容介紹
- Content-Type:表示送出的資料類型,其值為enctype的值。multipart/form-data表示送出的資料以多段的形式進行拼接(每一個表單項一個資料段),然後以二進制流的形式發送給伺服器
- boundary:表示每段資料的分隔符,由浏覽器随機生成
3.3 在伺服器中擷取上傳的檔案資訊
3.3.1 擷取上傳的檔案資訊
在Servlet中可以通過流的方式擷取上傳的檔案資訊:
ServletInputStream inputStream = req.getInputStream();
byte[] buffer = new byte[1024000];
int read = inputStream.read(buffer);
System.out.println(new String(buffer, 0, read));
3.3.2 解析上傳的資料
有現成的jar包可用于解析上傳的資料,導入commons-fileupload和commons-io兩個jar包,其中ServletFileUpload類用于解析上傳的資料,該類中提供了多種方法:
- boolean isMultipartContent(HttpServletRequest request):判斷目前上傳的資料是否是多段的格式
- List<FileItem> parseRequest(HttpServletRequest request):解析上傳的資料為FileItem類型的清單
FileItem類中的方法用于輔助解析上傳的資料:
- boolean isFormField():判斷目前表單項是否是普通的表單項,false表示為上傳的檔案
- String getFieldName():擷取目前表單項的name
- String getString():擷取目前表單項的值
- String getName():擷取上傳的檔案名
- void write(File var1):将上傳的檔案寫到var1所指向的硬碟位置
if (ServletFileUpload.isMultipartContent(req)) {
FileItemFactory fileItemFactory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
try {
List<FileItem> fileItems = servletFileUpload.parseRequest(req);
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
System.out.println(fileItem.getFieldName());
System.out.println(fileItem.getString("UTF-8"));
} else {
System.out.println(fileItem.getFieldName());
System.out.println(fileItem.getName());
fileItem.write(new File("D:/" + fileItem.getName()));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
3.4 檔案下載下傳的步驟
- 用戶端發請求告訴伺服器要下載下傳的檔案
- 伺服器擷取用戶端要下載下傳的檔案名
- 伺服器通過響應頭告訴用戶端傳回的資料類型,以及收到的資料是用于下載下傳使用
- 伺服器讀取要下載下傳的檔案内容
- 伺服器把下載下傳的檔案内容回傳給用戶端
String downloadFile = "smile.jpg";
ServletContext servletContext = getServletContext();
String mimeType = servletContext.getMimeType("/file/" + downloadFile);
System.out.println(mimeType);
response.setContentType(mimeType);
response.setHeader("Content-Disposition", "attachment;filename=" + downloadFile);
InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFile);
OutputStream outputStream = response.getOutputStream();
IOUtils.copy(resourceAsStream, outputStream);
注意:要下載下傳的檔案若不在resource目錄下,則要手動設定檔案所在目錄為Tomcat編譯目錄