【JavaWeb】JSTL 标签库
JSTL 标签库
简介
JSTL(JSP Standard Tag Library),即 JSP 标准标签库。标签库是为了替换代码脚本,使得整个 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 |
在 jsp 标签库中使用 taglib 指令引入标签库:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
使用
使用步骤:
- 先导入 jstl 标签的 jar 包:
taglibs-standard-impl-1.2.1.jartaglibs-standard-spec-1.2.1.jar - 使用 taglib 指令引入标签库:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set />:set 标签可以往域中保存数据
<%--
i.<c:set />
作用:set 标签可以往域中保存数据
域对象.setAttribute(key,value);
scope 属性设置保存到哪个域
page 表示 PageContext 域(默认值)
request 表示 Request 域
session 表示 Session 域
application 表示 ServletContext 域
var 属性设置 key 是多少
value 属性设置值
--%>
保存之前:${ sessionScope.abc } <br>
<c:set scope="session" var="abc" value="abcValue"/>
保存之后:${ sessionScope.abc } <br>
<c:if />:if 标签用来做 if 判断
<%--
ii.<c:if />
if 标签用来做 if 判断。
test 属性表示判断的条件(使用 EL 表达式输出)
--%>
<c:if test="${ 12 == 12 }">
<h1>12 等于 12</h1>
</c:if>
<c:if test="${ 12 != 12 }">
<h1>12 不等于 12</h1>
</c:if>
<c:choose> <c:when> <c:otherwise>:多路判断,跟 switch ... case .... default 非常接近
<%--
iii.<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>
<%-- 这是 html 注释 --%>
<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}">
<h3>大于 160</h3>
</c:when>
<c:when test="${requestScope.height > 150}">
<h3>大于 150</h3>
</c:when>
<c:when test="${requestScope.height > 140}">
<h3>大于 140</h3>
</c:when>
<c:otherwise>
其他小于 140
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
<c:forEach />:遍历输出
<%--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>
文件的上传和下载
文件的上传
实现步骤:
- 客户端:
- 发送 post 请求,告诉服务器要上传什么文件
- 服务器:
- 要有一个 form 标签,method=post 请求,form 标签的 encType 属性值必须为
multipart/form-data值 - 在 form 标签中使用
input type=file添加上传的文件 - 接收并处理上传的文件
- 要有一个 form 标签,method=post 请求,form 标签的 encType 属性值必须为
文件上传时 HTTP 协议说明:
Content-type表示提交的数据类型multipart/form-data表示提交的数据,以多段(每一个表单项代表一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器boundary表示每段数据的分隔符,它的值是有浏览器随机生成的,它是每段数据的分割符
实现上传下载功能常用两个包:
commons-fileupload.jarcommons-io.jar
这两个包的常用类:
ServletFileUpload用于解析上传的数据FileItem表示每一个表单项
常用方法:
boolean ServletFileUpload.isMultipartContent(HttpServletRequest request)判断当前上传的数据格式是否是多段的格式,即是否是文件public List<FileItem> parseRequest(HttpServletRequest request)解析上传的数据boolean FileItem.isFormField()判断当前这个表单项,是否是普通的表单项,还是上传的文件类型,true 表示普通类型的表单项,false 表示上传的文件类型String FileItem.getFieldName()获取表单项的 name 属性值String FileItem.getString()获取当前表单项的值String FileItem.getName()获取上传的文件名void FileItem.write(File file)将上传的文件写到 参数 file 所指向的位置
<%--
Created by IntelliJ IDEA.
User: parzulpan
Date: 2020/12/9
Time: 6:00 下午
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件的上传</title>
</head>
<body>
<form action="/JSP/uploadServlet" 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>
package cn.parzulpan.servlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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;
/**
* @Author : parzulpan
* @Time : 2020-12-09
* @Desc : 文件上传
*/
@WebServlet(name = "UploadServlet", urlPatterns = ("/uploadServlet"))
public class UploadServlet extends HttpServlet {
// 处理上传的文件
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("文件上传了");
// 1. 先判断上传的数据是否有多段数据,只有是多段的数据,才是文件上传的
if (ServletFileUpload.isMultipartContent(request)) {
// 创建 FileItemFactory 工厂实现类
FileItemFactory fileItemFactory = new DiskFileItemFactory();
// 创建用于解析上传数据的工具类
ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
// 解析上传的数据,得到每一个表单项 FileItem
try {
List<FileItem> list = servletFileUpload.parseRequest(request);
// 循环判断,每一个表单项,是普通类型,还是上传的文件
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(fileItem.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
文件的下载
实现步骤:
- 客户端:
- 发送请求,告诉服务器要下载什么文件
- 服务器:
- 获取要下载的文件名
- 读取要下载的文件内容
- 在回传前,通过响应头告诉客户端返回的数据类型以及告诉客户端收到的数据是用于下载使用
package cn.parzulpan.servlet;
import org.apache.commons.io.IOUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
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.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* @Author : parzulpan
* @Time : 2020-12-09
* @Desc : 文件下载
*/
@WebServlet(name = "DownloadServlet", urlPatterns = ("/downloadServlet"))
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
// 处理文件的下载
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取要下载的文件名
String downloadFileName = "cat.png";
// 2. 读取要下载的文件内容,通过 ServletContext 对象
ServletContext servletContext = getServletContext();
// 获取要下载的文件信息
String mimeType = servletContext.getMimeType("/file/" + downloadFileName); // 文件类型
// 3. 在回传前,通过响应头告诉客户端返回的**数据类型**以及告诉客户端收到的数据是**用于下载使用**
// Content-Disposition 表示收到的数据怎么处理,attachment 表示附件
response.setContentType(mimeType); // 告诉数据类型
// 解决中文乱码的问题
if (request.getHeader("User-Agent").contains("Firefox")) {
// 如果是火狐浏览器则使用 Base64 编码
response.setHeader("Content-Disposition",
"attachment; fileName=?UTF-8?B?" +
new BASE64Encoder().encode("猫.png".getBytes(StandardCharsets.UTF_8)) + "?=" );
} else {
// 如果不是火狐浏览器,例如谷歌或者 IE,则使用 URL 编码
System.out.println("attachment; fileName=" + URLEncoder.encode(downloadFileName, "UTF-8"));
response.setHeader("Content-Disposition",
"attachment; fileName=" + URLEncoder.encode("猫.png", "UTF-8"));
}
// 4. 数据回传
InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName); // 获取输入流
ServletOutputStream outputStream = response.getOutputStream(); // 获取响应的输出流
IOUtils.copy(resourceAsStream, outputStream); // 读取输入流中的全部数据,复制给输出流,输出给客户端
}
}
练习和总结
【JavaWeb】JSTL 标签库的更多相关文章
- JavaWeb基础—EL表达式与JSTL标签库
EL表达式: EL 全名为Expression Language.EL主要作用 获取数据(访问对象,访问数据,遍历集合等) 执行运算 获取JavaWeb常用对象 调用Java方法(EL函数库) 给出一 ...
- JavaWeb学习篇之----自定义标签&&JSTL标签库详解
今天来看一下自定义标签的内容,自定义标签是JavaWeb的一部分非常重要的核心功能,我们之前就说过,JSP规范说的很清楚,就是Jsp页面中禁止编写一行Java代码,就是最好不要有Java脚本片段,下面 ...
- JavaWeb学习之JSP常用标签、EL表达式的运算符、JSTL标签库(6)
1.JSP常用标签 * 只要支持JSP文件,常用标签有可以直接使用 * 格式: jsp:xxxx * jsp:forward ,完成jsp页面的转发 * page属性:转发的地址 <% requ ...
- javaweb学习总结(二十八)——JSTL标签库之核心标签
一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...
- JavaWeb总结(七)—JSTL标签库
一.JSTL标签库介绍 JSTL标签库的使用时为了弥补HTML标签的不足,规范自定义标签的使用而诞生的.使用JSTL标签的目的是不希望在JSP中出现Java逻辑代码. 二.JSTL标签库的分类 1.核 ...
- javaWeb学习总结(9)- JSTL标签库之核心标签
一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...
- JavaWeb(五)之JSTL标签库
前言 前面介绍了EL表达式,其实EL表达式基本上是和JSTL核心标签库搭配一起使用才能发挥效果的.接下来让我们一起来认识一下吧! 在之前我们学过在JSP页面上为了不使用脚本,所以我们有了JSP内置的行 ...
- JAVAWEB开发之JSTL标签库的使用、 自己定义EL函数、自己定义标签(带属性的、带标签体的)
JSTL JSTL简单介绍: JSTL的全称:JSP Standard Tag Library,JSP标准标签库 JSTL的作用: 提供给Java Web开发者一个标准通用的标签函数库 和E ...
- JavaWeb学习笔记(九)—— JSTL标签库
一.JSTL概述 1.1 什么是JSTL JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,它与JSP动作标签一样,只不过它不是 ...
- 【JavaWeb】JSTL标签库
JSTL标签库 JSTL标准标签库: JSTL用于简化JSP开发,提高代码的可读性与可维护性: JSTL由SUN(Oracle)定义规范,由Apache Tomcat团队实现: 引用JSTL核心库 核 ...
随机推荐
- I am zhoukangyang!
我是 \(\texttt{zhoukangyang}\),一名来自浙江省,杭州市的初二菜鸡 \(\texttt{oier}\) . 洛谷zhoukangyang 很多东西因为太垃圾所以 了,要开 请洛 ...
- 【笔记】「pj复习」深搜——拿部分分
说在最前面 众所周知, NOIP pj 的第三题大部分都是 dp ,但是有可能在考场上想不到动态转移方程,所以我们就可以拿深搜骗分. 方法 深搜拿部分分 剪枝 记忆化 看数据范围 有时候发现,写完深搜 ...
- 题解-CF1396C Monster Invaders
题面 CF1396C Monster Invaders 有 \(n\) 层关卡,每层有 \(a_i\) 个小怪(\(1\) 血)和 \(1\) 个老怪(\(2\) 血).有三种武器:\(1\) 武器每 ...
- AcWing 404. 婚礼
大型补档计划 题目链接 根据题意,显然只有新郎这边可能存在矛盾,考虑这边怎么放即可,新娘那边的放法与这边正好相反且一一对应. 显然对于两个约束条件是一对矛盾,开始我以为可以用并查集,后来发现输出方案的 ...
- uni-app中组件的使用
组件基本知识点: uniapp中:每个页面可以理解为一个单页面组件,这些单页面组件注册在pages.json里,在组件关系中可以看作父组件. 自定义可复用的组件,其结构与单页面组件类似,通常在需要的页 ...
- 最简单的 K8S 部署文件编写姿势,没有之一!
1. 头疼编写K8S部署文件? K8S yaml 参数很多,需要边写边查? 保留回滚版本数怎么设? 如何探测启动成功,如何探活? 如何分配和限制资源? 如何设置时区?否则打印日志是GMT标准时间 如何 ...
- 图的遍历BFS
图的遍历BFS 广度优先遍历 深度优先遍历 可以进行标记 树的广度优先遍历,我们用了辅助的队列 bool visited[MAX_VERTEX_NUM] //访问标记数组 //广度优先遍历 void ...
- 20201204-3 opp编程好处
面向对象编程(Object-Oriented Programming )介绍 对于编程语言的初学者来讲, OOP不是一个很容易理解的编程方式,大家虽然都按老师讲的都知道0OP的三大特性是 继承.封装. ...
- AWT03-LayoutManager布局管理器
1.LayoutManager布局管理器 在之前的学习中,我们使用setBounds()方法设置容器的位置大小,但我们不得不明白一件事--如果我们手动为容器设置位置大小的话,就会造成程序通用性的下降. ...
- IntelliJ IDEA(十二) :IDEA常用配置
idea版本 2019.3.4 配置JDK File--> Project Structure... 修改项目 jdk和项目语言等级 修改jdk版本 File--> Ohter Setti ...