一.JSTL的概况
1.Java Server Pages Standard Tag Libray(JSTL)为JSP标准标签库
2.核心标签库:http://java.sun.com/jsp/jstl/core 包含 Web 应用的常见工作,比如:循环、表达式赋值、基本输入输出等。
3.格式化标签库: http://java.sun.com/jsp/jstl/fmt 用来格式化显示数据的工作,比如:对不同区域的日期格式化等。
4.为了在 JSP 页面使用 JSTL 类库,必须以下列格式使用 taglib 指令:
<%@taglib uri=”” prefix=””%> 例如: <%@taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c”%>,前缀(prefix)可以是任意内容,遵循规范可以使团队中由不同人员编写的代码更加相
似;所以,建议使用事先设计好的前缀。此时需要导入两个 jar 包:
直接放入 Tomcat 的 lib 目录下即可。
二.JSTL的使用
1. 条件动作标签
JSTL 中有 4 个标签可以执行条件式动作指令: if、 choose、 when 和 otherwise。
a.if 标签
JSTL标签一般操作域对象,变量无法操作,if标签可以适合返回值,返回值是boolean类型,通过var属性来设置.
没有主体内容
格式:
<c:if test="条件" var="限域变量的名称" scope="域对象的范围[page|request|session|application]"></c:if>
有主体内容
格式:
<c:if test="条件" var="限域变量的名称" scope="域对象的范围[page|request|session|application]">
条件满足时,显示的内容
</c:if>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>if标签</title>
</head>
<body>
<%
int a = 1;
request.setAttribute("b", 0);
request.setAttribute("c", 1);
int d = 1;
%>
<c:if test="${1==1 }" var="flag" scope="request"></c:if> ${flag } <br>//true
<c:if test="${a == b}" var="flag1" ></c:if> ${flag1 } <br>//false
<c:if test="${c == b}" var="flag2" ></c:if> ${flag2 } <br>//false
<c:if test="${a == d}" var="flag3" ></c:if> ${flag3 } <br>//true
<c:if test="${'' == ''}" var="flag4" ></c:if> ${flag4 } <br>//true
<c:if test="${a > 0}" var="flag5" ></c:if> ${flag5 } <br>//false
<c:if test="b == c" var="flag6" ></c:if> ${flag6 } <br>//false
<c:if test="1 == 1" var="flag7" ></c:if> ${flag7 } <br>//false,值得注意的
<c:if test="true" var="flag8" ></c:if> ${flag8 } <br>//true
<c:if test="${'1==1' }" var="flag9" ></c:if> ${flag9 } <br>//false
<c:if test="${b > 0 }" var="flag10" ></c:if> ${flag10 } <br>//false
${b > 0 }//false
<hr>
<c:if test="${b>0 }">
<h1>我就是简单测试一下</h1>
</c:if>
<c:if test="${b<=0 }">
<h1>简单测试一下</h1>
</c:if>
</body>
</html>
b.choose、 when 和 otherwise 标签
格式:
<c:choose>
<c:when test="条件语句"></c:when>
...
<c:otherwise></c:otherwise>
</c:choose>
注意:
1、choose标签和otherwise标签没有属性
设置属性会报错 Attribute xxx invalid for tag choose according to TLD
2、when标签必须要有test属性
attribute test is mandatory for tag when
3、choose标签中只能包含when标签和otherwise标签、when标签和otherwise标签可以包含其他标签
Illegal child tag in "c:choose" tag: "c:if" tag
4、choose标签中至少要有一个吻痕标签,可以没有otherwise标签
Illegal "choose" without child "when" tag
5、otherwise标签必须放在最后一个when标签之后
Illegal "c:when" after "c:otherwise" tag in "c:choose" tag.
6、otherwise标签只有在所有when标签都不成立时才会执行
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>choose</title>
</head>
<body>
<%
request.setAttribute("score", 100);
%>
<c:choose>
<c:when test="${score == 60 }">
<h1>分不在高,及格就好!</h1>
</c:when>
<c:when test="${score > 60 && score < 80 }">
<h1>革命尚未完成,同志仍需努力!</h1>
</c:when>
<c:when test="${score >= 80 && score < 100 }">
<h1>哎哟不错哦!</h1>
</c:when>
<c:when test="${score == 100 }">
<h1>都是腰间盘,凭什么你这么突出!</h1>
</c:when>
<c:otherwise>
<h1>你个渣渣!这都不及格!</h1>
</c:otherwise>
</c:choose>
</body>
</html>
2. 迭代标签:forEach
将主体内容重复打印多次
格式:
<c:forEach begin="开始循环的数" end="结束循环的数" step="循环的间隔" var="被循环到的值的域对象名称">
主体内容
</c:forEach>
迭代集合
格式:
<c:forEach items="被循环的集合/对象" var="被循环到的成员的域对象名称" varStatus="当前被循环的成员的信息">
主体内容
</c:forEach>
a.forEach属性含义如下:
c.varStatus 属性的使用:
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>forEach迭代</title>
</head>
<body>
<c:forEach begin="1" end="5" step="1" var="i">
<h3>${i }、主体内容</h3>
</c:forEach>
<hr>
<c:forEach begin="1" end="10" step="2" var="i">
<h3>${i }、主体内容</h3>
</c:forEach>
<hr>
<%
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
request.setAttribute("list", list);
%>
<table border="1" style="border-collapse: collapse;">
<tr>
<th>姓名</th>
<th>当前成员的下标</th>
<th>循环的次数</th>
<th>当前成员是否第一次被循环</th>
<th>当前成员是否最后一次被循环</th>
</tr>
<c:forEach items="${list }" var="item" varStatus="info">
<tr>
<td>${item }</td>
<td>${info.index }</td>
<td>${info.count }</td>
<td>${info.first }</td>
<td>${info.last }</td>
</tr>
</c:forEach>
</table>
<hr>
<%
Map<String,Object> map = new HashMap<>();
map.put("zhangsan","张三,今年18,性别男爱好女");
map.put("lisi","李四,今年18,爱好张三");
map.put("wangeu","王五,今年20,爱好李四");
map.put("admin",list);
request.setAttribute("myMap", map);
%>
<c:forEach items="${myMap }" var="user">
${user.key } = ${user.value } <br>
</c:forEach>
</body>
</html>
3. 格式化动作指令
JSTL 提供了格式化和解析数字和日期的标签,我们讨论里面有:formatNumber、 formatDate、 parseNumber 及 parseDate。
a.formatNumber标签
该标签用指定的格式或精度来格式化数
没有主体内容
格式:<fmt:formatNumber value="被格式化的值" var="格式化后的结果(域对象的名称)" type="被格式化的类型"></fmt:formatNumber>
type:被格式化的类型
number:数值型
percent:百分比类型
currency:货币类型
value:被格式化的值
可以是字面量或用表达式从域对象中取值
var:用来接收格式化后的结果的限域变量
如果没有设置该属性,格式化后的结果会直接输出;如果设置了var属性,就需要通过表达式获取域对象中的值如果格式化成百分比,默认保留两位,四舍五入
maxIntegerDigits:允许最大的整数位
maxFractionDigits:允许最大的小数位
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>formatNumber格式化数值</title>
</head>
<body>
<fmt:formatNumber value="10" type="number" ></fmt:formatNumber> <br><!-- 10 -->
<fmt:formatNumber value="10" type="number" var="num" ></fmt:formatNumber> ${num }<br><!--10 -->
<fmt:formatNumber value="0.25678" type="percent" ></fmt:formatNumber><br><!-- 0.26% -->
<fmt:formatNumber value="1234.567" type="number" maxIntegerDigits="4" maxFractionDigits="1" ></fmt:formatNumber><br> <!-- 1234.6 -->
<fmt:setLocale value="en_US" /><!-- 设置当前区域,如果不设置,默认当前区域 zh_CN-->
<fmt:formatNumber value="1000" type="currency" ></fmt:formatNumber><br> <!-- ¥1,000.00 -->
<fmt:formatNumber type="currency" >1000</fmt:formatNumber><br> <!-- ¥1,000.00 -->
<%
request.setAttribute("numb", 100);
%>
<fmt:formatNumber type="currency" >${numb }</fmt:formatNumber><br> <!-- ¥1,000.00 -->
</body>
</html>
b.formatDate 标签--->格式化日期
格式:<fmt:formatDate value="要被格式化的值" type="被格式化的类型"/>
value:也可以用表达式从域对象中取值
type:被格式化的类型
date:日期类型,默认值
time:时间类型
both:日期+时间类型
<fmt:formatDate>标签有如下属性:
pattern 属性指定更精确的处理日期:
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>formatDate格式化日期</title>
</head>
<body>
<%
Date myDate = new Date();
request.setAttribute("myDate", myDate);
%>
${myDate } <br>
<fmt:formatDate value="${myDate }"/><br>
<fmt:formatDate value="${myDate }" type="date"/><br>
<fmt:formatDate value="${myDate }" type="time"/><br>
<fmt:formatDate value="${myDate }" type="both"/><br>
<fmt:formatDate value="${myDate }" type="date" dateStyle="full"/><br>
<fmt:formatDate value="${myDate }" type="date" dateStyle="long"/><br>
<fmt:formatDate value="${myDate }" type="date" dateStyle="short"/><br>
<fmt:formatDate value="${myDate }" type="date" dateStyle="medium"/><br>
<fmt:formatDate value="${myDate }" type="date" dateStyle="default"/><br>
<fmt:formatDate value="${myDate }" type="time" dateStyle="full"/><br>
<fmt:formatDate value="${myDate }" type="time" dateStyle="short"/><br>
<fmt:formatDate value="${myDate }" type="both" timeZone="America/Los_Angeles" /><br>
<fmt:formatDate value="${myDate }" pattern="yyyy-MM-dd HH:mm:ss" /><br>
<fmt:formatDate value="${myDate }" pattern="yyyy/MM/dd HH:mm:ss" /><br>
<fmt:formatDate value="${myDate }" pattern="yy/MM/dd" /><br>
</body>
</html>
c.parseNumber标签
利用 parseNumber 标签可以将数字、货币或百分比的字符串表示法解析成指定语言环 境的数字,即解析一个代表着数字,货币或百分比的字符串。
两种语法形式:
没有主体内容
使用主体内容
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>parseNumber</title>
</head>
<body>
<%
request.setAttribute("num1", "100.1244");
%>
<fmt:parseNumber value="25%" type="percent"></fmt:parseNumber><br>
<fmt:parseNumber value="¥100.00" type="currency" var="num"></fmt:parseNumber> ${num }<br>
<fmt:parseNumber value="${num1 }" type="number" ></fmt:parseNumber><br>
<fmt:parseNumber value="${num1 }" type="number" integerOnly="true"></fmt:parseNumber><br>
</body>
</html>
d.parseDate:将指定格式的字符串转换成日期类型
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html >
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>parseDate</title>
</head>
<body>
<fmt:parseDate value="2018-09-03" pattern="yyyy-MM-dd" ></fmt:parseDate><br>
<fmt:parseDate value="15:50:50" pattern="HH:mm:ss" ></fmt:parseDate><br>
<%
request.setAttribute("date1", "2018/09/03");
request.setAttribute("date2", "09/03/2018");
%>
<fmt:parseDate pattern="yyyy/MM/dd">${date1 }</fmt:parseDate><br>
<fmt:parseDate pattern="MM/dd/yyyy">${date2 }</fmt:parseDate><br>
</body>
</html>
三.JSON的初见
JSON(JavaScript Object Notation)是一种轻量级易与解析的数据格式,它按照 js 的对象和数组的字面量格式来书写。 现在 JSON 的光环已经逐渐超越了 XML,各大网站提供的数据接口一般都是 JSON。广泛应用于服务端与客户端的数据交互
1.JSON 格式
jquery 1.4 以后对 json 格式变严格了,也就是说必须要这种格式的{"键":"值","键":"值 "};像原来的{键:值,键:值}和{'键':'值','键':'值'}这种都是错误的,不合标准,所以 jquery 返回 error 如"{\"success\":true,\"msg\":\"success\"}",如果说是boolean 类型,则不用加 引号,其它的键/值都需要加引号。
-
Json 以 key-value 的形式存储数据
-
Key 的取值 为 String 类型;
-
Value 的取值 为 String,boolean,Number,数组,Object,null;
-
Json 串以{开始,以}结尾;
-
Json 串中数组是以[开始,以]结尾;
-
Json 串中 Object 是以{开始,以}结尾;
2.解析方式(重点)
java的user类
package com.shsxt.po;
public class User {
private Integer userId;
private String uname;
private Integer age;
private boolean sex;
public User() {
super();
}
public User(Integer userId, String uname, Integer age, boolean sex) {
super();
this.userId = userId;
this.uname = uname;
this.age = age;
this.sex = sex;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
}
a.使用 gson 处理(导入相应的架包)
Gson是一个Google提供的一个Java库,可用于将Java对象转换为JSON表示。它也可以被用来将 JSON 字符串转换成一个等效的 Java 对象。提供易于使用的机制如 toString()和构造函数(工厂方法)将 Java 转换为 JSON,反之亦然。 允许自定义表示对象, 支持任意复杂的对象, 生成紧凑和可读性的JSON 输出.
重点掌握JSON的串与对象的转化(Json 解析成 java 对象---->Json 解析 成 List---->Json 解析 成 map)
Gson 的 节点对象:
JsonElement : 所有的节点 都是 JsonElement 对象.
JsonPrimitive : 基本的 数据类型的 节点 对象, JsonElement 的子类.
JsonNull : 代表 空节点 对象,即 有 key, value 为空, JsonElement 的子类.
JsonObject : 对象 数据类型的 节点 对象, JsonElement 的 子类.
JsonArray : 数组 数据类型的 节点 对象, JsonElement 的 子类.
II)、 JsonElement 的取值:
JsonPrimitive : value 的 取值对应 java 的 int,double,float,long,short,boolean,char,byte,String,BigDecimal,BigI nteger,Number
JsonObject : value 的取值对应 java 的 Object 对象.
JsonArray : value 的取值对应 java 的 List 及其子类对象.
package com.shsxt.test;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.reflect.TypeToken;
import com.shsxt.po.User;
public class GsonTest {
/**
* @Test注解 单元测试
* 1、不能有父类
* 2、不能是静态方法
* 3、不能有参数
* 4、返回值是void
*/
@Test
public void test() {
fail("Not yet implemented");
}
/**
* 将对象转换成JSON字符串
*/
@Test
public void testObjectToJson() {
// 得到对象
User user = new User(1, "zhangsan", 18, true);
/**
* String json = {"userId":1,"uname":"zhangsan","age":18,"sex":true};
*/
// 得到gson对象
Gson gson = new Gson();
// 将对象转换成JSON字符串
String json = gson.toJson(user);
System.out.println(json);
}
/**
* 将JSON字符串转换成对象
*/
@Test
public void testJSONToObject(){
// 定义JSON字符串
String json = "{\"userId\":1,\"uname\":\"zhangsan\",\"age\":18,\"sex\":true}";
// 得到gson对象
Gson gson = new Gson();
// 将JSON字符串转换成对象
User user = gson.fromJson(json, User.class);
System.out.println(user.getUname());
}
/**
* 将集合转换成JSON字符串
*/
@Test
public void testListToJson() {
// 定义集合
List<String> list = new ArrayList<>();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");
// 得到gson对象
Gson gson = new Gson();
// 将集合转换成JSON字符串
String json = gson.toJson(list);
System.out.println(json);
List<User> userList = new ArrayList<>();
User user = new User(1, "zhangsan", 18, true);
User user2 = new User(2, "lisi", 19, false);
User user3 = new User(3, "wangwu", 20, true);
userList.add(user);
userList.add(user2);
userList.add(user3);
// 将集合转换成JSON字符串
String json2 = gson.toJson(userList);
System.out.println(json2);
}
/**
* 将JSON字符串转换成集合
*/
@Test
public void testJsonToList() {
// 定义json对象
String json = "[\"zhangsan\",\"lisi\",\"wangwu\"]";
// 得到gson对象
Gson gson = new Gson();
// 将JSON字符串转换成集合
List<String> list = gson.fromJson(json, new TypeToken<List<String>>(){}.getType());
System.out.println(list.get(0));
}
/**
* 将map转换成JSON字符串
*/
@Test
public void testMapToJSON() {
Map<String, Object> map = new HashMap<>();
map.put("uname", "张三");
map.put("age", 18);
map.put("sex", true);
// 得到gson对象
Gson gson = new Gson();
String json = gson.toJson(map);
System.out.println(json);
}
/**
* 将JSON字符串转换成MAP
*/
@Test
public void testJSONToMap() {
String json = "{\"uname\":\"张三\",\"sex\":true,\"age\":18}";
// 得到gson对象
Gson gson = new Gson();
Map<String, Object> map = gson.fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());
System.out.println(map.get("uname"));
}
}
b.Json 节点解析
解析步骤 :获得解析器---->获得根节点元素---->根据文档判断根节点属于什么类型的 Gson 节点对象---->取得节点下的某个节点的 value
@Test
public void parse() {
String json = "{\"flag\": true,\"data\": {\"userId\":1,\"uname\": \"张三\",\"age\": 18,\"sex\":true }}";
// 节点解析
// 得到解析器
JsonParser parser = new JsonParser();
// 得到根节点
JsonElement element = parser.parse(json);
// 根据JSON字符串判断当前是什么json数据类型
JsonObject root = element.getAsJsonObject();
// 解析flag 根据文档判定是boolean类型 基本数据类型
JsonPrimitive primitive = root.getAsJsonPrimitive("flag");
// 将基本数据类型转换成具体的数据类型
boolean flag = primitive.getAsBoolean();
System.out.println(flag);
// 解析data 根据文档判定是对象类型 JSONObject
JsonObject data = root.getAsJsonObject("data");
// 将对象转换为具体的对象
User user = new Gson().fromJson(data, User.class);
System.out.println(user.getUname());
}
3.使用 fastjson 处理(导入相应架包)
阿里巴巴 fastJson 是一个 Json 处理工具包,包括“序列化”和“反序列化”两部分,它 具备如下特征:速度最快,测试表明, fastjson 具有极快的性能,超越其他的 Java Json parser。包括自称最快的 JackJson;功能强大,完全支持 JavaBean、集合、 Map、 日期、 Enum,支持范型,支持自省;无依赖。
下载路径:https://github.com/alibaba/fastjson/releases/tag/1.2.13
a.转为 json 字符串
b.解析成对象
package com.shsxt.test;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import com.shsxt.po.User;
public class FastJsonTest {
@Test
public void test() {
fail("Not yet implemented");
}
@Test
public void testToJson(){
// 得到对象
User user = new User(1, "zhangsan", 18, true);
// 将javaBean转换成JSON字符串
String json1 = JSON.toJSONString(user);
System.out.println(json1);
// 定义集合
List<String> list = new ArrayList<>();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");
String json2 = JSON.toJSONString(list);
System.out.println(json2);
List<User> userList = new ArrayList<>();
User user1 = new User(1, "zhangsan", 18, true);
User user2 = new User(2, "lisi", 19, false);
User user3 = new User(3, "wangwu", 20, true);
userList.add(user1);
userList.add(user2);
userList.add(user3);
String json3 = JSON.toJSONString(userList);
System.out.println(json3);
}
@Test
public void testToObject() {
// 定义JSON字符串
String json1= "{\"userId\":1,\"uname\":\"zhangsan\",\"age\":18,\"sex\":true}";
User user = JSON.parseObject(json1,User.class);
System.out.println(user.getUname());
// 定义json对象
String json2 = "[\"zhangsan\",\"lisi\",\"wangwu\"]";
List<String> list = JSON.parseArray(json2,String.class);
System.out.println(list.get(2));
String json3 = "[{\"age\":18,\"sex\":true,\"uname\":\"zhangsan\",\"userId\":1},{\"age\":19,\"sex\":false,\"uname\":\"lisi\",\"userId\":2},{\"age\":20,\"sex\":true,\"uname\":\"wangwu\",\"userId\":3}]";
List<User> userList = JSON.parseArray(json3,User.class);
System.out.println(userList.get(1).getUname());
}
}
要将数据相应首先要将JSON对象转化为串
package com.shsxt.web;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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 com.alibaba.fastjson.JSON;
import com.shsxt.po.User;
@WebServlet("/test")
public class ServletTest extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<User> userList = new ArrayList<>();
User user1 = new User(1, "zhangsan", 18, true);
User user2 = new User(2, "lisi", 19, false);
User user3 = new User(3, "wangwu", 20, true);
userList.add(user1);
userList.add(user2);
userList.add(user3);
String json = JSON.toJSONString(userList);
response.getWriter().write(json);
}
}