JSP
1.JSP的基础语法
JSP:Java Server Page SUN 公司提供的动态网页编程技术,是 Java Web 服务器端的动态资源。
它相比 html 而言,html 只能为用户提供静态数据,而 Jsp 技术允许在页面中嵌套 java 代码,为用户提供动态数据。
相比 servlet 而言,servlet 很难对数据进行排版,而 jsp 除了可以用 java 代码产生动态数据的同时,也很容易对数据进行排版。
1.1 JSP 的注释
1. 显式注释 (在浏览器中审查元素或查看源代码可以看到的注释)
1. 继承HTML风格
<!-- HTML的注释 -->
2. 隐式注释(在浏览器中审查元素或查看源代码不可以看到的注释)
1. JSP自己的注释
<%-- JSP注释 --% >
2. 继承Java风格
// 单行注释
/* 多行注释 */
1.2 Scriptlet 脚本
1. Java脚本段
定义局部变量,编写语句。JSP生成的源码在编译后的Servlet类中的service方法体中
<%
%>
2. 声明
声明全局变量、方法、类等。JSP生成的源码在编译后的Servlet类体中
<%!
%>
3. 输出
输出变量或字面量。JSP生成的源码在编译后的Servlet类中的service方法体中
<%= %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP的基础语法</title>
</head>
<body>
HTML的注释:<!-- HTML的注释 --> <br>
JSP的注释:<%-- JSP的注释 --%><br>
Java的注释:
<%
// 这是单行注释
/* 这是多行注释 */
%>
<hr>
<%=b%>
<h3>Java脚本段</h3>
<%
// 定义变量
int a = 1;
// 控制台打印
System.out.println(a);
// 浏览器输出
out.print(a);
%>
<h3>声明</h3>
<%!
// 定义全局变量
int b = 10;
%>
</body>
</html>
2 JSP的指令标签
2.1 include静态包含
<%@include file="要包含的文件的路径"%>
特点:
相当于将内容进行复制,只会生成一个jsp源码文件,不能出现同名变量。运行效率高一点点,但耦合度高,不够灵活。
2.2 include动态包含
动态包含在代码的编译阶段,包含和被包含部分是两个独立的部分,只有当运行时,才会动态包含进来,好比方法的调用。
<jsp:include page="要包含文件的路径"></jsp:include>
特点:
相当于方法的调用,会生成多个JSP的源码文件,可以定义同名变量。运行效率高,耦合度低。
通过动态包含传递参数
<jsp:include page="head.jsp">
<jsp:param name="参数名" value="参数值"/>
</jsp:include>
注:
1. 如果include动态包含没有参数需要传递,双标签中不要有任何内容,包括空格和回车
2. 设置参数时,name属性不支持任何表达式,value属性支持表达式
创建head.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>头部</title>
</head>
<body>
<h2>头部信息</h2>
<%
int a = 10;
%>
<%-- 获取传递的参数 --%>
<%=request.getParameter("uname")%> <br>
<%=request.getParameter("upwd")%>
</body>
</html>
创建foot.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>底部</title>
</head>
<body>
<h2>底部内容</h2>
</body>
</html>
创建主体jsp
<%
int a = 1;
String pwd = "123456";
%>
<%-- 通过静态传递参数 --%>
<jsp:include page="head.jsp"></jsp:include>
<h2>主体内容</h2>
<jsp:include page="foot.jsp"></jsp:include>
<%-- 通过动态包含传递参数 --%>
<jsp:include page="head.jsp">
<jsp:param name="uname" value="admin"/>
<jsp:param name="upwd" value="<%=pwd%>"/>
</jsp:include>
3. JSP的四大域对象
3.1四种属性范围
在JSP中提供了四种属性的保存范围,所谓的属性保存范围,指的就是一个设置的对象,可以再多少个页面中保存并可以继续使用。
1. page范围
pageContext : 只在一个页面中保存属性,跳转之后无效
2. request范围
request : 只在一次请求中保存,服务器跳转后依然有效
3. session范围
session : 在一次会话范围中,无论何种跳转都可以使用
4. application范围
application : 在整个服务器上保存
具体概述
1. page
本页面取得,服务器端跳转( <jsp :forward> )后无效
2. request
服务器跳转有效,客户端跳转无效
如果是客户端跳转,则相当于发出了两次请求,那么第一次的请求将不存在了;如果希望不管是客户端还是
服务器跳转,都能保存的话,就需要继续扩大范围。
3. session
无论客户端还是服务器端都可以取得,但是现在重新开启一个新的浏览器,则无法取得之前设置session 了,因为每一个session只保存在当前的浏览器当中,并在相关的页面取得。
对于服务器而言,每一个连接到它的客户端都是一个session。
如果想要让属性设置一次之后,不管是否是新的浏览器打开都能取得则可以使用application
4.application
所有的application属性直接保存在服务器上,所有的用户(每一个session)都可以直接访问取得
只要是通过application设置的属性,则所有的session都可以取得,表示公共的内容,但是如果此时服务器重启了,则无法取得了,因为关闭服务器后,所有的属性都消失了,所以需要重新设置
注意:使用哪个范围呢?
答:在合理范围尽可能小
4. EL表达式的使用
4.1语法:${限域变量名}
一般操作的是域对象的值,无法操作变量。
取值范围:从小到大范围,依次查找;如果找到,则显示;未找到,则往大范围找,如果都未找到,则显示空字符串。
从小到大:page范围 -> request范围 -> session范围 -> application范围
获取指定范围的值: pageScope、requestScope、sessionScope、applicationScope
4.2操作数据
List
大小:${限域变量名.size()}
获取指定值:${限域变量名[下标]}
Map
获取指定值:${限域变量名.key} -- ${限域变量名["key"]}
JavaBean
给属性字段提供get方法
${限域变量名.属性字段名} -- ${限域变量名.get属性字段名()}
4.3empty为空判断 (空返回true;否则返回false)
字符串:判断null和空字符串
List:判断null和size
JavaBean:判断null
4.4等值比较
比较两个值是否相等,返回true或false
== 或 eq
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="com.xxx.po.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式</title>
</head>
<body>
<%
// page范围
pageContext.setAttribute("uname","admin");
// request作用域
request.setAttribute("uname","zhangsan");
// session作用域
request.getSession().setAttribute("uname","lisi");
// servletContext对象
request.getServletContext().setAttribute("uname","wangwu");
// 定义变量
String str = "hello";
%>
获取域对象:${uname} <br>
获取域对象:${userName} <br>
获取指定范围的域对象:${sessionScope.uname} <br>
获取变量:${str} <br>
<hr><br>
<h2>操作指定类型的数据</h2>
<%
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("mylist", list);
%>
获取List的size:${mylist.size()} <br>
获取指定下标的值:${mylist[1]}<br>
<br>
<%
Map map = new HashMap();
map.put("aaa", "111");
map.put("bbb", 2222);
map.put("ccc-a", 333);
request.setAttribute("map", map);
%>
获取Map的值:${map.aaa} -- ${map["bbb"]}<br>
<br>
<%
User user = new User();
user.setUserId(1);
user.setUname("zhangsan");
user.setUpwd("123456");
request.setAttribute("user",user);
%>
获取JavaBean对象:${user} <br>
获取属性字段:${user.uname } -- ${user.getUpwd()} <br>
<br><hr>
<h4>empty</h4>
<%
// 字符串
String str1 = null;
String str2 = "";
String str3 = "test";
request.setAttribute("str1",str1);
request.setAttribute("str2",str2);
request.setAttribute("str3",str3);
%>
${str1 == null || str1 == ""} -- ${str1 != null && str1 != ""} -- ${!empty str1}
<%-- 判断null与空字符串 --%>
${empty str1} -- ${empty str2} -- ${empty str3}
<br><br>
<%
// List
List list1 = null;
List list2 = new ArrayList<>();
List<String> list3 = new ArrayList<>();
list3.add("ccc");
request.setAttribute("list1", list1);
request.setAttribute("list2", list2);
request.setAttribute("list3", list3);
%>
<%-- 判断null和长度为0 --%>
${empty list1} -- ${empty list2} -- ${empty list3}
<br><br>
<%
// JavaBean
User user1 = null;
User user2 = new User();
User user3 = new User();
user3.setUserId(1);
request.setAttribute("user1",user1);
request.setAttribute("user2",user2);
request.setAttribute("user3",user3);
%>
<%-- 判断null --%>
${empty user1} -- ${empty user2} -- ${empty user3}
</body>
</html>
5. JSTL
JSTL标签库操作的是域对象!!
5.1 条件动作标签
if标签
格式:
<c:if test="条件">
满足条件执行的代码
</c:if>
常用属性:
test:判断条件,返回boolean类型,必须设置的属性
var:用来接收判断结果,值为true或false,存在作用域中的变量(限域变量名)
scope:设置限域变量名的域范围 (page|request|session|application)
注:JSTL没有else标签,如果想要else的效果,需要使用if标签并设置完全相反的条件
choose、when 和 otherwise 标签
1. choose和otherwise标签没有属性,when标签必须有test属性
2. choose标签中只能包含when和otherwise标签,when和otherwise标签中可以嵌套其他标签
3. choose标签中必须要有至少一个when标签,可以没有otherwise标签
4. otherwise标签必须放在最后一个when标签之后
5. otherwise标签在所有的when标签不成立时执行
5.2 迭代标签(forEach标签)
Java中的循环
for(int i = 0; i < length; i++) {
}
for (String str : mylist) {
}
forEach标签
遍历主体内容多次
<c:forEach var="限域变量名" begin="开始数" end="结束数" step="间隔数">
</c:forEach>
遍历
<c:forEach var="限变量名域" items="需要遍历的数据">
</c:forEach>
测试代码jsp
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.xxx.po.User" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 导入指定标签库 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>JSTL标签</title>
</head>
<body>
<%
request.setAttribute("score",60);
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("mylist", list);
%>
<h2>if标签</h2>
<c:if test="${score < 60}" var="flag" scope="request">
<h4>你个小渣渣!</h4>
</c:if>
<c:if test="${score == 60}">
<h4>分不在高,及格就行!</h4>
</c:if>
<c:if test="${score > 60}">
<h4>哎哟不错哦!</h4>
</c:if>
获取条件判断的结果:${flag} <br>
获取request范围:${requestScope.flag}<br>
获取session范围:${sessionScope.flag}<br>
<h2>choose、when 和 otherwise 标签</h2>
<c:choose>
<c:when test="${score < 60}">
<h4>不及格!</h4>
</c:when>
<c:when test="${score >= 60 && score < 80}">
<h4>良好!</h4>
</c:when>
<c:when test="${score >= 80 && score < 90 }">
<h4>优秀!</h4>
</c:when>
<c:otherwise>
<h4>棒!</h4>
</c:otherwise>
</c:choose>
<h2>forEach标签</h2>
<c:forEach var="i" begin="0" end="5" step="1">
${i} --
</c:forEach>
<br>
<c:forEach var="str" items="${mylist}" varStatus="itemp">
当前数据:${str} -- 下标:${itemp.index} -- 循环次数:${itemp.count} -- 是否是第一个被循环:${itemp.first} -- 是否是最后一次被循环:${itemp.last} <br>
</c:forEach>
<br>
<!-- 循环对象集合 -->
<%
List<User> userList = new ArrayList<User>();
User user = new User(1,"zhangsan","123456");
User user2 = new User(2,"lisi","123321");
User user3 = new User(3,"wangwu","654321");
userList.add(user);
userList.add(user2);
userList.add(user3);
// 将数据设置到作用域中
request.setAttribute("userList", userList);
%>
<c:forEach var="user" items="${userList}">
用户编号:${user.userId} -- 用户名称:${user.uname} -- 用户密码:${user.upwd} <br>
</c:forEach>
<br>
<%-- 将用户数据显示在表格中 --%>
<%-- 判断数据是否存在 --%>
<c:if test="${!empty userList}">
<table width="600px" border="1" style="border-collapse: collapse">
<tr>
<th>用户编号</th>
<th>用户姓名</th>
<th>用户密码</th>
</tr>
<%-- 遍历集合 --%>
<c:forEach var="user" items="${userList}">
<tr align="center">
<td>${user.userId}</td>
<td>${user.uname}</td>
<td>${user.upwd}</td>
</tr>
</c:forEach>
</table>
</c:if>
<br>
<!-- 遍历Map -->
<%
Map<String,Object> map = new HashMap<>();
map.put("map1", "aaa");
map.put("map2", "bbb");
map.put("map3", "ccc");
pageContext.setAttribute("mymap", map);
%>
<c:forEach var="m" items="${mymap}">
键:${m.key},值:${m.value} <br>
</c:forEach>
</body>
</html>
5.3格式化动作标签
JSTL 提供了格式化和解析数字和日期的标签,我们讨论里面有:
formatNumber、formatDate、parseNumber及 parseDate。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<html>
<head>
<title>JSTL</title>
</head>
<body>
<h3>formatNumber标签</h3>
<%
request.setAttribute("num1", 1.5);
request.setAttribute("num2", 18);
request.setAttribute("num3", 100);
%>
${num1} -- ${num2} -- ${num3} <br>
百分比类型:<fmt:formatNumber value="${num1}" type="percent" ></fmt:formatNumber> <br>
数值类型:<fmt:formatNumber value="${num2}" type="number" ></fmt:formatNumber> <br>
货币类型:<fmt:formatNumber value="${num3}" type="currency" ></fmt:formatNumber> <br>
<hr>
<h3>formatDate标签</h3>
<%
request.setAttribute("date", new Date());
%>
当前时间:${date} <br>
日期型:<fmt:formatDate value="${date}" type="date" dateStyle="full"></fmt:formatDate> ||
<fmt:formatDate value="${date}" type="date"></fmt:formatDate><br>
时间型:<fmt:formatDate value="${date}" type="time"></fmt:formatDate><br>
日期时间型:<fmt:formatDate value="${date}" type="both"></fmt:formatDate><br>
自定义格式类型:<fmt:formatDate value="${date}" pattern="yyyy年MM-dd"></fmt:formatDate><br>
</body>
</html>