1.jsp的介绍和配置
1.1.简介
JSP: Java Server Page SUN公司提供的动态网页编程技术,是Java Web服务器端的动态资源.
它相比html而言,html只能为客户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为客户提供动态数据
简单来说:JSP是一个模版引擎,它简化了开发,封装了servlet响应html标签的繁琐代码。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。
JSP就是一种特殊的servlet.
1.2.准备工作
新建JSP页面
2.jsp的注释
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Jsp页面</title>
</head>
<body>
<h1>你好 jsp</h1>
<pre>
JSP中 有两种类型的注释:
1.显式注释
能够在客户端查看的注释
1.继承HTML风格的注释 <!--HTML注释-->
<!--HTML注释-->
2.隐式注释
不能再客户端查看的注释
1.JSP自己的注释 <%--jsp自己的注释--%>
<%--Jsp自己的注释--%>
2.继承java的注释
//单行注释
/*多行注释*/
</pre>
<%
//这是单行注释
/**这是多行注释*/
%>
</body>
</html>
页面效果
3.Scriptle脚本小程序
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Scriptlet脚本小程序</title>
</head>
<body>
<%--
Scriptlet脚本小程序
JSP一共有三种Scriptlet脚本小程序:
第一种:Java脚本段,可以写Java代码,定义局部变量、编写语句等
<%
//可以写Java代码
%>
生成的代码在servlet中的service方法体中
第二种:声明、声明全局变量、方法、类等
<%!
//声明全局变量
%>
生成的代码在servlet的类体中
第三种:输出表达式,可以输出变量或字面量
<%=数值%>
生成的代码在servlet中的service方法体中,相当于out.print()输出
--%>
<%-- 第一种:java脚本段,可以写java代码,定义局部变量、编写语言等 --%>
<%
//定义局部变量
String str="hello jsp";
//输出内容到控制台
System.out.println(str);
//输出内容到浏览器
out.print(str);
//输出全局变量
out.print("全局变量:"+num);
%>
<%--第二种:声明、声明全局变量、方法、类等--%>
<%!
//声明全局变量
int num=0;
%>
<%--第三种:输出表达式,可以输出变量或字面量--%>
<%=str%>
</body>
</html>
页面效果
4.jsp中的指令标签
使用包含操作,可以将一些重复的代码包含进来继续使用,从正常的页面组成来看,有时可能分为几个区域.而其中的一些区域可能是一直不需要改变的,改变的就其中的一个具体内容区域.现在有两种方法可以实现上述功能.
方法一:在每个JSP页面(HTML)都包含工具栏、头部信息、尾部信息、具体内容
方法二:将工具栏、头部信息、尾部信息都分成各个独立的文件,使用的时候直接导入
很明显,第二种方法比第一种更好,第一种会存在很多重复的代码,并且修改很不方便,在JSP中如果想要实现包含的操作,有两种做法:静态包含、动态包含,静态包含使用include指令即可,动态包含则需要使用include动作标签.
动态包含在代码的编译阶段,包含和被包含部分是两个独立的部分,只有当运行时,才会动态包含进来,好比方法的调用.
4.1. include静态包含
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
int num=1;
%>
<h2>头部内容</h2>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>尾部内容</h2>
<%
//获取动态包含传递的参数
String uname=request.getParameter("uname");
String msg=request.getParameter("msg");
out.print(uname+","+msg);
%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>include静态包含</title>
</head>
<body>
<%--
include静态包含
格式:
<%@include file="要包含的页面地址"%>
特点:
1.将内容进行了直接的替换
2.静态包含只会生成一个源码文件,最终的内容全部在 jspService方法体中(源码文件中)
3.不能出现同名变量
4.运行效率高一点点.耦合性较高,不够灵活
--%>
<%@include file="03-header.jsp"%>
<h2>主题内容</h2>
<%@include file="03-footer.jsp"%>
</body>
</html>
页面效果
4.2.include动态包含
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>include动态包含</title>
</head>
<body>
<%--
include动态包含
格式:
<jsp:include page="要包含页面路径"></jsp:include>
特点:
1.动态包含相当于方法的调用
2.动态包含会生成多个源码文件
3.可以定义同名变量
4.效率高,耦合度低
注意:
当动态包含不需要传递参数时,include双标签之间不要有任何内容,包括换行和空格
使用动态包含传递参数
<jsp:include page="要包含页面的路径">
<jsp:param name="参数名" value="参数值"/>
</jsp:include>
注意:name属性不支持表达式,value属性支持表达式
获取参数:
request.getParaneter(name);通过指定参数名称获取参数值
--%>
<jsp:include page="03-header.jsp"></jsp:include>
<%
int num=1;
%>
<h2>主题内容</h2>
<jsp:include page="03-footer.jsp"></jsp:include>
<%--动态包含传递参数--%>
<%
String str="hello";
%>
<jsp:include page="03-footer.jsp">
<jsp:param name="uname" value="admin"/>
<jsp:param name="msg" value="<%=str%>"/>
</jsp:include>
</body>
</html>
页面效果
5.Jsp的四大域对象
5.1.四种属性范围
在jsp中提供了四种属性的保存范围,所谓的保存范围,指的就是一个设置的对象,可以在多少个页面中保存并可以继续使用
1.page范围
pageContext:只在一个页面中保存属性,跳转之后无效
2.request范围
request:只在一个请求中保存,服务器调整后依然有效
3.session范围
session:在一次会话范围中,无论何种跳转都可以使用
4.application范围
application:在整个服务器上保存
5.2.验证属性范围的特点
使用哪个范围:在合理的范围尽可能小
6.实现用户登录-简易版
后端代码:
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置客户端的编码格式
request.setCharacterEncoding("UTF-8");
//结束客户端传过来的参数
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
//判断参数是否为空
if(uname==null||"".equals(uname.trim())){
//提示用户信息
request.setAttribute("msg","用户姓名不能为空");
//请求跳转到login.jsp
request.getRequestDispatcher("login.jsp").forward(request,response);
return;
}
if(upwd==null||"".equals(upwd.trim())){
//提示用户信息
request.setAttribute("msg","用户密码不能为空");
//请求跳转到login.jsp
request.getRequestDispatcher("login.jsp").forward(request,response);
return;
}
//判断账号是否正确
if(!uname.equals("admin")||!upwd.equals("admin")){
//提示用户信息
request.setAttribute("msg","登录失败");
//请求跳转到login.jsp
request.getRequestDispatcher("login.jsp").forward(request,response);
return;
}
//登录成功
//设置登录信息到作用域
request.getSession().setAttribute("uname",uname);
//跳转到index。jsp页面
response.sendRedirect("index.jsp");
}
}
前端:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登入</title>
</head>
<body>
<form action="loginServlet" method="post">
账号:<input type="text" name="uname"><br>
密码:<input type="password" name="upwd"><br>
<button>登录</button>
<%--获取后台设置在作用域中的数据,并显示--%>
<span style="color:red;font-size: 12px"><%=request.getAttribute("msg")%></span>
</form>
</body>
</html>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h2>欢迎<%=session.getAttribute("uname")%>登录!</h2>
</body>
</html>
页面效果
7.el表达式
7.1.el表达式的语法:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el表达式</title>
</head>
<body>
<%--
EL表达式
作用:
简化JSP代码
格式:
${域对象名称}
操作对象:
EL表达式一般操作的是域对象,不能操作局部变量
操作范围:-从小范围到大范围依次寻找
page范围
request范围
session范围
application范围
注意:
1.如果el表达式获取域对象的值为空,默认为空字符串
2.el表达式默认从小到大范围去找,未找到则为空串
--%>
<%--设置数据--%>
<%
pageContext.setAttribute("name","zhangsan");
request.setAttribute("name","lisi");
session.setAttribute("name","wangwu");
application.setAttribute("name","sijunxi");
//定义局部变量
String str="hello";
%>
<%--获取数据--%>
获取局部变量:${str}<br>
获取域对象:${name}
获取指定范围的域对象:<br>
<%--
page范围:${pageScope.name}
request范围:${requestScope.name}
session范围:${sessionScope.name}
application范围:${applicationScope.name}
--%>
</body>
</html>
页面效果:
7.2.el表达式的使用
7.2.1.获取数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el表达式的使用</title>
</head>
<body>
<%--
el表达式的使用
获取List
获取List的size ${list.size}
获取List的指定下标的值 ${list[下标]}
注:list代表的是限域变量名
获取map
获取Map中指定key的value ${map.key}或${map["key"]}
注意:map代表的是限域变量名
获取JavaBean对象
获取JavaBean中的属性
${JavaBean.属性名} 或 ${JavaBean.get属性名()}
注意:JavaBean中的属性字段必须提供get方法
--%>
<%
//List
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list",list);
//Map
Map map=new HashMap<>();
map.put("aaa","111");
map.put("bbb","222");
map.put("ccc","333");
request.setAttribute("map",map);
//JavaBean对象
User user=new User();
user.setUserId(1);
user.setUname("zhangsan");
user.setUpwd("123456");
request.setAttribute("user",user);
%>
<h4>获取List</h4>
获取List的size:${list.size()}<br>
获取List的指定下标的值:${list[1]}<br>
<h4>获取Map</h4>
获取Map指定key的value值:${map.aaa}---${map["bbb"]}
<h4>获取JavaBean</h4>
获取JavaBean对象:${user}<br>
获取JavaBean中的属性:${user.uname}--${user.getUname()}
</body>
</html>
页面效果
7.2.2.empty和EL运算
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el表达式的使用</title>
</head>
<body>
<%--
EL表达式的使用
empty
判断域对象是否为空
为空,返回true
不为空,返回false
如果域对象是字符串
不存在的域对象:true
空字符串:true
null:true
如果域对象是List
null:true
没有长度的List(size):true
如果域对象是Map
null:true
空map对象:true
如果域对象是JavaBean
null:true
空对象:false
判断域对象不为空
${!empty 限域变量名}
--%>
<%
//字符串
request.setAttribute("str1","aaa");
request.setAttribute("str2","");
request.setAttribute("str3",null);
//List
List list1=new ArrayList<>();
List list2=null;
List list3=new ArrayList<>();
list3.add(1);
request.setAttribute("list1",list1);
request.setAttribute("list2",list2);
request.setAttribute("list3",list3);
//Map
Map map1=null;
Map map2=new HashMap<>();
Map map3=new HashMap<>();
map3.put(1,2);
request.setAttribute("map1",map1);
request.setAttribute("map2",map2);
request.setAttribute("map3",map3);
//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);
%>
<div>判断字符串是否存在</div>
${empty str} <br>
${empty str1} <br>
${empty str2} <br>
${empty str3} <br>
<hr>
<div>判断集合是否存在</div>
${empty list1} <br>
${empty list2} <br>
${empty list3} <br>
<hr>
<div>判断Map是否存在</div>
${empty map1} <br>
${empty map2} <br>
${empty map3} <br>
<hr>
<div>判断JavaBean是否存在</div>
${empty user1} <br>
${empty user2} <br>
${empty user3} <br>
<hr>
<%
request.setAttribute("a",10);
request.setAttribute("b",2);
request.setAttribute("c","aa");
request.setAttribute("d","bb");
%>
<%--
比较两个值是否相等,返回true或false
== 或 eq
--%>
${a == b}<br>
${c == d}<br>
${c eq d}<br>
${a == 5}<br>
${c == "aa"}<%--true--%>
${a == 10}
${c eq "aa"}
<hr>
<%--
加法: +
减法: -
乘法: *
除法: /或div
--%>
${a + b}<br>
${a / b} 或 ${a div b}
${a * b}<br>
<hr>
<%--
大于: >
小于: <
大于等于:>=
小于等于:<=
--%>
${a > b}
${a + 1 >10 }
${a + b>=10}
${a > b &&b>5}
${a + b>10 || a-b>5}
</body>
</html>
页面效果
8.JSTL
8.1.标签的使用
链接:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
代码如下:
<%--1.通过taglib标签引入所需要的标签库--%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSTL的使用</title>
<%--
JSTL的使用
1.下载JSTL所需要的jar包(standard.jar 和jstl.jar)
2.在项目对的web目录下的WEB-INF中新建lib目录,将jar拷贝进去
3.选择"File",再选择"Project Structure"
4.选择"Modules",选择右侧的"Dependencies",选择右侧的"+"号,将对应的lib目录加载进来
5.在需要使用标签库的JSP页面通过taglib标签引入指定库
--%>
</head>
<body>
<c:if test="${1==1}">
hello JSTL
</c:if>
</body>
</html>
页面效果
8.2.条件动作标签
8.2.1.if标签
语法格式
代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
if标签
格式:
<c:f test="<boolean>" var="<string>" scope="<string>">
...
</c:if>
常用属性;
test:条件判断,操作的是域对象,接收返回结果是boolean类型的值-(必要属性)
var:限域变量名(存放在作用域中的变量名),用来接收判断结果的值-(可选属性)
scope:限域变量名的范围(page,request,session,application)-(可选属性)
注意:
1.标签操作的一般都是域对象
2.if标签没有else,如果想要else的效果,就需要设置两个完全相反的条件
--%>
<%
request.setAttribute("num",10);
%>
<c:if test="${num>0}" >
数值大于0
</c:if>
<c:if test="${num<=0}" >
数值不大于0
</c:if>
<br>
<c:if test="${num>100}" var="flag" scope="request" >
数值大于100
</c:if>
${flag}--${requestScope.flag}--${sessionScope.flag}
</body>
</html>
页面效果
8.2.2. choose,when和otherwise标签
语法格式:
代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>choose,when和otherwise标签</title>
</head>
<body>
<%--
choose,when和otherwise标签
<c:choose>
<c:when test="<boolean>">
......
</c:when>
<c:when test="<boolean>">
......
</c:when>
......
<c:otherwise>
......
</c:otherwise>
</c:choose>
属性:
1.choose标签没有属性
2.when标签只有一个test属性-必须属性
3.otherwise标签没有属性
注意:
1.when必有一个test标签
2.choose必须有一个when标签,可以没有otherwise
3.otherwise标签必须设置在最后
4.choose标签中只能设置when标签与otherwise标签
5.when标签和otherwise标签可以嵌套其他标签
--%>
<%
request.setAttribute("score",80);
%>
<c:choose>
<c:when test="${score<60}">
<h2>你个渣渣</h2>
</c:when>
<c:when test="${score==60}">
<h2>及格就行</h2>
</c:when>
<c:otherwise>
<h2>很优秀啊</h2>
</c:otherwise>
</c:choose>
</body>
</html>
页面效果
8.3.迭代标签
8.3.1foreach标签
8.3.1.1语法格式
代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: sijunxi
Date: 2022/5/13
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>foreach标签</title>
</head>
<body>
<%--
foreach标签
格式:
<c:forEach
items="<object>"
begin="<int>"
end="<int>"
step="<int>"
var="<String>"
varStatus="<String>"
</c:forEach>
属性:
begin:开始数
end:结束数
step:间隔数
var:限域变量名,用来接收当前遍历的成员变量
items:要循环的数据(数组,List等)
varStatus:
1.迭代主题内容多次
<c:forEach var="限域变量名" begin="开始数" end="结束数" step="间隔数">
</c:forEach>
相当于Java中for...int
for(int i=0;i<10;i++){
}
2.循环
<c:forEach items="要循环的数据" var="限域变量名" >
</c:forEach>
相当于Java中的foreach
for(String str:list){
}
--%>
<%--迭代主题内容多次--%>
<c:forEach var="i" begin="1" end="10" step="2">
${i}<br>
</c:forEach>
<%--循环--%>
<%
List<Object> list = new ArrayList<>();
for (int i=0;i<=10;i++){
list.add("A"+i);
}
request.setAttribute("li",list);
%>
<c:forEach items="${li}" var="item">
${item}
</c:forEach>
</body>
</html>
页面效果
<%--循环对象集合--%>
<%
ArrayList<User> userList = new ArrayList<>();
User user=new User(1,"zhangsan","123456");
User user2=new User(2,"lisi","123321");
User user3=new User(3,"wangwu","888888");
userList.add(user);
userList.add(user2);
userList.add(user3);
//将数据设置到作用域中
request.setAttribute("userList",userList);
%>
<%--判断集合是否为空--%>
<c:if test="${!empty userList}">
<%--当集合不为空时遍历--%>
<table align="center" width="800" border="1" style="border-collapse: collapse">
<tr>
<th>用户编号</th>
<th>用户名称</th>
<th>用户密码</th>
<th>用户操作</th>
</tr>
<c:forEach items="${userList}" var="user">
<tr align="center">
<td>${user.userId}</td>
<td>${user.uname}</td>
<td>${user.upwd}</td>
<td><button>修改</button></td>
</tr>
</c:forEach>
</c:if>
<%--循环map--%>
<%
Map<Object,Object> map = new HashMap<>();
map.put("1","aaa");
map.put("2","bbb");
map.put("3","ccc");
request.setAttribute("map",map);
%>
<c:forEach items="${map}" var="m">
key:${m.key} value:${m.value} <br>
</c:forEach>
页面效果
8.4.格式化动作标签
8.4.1.formatNumber标签
8.4.1.1.语法格式
8.4.2.formatDate标签
语法
属性
<%
request.setAttribute("date",new Date());
%>
${date}<br>
<fmt:formatDate value="${date}"/><br>
<fmt:formatDate value="${date}" type="time"/><br>
<fmt:formatDate value="${date}" type="both"/><br>
<fmt:formatDate value="${date}" dateStyle="full"/><br>
<fmt:formatDate value="${date}" timeStyle="short"/><br>
<fmt:formatDate value="${date}" pattern="yyyy-MM-dd"/><br>
页面效果
8.4.3.parseNumber标签
语法
属性
代码
页面效果
8.4.3.parseDate标签
语法
属性
代码
页面效果