EL(Expression Laguage),是一种表达式语言,主要是代替jsp页面中的表达式脚本在jsp页面中进行数据的输出
格式
${ 表达式 }
EL表达式在输出null的时候,输出的是空串,jsp表达式脚本输出null值的时候,输出的是null字符串
EL表达式主要是输出jsp页面中域对象的数据
pageContext>requst>session>application
public class Person {
private String name;
private String[] phones;
private List cities;
private Map map;
public int getAge() {
return 18;
}
<%
Person p = new Person();
p.setName("nick");
p.setPhones(new String[]{"18612345676","19865896565","19876323689"});
List cities = new ArrayList();
cities.add("北京");
cities.add("上海");
cities.add("深圳");
p.setCities(cities);
Map map = new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
p.setMap(map);
pageContext.setAttribute("p",p);
%>
输出 Person:${ p }
输出 Person 的 name 属性:${p.name}
输出 Person 的 pnones 数组属性值:${p.phones[2]}
输出 Person 的 cities 集合中的元素值:${p.cities}
输出 Person 的 List 集合中个别元素值:${p.cities[2]}
输出 Person 的 Map 集合: ${p.map}
输出 Person 的 Map 集合中某个 key 的值: ${p.map.key3}
输出 Person 的 age 属性(直接对应getAge()方法,无需定义变量):${p.age}
关系运算
关系运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
== 或 eq | 等于 | ${ 5 == 5 } 或 ${ 5 eq 5 } | true |
!=或 ne | 不等于 | ${ 5 !=5 } 或 ${ 5 ne 5 } | false |
< 或 lt | 小于 | ${ 3 < 5 } 或 ${ 3 lt 5 } | true |
> 或 gt | 大于 | ${ 2 > 10 } 或 ${ 2 gt 10 } | false |
<= 或 le | 小于等于 | ${ 5 <= 12 } 或 ${ 5 le 12 } | true |
>= 或 ge | 大于等于 | ${ 3 >= 5 } 或 ${ 3 ge 5 } | false |
逻辑运算
逻辑运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
&& 或 and | 与运算 | ${ 12 == 12 && 12 < 11 } 或 ${ 12 == 12 and 12 < 11 } | false |
|| 或 or | 或运算 | ${ 12 == 12 || 12 < 11 } 或 ${ 12 == 12 or 12 < 11 } | true |
! 或 not | 取反运算 | ${ !true } 或 ${not true } | false |
算数运算
算数运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
+ | 加法 | ${ 12 + 18 } | 30 |
- | 减法 | ${ 18 - 8 } | 10 |
* | 乘法 | ${ 12 * 12 } | 144 |
/ | 或 div 除法 | ${ 144 / 12 } 或 ${ 144 div 12 } | 12 |
% | 或 mod 取模 | ${ 144 % 10 } 或 ${ 144 mod 10 } | 4 |
empty运算
${ empty 变量 }
${ not empty 变量 }
以下几种情况为空:
三元运算
${ 1 == 1 ? "对" : "错" }
.运算和[]运算
例:
${ map["a-a-a"] }
变量 | 类型 | 作用 |
---|---|---|
pageContext | PageContextImpl | 获取jsp中的九大内置对象 |
pageScore | Map |
获取pageContext域中的数据 |
resultScope | Map |
获取Request域中的数据 |
sessionScope | Map |
获取 Session 域中的数据 |
applicationScope | Map |
获取 ServletContext 域中的数据 |
param | Map |
获取请求参数的值 |
paramValues | Map |
获取请求参数的值,获取多个值的时候使用。 |
header | Map |
获取请求头的信息 |
headerValues | Map |
获取请求头的信息,还可以获取多个值的情况 |
cookie | Map |
获取当前请求的 Cookie 信息 |
initParam | Map |
获取在 web.xml 中配置的 |
变量 | 类型 | 作用 |
---|---|---|
pageScore | Map |
获取pageContext域中的数据 |
resultScope | Map |
获取Request域中的数据 |
sessionScope | Map |
获取 Session 域中的数据 |
applicationScope | Map |
获取 ServletContext 域中的数据 |
${ pageScope.属性}
变量 | 类型 | 作用 |
---|---|---|
pageContext | PageContextImpl | 获取jsp中的九大内置对象 |
<%--
request.getScheme() 它可以获取请求的协议
request.getServerName() 获取请求的服务器 ip 或域名
request.getServerPort() 获取请求的服务器端口号
request.getContextPath() 获取当前工程路径
request.getMethod() 获取请求的方式( GET 或 POST )
request.getRemoteHost() 获取客户端的 ip 地址
session.getId() 获取会话的唯一标识
--%>
<%
pageContext.setAttribute("req", request);
%>
1.协议: ${ req.scheme }
2.服务器 ip:${ pageContext.request.serverName }
3.服务器端口:${ pageContext.request.serverPort }
4.获取工程路径:${ pageContext.request.contextPath }
5.获取请求方法:${ pageContext.request.method }
6.获取客户端 ip 地址:${ pageContext.request.remoteHost }
7.获取会话的 id 编号:${ pageContext.session.id }
变量 | 类型 | 作用 |
---|---|---|
param | Map |
获取请求参数的值 |
paramValues | Map |
获取请求参数的值,获取多个值的时候使用。 |
header | Map |
获取请求头的信息 |
headerValues | Map |
获取请求头的信息,还可以获取多个值的情况 |
cookie | Map |
获取当前请求的 Cookie 信息 |
initParam | Map |
获取在 web.xml 中配置的 |
输出请求参数 username 的值:${ param.username }
输出请求参数 username 的值:${ paramValues.username[0] }
输出请求参数 hobby 的值:${ paramValues.hobby[0] }
输出请求头【User-Agent】的值:${ header['User-Agent'] }
输出请求头【Connection】的值:${ header.Connection }
输出请求头【User-Agent】的值:${ headerValues['User-Agent'][0] }
获取 Cookie 的名称:${ cookie.JSESSIONID.name }
获取 Cookie 的值:${ cookie.JSESSIONID.value }
.
输出<Context-param>username 的值:${ initParam.username }
输出<Context-param>url 的值:${ initParam.url }
测试initParam的web.xml
username
root
url
jdbc:mysql:///test
JSTL全程JSP Standard Tag Libary,JSTL标准标签库,标签库主要是为了替换代码脚本,使代码更简洁。
功能范围 | URL | 前缀 |
---|---|---|
核心标签库-- 重点 | 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 |
CORE 标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
XML 标签库
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
FMT 标签库
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
SQL 标签库
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
FUNCTIONS 标签库
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
set标签可以在域中保存数据
<%--
传统保存:
域对象.setAttribute(key,value);
set保存:
scope 属性设置保存到哪个域
page 表示 PageContext 域(默认值)
request 表示 Request 域
session 表示 Session 域
application 表示 ServletContext 域
var 属性设置 key
value 属性设置值
--%>
保存之前:${ sessionScope.abc }
保存之后:${ sessionScope.abc }
if 标签用来做 if 判断。
<%--
test 属性表示判断的条件(使用 EL 表达式输出)
--%>
12 等于 12
12 不等于 12
多路判断。跟 switch … case … default 非常接近
<%--
标签
choose 标签开始选择判断
when 标签表示每一种判断情况
test 属性表示当前这种判断情况的值
otherwise 标签表示剩下的情况
标签使用时需要注意的点:
1 、标签里不能使用 html 注释,要使用 jsp 注释
2 、 when 标签的父标签一定要是 choose 标签
--%>
<%-- 这是 html 注释 --%>
小巨人
很高
还可以
大于 160
大于 150
大于 140
其他小于 140
遍历输出使用
<%--
1. 遍历 1 到 10 ,输出
for (int i = 1; i < 10; i++)
begin 属性设置开始的索引
end 属性设置结束的索引
var 属性表示循环的变量 ( 也是当前正在遍历到的数据 )
--%>
第${i}行
<%--
2. 遍历 Object 数组
for (Object item: arr)
items 表示遍历的数据源(遍历的集合)
var 表示当前遍历到的数据
--%>
<%
request.setAttribute("arr", new String[]{"18610541354","18688886666","18699998888"});
%>
${ item }
<%--
3. 遍历Map集合
与遍历数组一样
获取key、value时,可直接使用var.调用
--%>
<%
Map map = new HashMap();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
request.setAttribute("map",map);
%>
${entry.key} = ${entry.value}
1、要有一个 form 标签,method=post 请求
2、form 标签的 encType 属性值必须为 multipart/form-data 值
3、在 form 标签中使用 input type=file 添加上传的文件
4、编写服务器代码(Servlet 程序)接收,处理上传的数据。
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼
接,然后以二进制流的形式发送给服务器
第一步,需要导入两个 jar 包:
commons-fileupload-1.2.1.jar
commons-io-1.4.jar
ServletFileUpload 类,用于解析上传的数据。
FileItem 类,表示每一个表单项。
方法 | 作用 |
---|---|
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request); | 判断当前上传的数据格式是否是多段的格式。 |
public List |
解析上传的数据 |
boolean FileItem.isFormField() | 判断当前这个表单项,是普通的表单项,还是上传的文件类型。true 表示普通类型的表单项,false 表示上传的文件类型 |
String FileItem.getFieldName() | 获取表单项的 name 属性值 |
String FileItem.getString() | 获取当前表单项的值。 |
String FileItem.getName(); | 获取上传的文件名 |
void FileItem.write(String file); | 将上传的文件写到file所指向的位置 |
upload.jsp
UploadServelet.java
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//判断上传的数据是否是多段数据(只有是多段的数据,才是文件上传的)
if (ServletFileUpload.isMultipartContent(req)) {
//创建FileItemFactory工厂实现类
FileItemFactory fileItemFactory = new DiskFileItemFactory();
//创建用于解析上传数据的工具类ServletFileUpload类
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
//解析上传的数据,得到每一个表单项FileItem
try {
List list = servletFileUpload.parseRequest(req);
//判断每一个表单项的类型
for (FileItem fileItem : list) {
if (fileItem.isFormField()){
//普通表单项
System.out.println("表单项的name属性值"+fileItem.getFieldName());
//参数UTF-8,解决乱码问题
System.out.println("表单项的name属性值"+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();
}
}
}
}
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取要下载的文件名
String downloadFileName = "1.png";
//2.获取要下载的文件内容(通过ServletContext对象可以获取)
ServletContext servletContext = getServletContext();
//获取要下载的文件类型
String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
/3.在回传前,通过响应头告诉客户端返回的数据类型
resp.setContentType(mimeType);
//4.还要告诉客户端收到的数据是用于下载使用(还是使用响应头)
//Content-Disposition 响应头,表示收到的数据怎么处理
//attachment 表示附件,表示下载使用
//filename 表示指定下载的文件名
resp.setHeader("Content-Disposition","attachment;filename");
// JavaWeb中第一个/表示映射到web目录
InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
//获取响应的输出流
OutputStream outputStream = resp.getOutputStream();
//5.把下载的文件内容回传给客户端
//读取输入流中全部的数据复制给输出流,输出给客户端
IOUtils.copy(resourceAsStream,outputStream);
}
}
//需要设置文件的url编码,url编码是把汉字转换成%xx%xx的格式
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("图片.jpg","UTF-8"));
这时候需要把请求头 Content-Disposition: attachment; filename=中文名
编码成为:
Content-Disposition: attachment; filename==?charset?B?xxxxx?==?charset?B?xxxxx?=
=? 表示编码内容的开始
charset 表示字符集
B 表示 BASE64 编码
xxxx 表示文件名 BASE64 编码后的内容
?= 表示编码内容的结束
public static void main(String[] args) throws Exception {
String content = "这是需要Base64编码的内容";
//创建一个Base64编码器
BASE64Encoder base64Encoder = new BASE64Encoder();
//执行Base64编码操作
String encode = base64Encoder.encode(content.getBytes("UTF-8"));
//创建Base64解码器
BASE64Decoder base64Decoder = new BASE64Decoder();
//解码操作
byte[] bytes = base64Decoder.decodeBuffer(encode);
String str = new String(bytes,"UTF-8");
System.out.println(str);
}
resp.setHeader("Content-Disposition", "attachment;filename==?UTF-8?B?" +
new BASE64Encoder().encode("图片.png".getBytes("UTF-8")) + "?=");
String ua = req.getHeader("User-Agent");
String str = "";
if (ua.contains("Firefox")) {
//为了解决IE和Google中文乱码的问题,需要设置文件的url编码,url编码是把汉字转换成%xx%xx的格式
str = "attachment;filename==?UTF-8?B?" +
new BASE64Encoder().encode("图片.png".getBytes("UTF-8")) + "?=";
}else{
//使用Base64Encoder解决火狐浏览器下载文件时中文乱码
str ="attachment;filename=" + URLEncoder.encode("图片.png", "UTF-8");
}
resp.setHeader("Content-Disposition",str);