EL表达式&JSTL标签库
1.EL表达式
1.1 EL表达式介绍
1.2 jsp原始输出和EL表达式输出的对比
代码
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/3
Time: 19:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%request.setAttribute("key","值");%>
jsp原始表达式输出key值是:
<%=request.getAttribute("key")%><br>
EL 表达式输出 key 的值是:${key1}
</body>
</html>
运行结果
1.3 EL 表达式搜索域数据的顺序
1.4 EL 表达式输出 Bean 的普通属性,数组属性。List 集 合属性,map 集合属性
创建person类
package com.atguigu.EL_JSTL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class Person {
private String name;
private String[] phone;
private List cities;
private Map<String,Object> map;
public Person() {
}
public Person(String name, String[] phone, List cities, Map<String, Object> map) {
this.name = name;
this.phone = phone;
this.cities = cities;
this.map = map;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getPhone() {
return phone;
}
public void setPhone(String[] phone) {
this.phone = phone;
}
public List getCities() {
return cities;
}
public void setCities(List cities) {
this.cities = cities;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", phone=" + Arrays.toString(phone) +
", cities=" + cities +
", map=" + map +
'}';
}
}
person.jsp
<%@ page import="com.atguigu.EL_JSTL.Person" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/3
Time: 20:15
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Person person = new Person();
person.setName("林某人");
person.setPhone(new String[]{"110","120","119"});
List<String> cities = new ArrayList<>();
cities.add("北京");
cities.add("上海");
cities.add("天津");
person.setCities(cities);
Map<String,Object> map = new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
person.setMap(map);
pageContext.setAttribute("p",person);
%>
<%-- ${类.属性}实际上是调用该类的getXxx()方法 --%>
输出 Person:${p}<br>
输出 Person 的 name 属性:${p.name}<br>
输出 Person 的 pnones 数组属性值:${p.phone[2]}<br>
输出 Person 的 cities 集合中的元素值:${p.cities}<br>
输出 Person 的 List 集合中个别元素值:${p.cities[1]}<br>
输出 Person 的 Map 集合:${p.map}<br>
输出 Person 的 Map 集合中某个 key 的值:${p.map.key3}<br>
</body>
</html>
运行结果
1.5 EL 表达式——运算
1.5.1 基本运算
1.5.2 empty运算
1.5.3 三元运算
1.5.4 “.”点运算 和 [] 中括号运算符
a.a.a中“.”为特殊字符,如果没有中括号的话格式错误
1.6 EL表达式中的11个隐含对象
1.6.1 11个隐含对象
1.6.2 EL获取四个特定域中的属性
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/4
Time: 0:32
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
pageContext.setAttribute("key1","pageContext1");
pageContext.setAttribute("key1","pageContext1");
request.setAttribute("key2","request");
session.setAttribute("key2","session");
application.setAttribute("key2","application");
%>
${applicationScope.key2}
</body>
</html>
1.7 pageContext对象的使用
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/4
Time: 12:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
request.getScheme() 它可以获取请求的协议
request.getServerName() 获取请求的服务器 ip 或域名
request.getServerPort() 获取请求的服务器端口号
getContextPath() 获取当前工程路径
request.getMethod() 获取请求的方式(GET 或 POST)
request.getRemoteHost() 获取客户端的 ip 地址
session.getId() 获取会话的唯一标识
--%>
1.协议: ${pageContext.request.scheme}<br>
2.服务器 ip:${pageContext.request.serverName}<br>
3.服务器端口:${pageContext.request.serverPort}<br>
4.获取工程路径:${pageContext.request.contextPath}<br>
5.获取请求方法:${pageContext.request.method}<br>
6.获取客户端 ip 地址:${pageContext.request.remoteHost}<br>
7.获取会话的 id 编号:${pageContext.session.id}<br>
</body>
</html>
1.8 EL表达式其他隐含对象的使用
2. JSTL标签库
2.1 基本介绍
2.2 core的核心库使用
2.2.1 <c:set />
作用:set标签可以往域中保存数据
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/4
Time: 12:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- i.<c:set />
作用:set 标签可以往域中保存数据
jsp中代码脚本设置域对象中的值:域对象.setAttribute(key,value);
scope 属性设置保存到哪个域
page 表示 PageContext 域(默认值)
request 表示 Request 域
session 表示 Session 域
application 表示 ServletContext 域
var 属性设置 key 是多少 value 属性设置值
--%>
保存之前abc的值:${seddionScope.abc}<br>
<c:set scope="session" var="abc" value="abcValue"/>
保存之后abc的值:${sessionScope.abc}
</body>
</html>
2.2.2 <c:choose> <c:when> <c:otherwise>标签
作用:多路判断。跟 switch … case … default 非常接近
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/4
Time: 20:21
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
<c:choose> <c:when> <c:otherwise>标签
作用:多路判断。跟 switch ... case .... default 非常接近
choose 标签开始选择判断
when 标签表示每一种判断情况
test 属性表示当前这种判断情况的值
otherwise 标签表示剩下的情况
<c:choose> <c:when> <c:otherwise>标签使用时需要注意的点:
1、标签里不能使用 html 注释,要使用 jsp 注释
2、when 标签的父标签一定要是 choose 标签
--%>
<%
request.setAttribute("height",180);
%>
<c:choose>
<c:when test="${requestScope.height>190}">
<h2>小巨人</h2>
</c:when>
<c:when test="${requestScope.height>180}">
<h2>很高</h2>
</c:when>
<c:when test="${requestScope.height>170}">
<h2>还可以</h2>
</c:when>
<c:otherwise>
<c:choose>
<c:when test="${requestScope.height>160}">
<h2>大于160</h2>
</c:when>
<c:when test="${requestScope.height>150}">
<h2>大于150</h2>
</c:when>
<c:when test="${requestScope.height>140}">
<h2>大于140</h2>
</c:when>
</c:choose>
</c:otherwise>
</c:choose>
</body>
</html>
2.2.3 使用<c:forEach />遍历
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.List" %>
<%@ page import="com.atguigu.EL_JSTL.Person" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.atguigu.EL_JSTL.Person1" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/4
Time: 20:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
1.遍历 1 到 10,输出
begin 属性设置开始的索引
end 属性设置结束的索引
var 属性表示循环的变量(也是当前正在遍历到的数据)
for (int i = 1; i < 10; i++)
--%>
<table border="1">
<c:forEach begin="1" end="10" var="i">
<tr>
<td>
第${i}行
</td>
</tr>
</c:forEach>
</table>
<%--
2.遍历 Object 数组
for (Object item: arr)
items 表示遍历的数据源(遍历的集合)
var 表示当前遍历到的数据
--%>
<%
request.setAttribute("arr",new String[]{"110","120","119"});
%>
<c:forEach items="${requestScope.arr}" var="item">
${item}<br>
</c:forEach>
<%--
遍历map集合
--%>
<%
Map<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">
<h1>${entry.key}=${entry.value}</h1>
</c:forEach>
<%-- list集合遍历 --%>
<%
List<Person1> list = new ArrayList<>();
for(int i=0;i<5;i++){
list.add(new Person1(i,"username"+i));
}
request.setAttribute("stus",list);
%>
<table border="1" cellspacing="0">
<tr>
<td>编号</td>
<td>姓名</td>
<td>操作</td>
</tr>
<c:forEach items="${requestScope.stus}" var="stu">
<tr>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>修改/删除</td>
</tr>
</c:forEach>
</table>
</body>
</html>
2.2.4 forEach标签中所有属性组合使用
<%-- list集合遍历 --%>
<%
List<Person1> list = new ArrayList<>();
for(int i=0;i<5;i++){
list.add(new Person1(i,"username"+i));
}
request.setAttribute("stus",list);
%>
<table border="1" cellspacing="0">
<tr>
<td>编号</td>
<td>姓名</td>
<td>操作</td>
</tr>
<%--
begin和end标签指定遍历的开始和结束索引
step的属性表示遍历的步长值(每一次循环i加多少)
status表示当前遍历的数据状态,例如下面status运行后是一个对象
--%>
<c:forEach begin="1" end="4" step="2" varStatus="status" items="${requestScope.stus}" var="stu">
<tr>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${status}</td>
</tr>
</c:forEach>
</table>
3.文件的上传
3.1 文件上传和下载的基本介绍
3.2 文件的上传介绍
picture.jsp代码
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/5
Time: 10:57
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
<base href="http://localhost:8080/EL_JSTL/">
</head>
<body>
<form action="picture" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"><br>
头像:<input type="file" name="photo"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
servlet程序代码
package com.atguigu.EL_JSTL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Picture extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("文件上传成功");
}
}
3.3 文件上传HTTP协议的内容
谷歌浏览器为了让控制台太乱,上传的文件的值没有在控制台输出
客户端以流的形式传数据,服务器也得用流的形式接收数据
package com.atguigu.EL_JSTL;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Picture extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println("文件上传成功");
//使用流的形式接受数据
ServletInputStream inputStream = req.getInputStream();
byte[] buffer = new byte[102400];
int read = inputStream.read(buffer);
System.out.println(new String(buffer,0,read));
}
}
3.4 commons-fileupload.jar 常用 API 介绍说明
表单代码
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/5
Time: 10:57
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
<base href="http://localhost:8080/EL_JSTL/">
</head>
<body>
<form action="fileuploadUse" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"><br>
头像:<input type="file" name="photo"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
servlet程序代码
package com.atguigu.EL_JSTL;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class FileuploadUse extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.判断上传的数据是否是多段数据
if(ServletFileUpload.isMultipartContent(req)){
//创建FileItemFactory工程实现类
FileItemFactory diskFileItemFactory = new DiskFileItemFactory();
//创建用于解析上传数据的工具类
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
try {
//解析上传的数据,得到表单项的集合
List<FileItem> list = servletFileUpload.parseRequest(req);
//遍历集合得到表单项
for(FileItem fileItem:list){
//判断是正常表单项还是上传的文件
if(fileItem.isFormField()){
System.out.println("表单项的name属性值为:"+fileItem.getFieldName());
System.out.println("表单项的value属性值为:"+fileItem.getString("UTF-8"));
}else{
//上传的文件
System.out.println("表单的name属性值为:"+fileItem.getFieldName());
System.out.println("文件的名字为:"+fileItem.getName());
//将文件存储到指定路径
fileItem.write(new File("e://"+fileItem.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4.文件下载
package com.atguigu.EL_JSTL;
import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
public class Download extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取想要的文件名
String fileName= "logo.jpg";
ServletContext servletContext = getServletContext();
//2.获取要下载的文件类型
String mimeType = servletContext.getMimeType("/file/"+fileName);
//3.设置响应头头告诉客户端返回的数据类型
resp.setContentType(mimeType);
//4.设置响应头告诉客户端的处理方法为下载
//Content-Disposition为响应头,表示文件该怎样处理
//attachment表示附件,下载使用
//name表示下载后的文件名
String name = "图片.jpg";
if(req.getHeader("User-Agent").contains("Firefox")){
//火狐浏览器使用BASE64 编解码解决文件名问题
resp.setHeader("Content-Disposition","attachment;filename="+"=?utf-8?B?"+new BASE64Encoder().encode(name.getBytes("utf-8"))+"?=");
}else {
//谷歌和ie浏览器采用URLEncode解决文件名编码问题
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
}
//4.通过ServletContext获取文件输入流
InputStream inputStream = servletContext.getResourceAsStream("/file/"+fileName);
//5.获取响应的输出流
OutputStream outputStream = resp.getOutputStream();
//6.读取输入流中的数据复制给输出流,输出给输出端
IOUtils.copy(inputStream,outputStream);
}
}
5.MVC概念