JSP
- JSP全称为Java Server Page 是SUN公司提供的动态网页编程技术,是Java Web服务器端的动态资源;
- 其相比于html而言,html只能为用户提供静态数据,而JSP技术允许在页面中嵌套Java代码,为用户提供动态数据;
- 其相比于Servlet而言,Servlet很难对数据进行排版,而JSP除了可以用Java代码产生动态数据的同时,也很容易对数据进行排版;
- 不管是JSP还是Servlet,虽然都可以用于动态web资源,但由于这两门技术各自的特点,开发者逐渐将Servlet作为Web应用中的控制器组件来使用,将JSP技术作为数据显示模版来使用;
- 从本质上来看,JSP就是一个Servlet,当我们第一次访问JSP时,JSP引擎都会将这个JSP翻译成一个Servlet,这个文件存放在Tomcat(源码目录)中的work目录中;
在IDEA中关于JSP的配置
- 设置编码格式;
- 设置页面模版;
- 新建JSP页面,注意在
web
目录下创建JSP文件,如下所示:
- 运行项目,在浏览器中输入
http://localhost:8080/JSP/JSP01.jsp
,如下所示:
JSP的注释
- 显示注释:能够在客户端查看的注释;
- 继承HTML风格的注释,``
- 隐士注释:不能在客户端查看的注释;
- JSP自己的注释,
<%-- JSP注释 --%>
- 继承Java风格的注释,Java脚本段中的单行与多行注释;
- JSP自己的注释,
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
JSP页面
Hello JSP!!!
<%-- JSP注释 --%>
<%-- Java脚本段代码 --%>
<%
//单行注释
/*多行注释*/
%>
Scriptlet
- 在JSP中最重要的部分就是Scriptlet(脚本小程序),是所有嵌入在HTML代码中的Java程序;
- JSP中一共有三种Scriptlet代码,都必须使用Scriptlet标记出来;
- 第一种:Java脚本段,可以写Java代码,定义局部变量,编写语句等,
<% Java代码 %>
- 第二种:声明,声明全局变量,方法,类等等,
<%! 声明%>
- 第三种:输出表达式,可以输出变量或字面量,
<%=str%>
- 第一种:Java脚本段,可以写Java代码,定义局部变量,编写语句等,
- 案例代码:
- 创建一个
JSP03.jsp
文件,内容如下:
<%--
Created by IntelliJ IDEA.
User: ljj
Date: 2021/12/10
Time: 下午10:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
脚本小程序
<%-- 第一种:Java脚本段--%>
<%
String str = "Hello JSP";
//输出到控制台
System.out.println(str);
//输出到浏览器
out.print(str);
out.write("全局变量: " + num);
%>
<%-- 第二种:声明--%>
<%!
//声明全局变量
int num = 100;
%>
<%-- 第三种:输出表达式--%>
<%=str%>
JSP的指令标签
- 使用包含操作,可以将一些重复的代码包含进来继续使用,从正常的页面组成来看,有时可能分为几个区域,而其中的一些区域可能是一直不需要改变的,改变的是就其中的一个具体内容区域,现在有两种方法可以实现上述的功能:
- 方法一:在每个JSP页面都包含工具栏,头部信息,尾部信息,具体内容;
- 方法二:将工具栏,头部信息,尾部信息都分成各个独立的文件,使用的时候直接导入;
- 很明显第二种方法比第一种方法更好,第一种会存在很多重复代码,并且修改很不放方便,在JSP中若要想实现包含操作,有两种做法:
静态包含
与动态包含
,静态包含使用include指令即可
,动态包含则需要使用include动作标签
;
静态包含
- 格式:
<%@include file="被包含的文件名"%>
; - 特点:
- 静态包含是将内容进行直接替换,只会生成一个源码文件,最终的内容全部在_jspservices方法中(源码文件);
- 不能出现同名变量,运行效率高,但耦合性较高,不够灵活;
- 案例代码,创建一个
JSP04.jsp
文件,以及JSP_header.jsp
,JSP_footer.jsp
,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
头部
头部内容
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
底部
底部内容
- JSP04.jsp文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
静态包含
<%@include file="JSP_header.jsp"%>
主体内容
<%@include file="JSP_footer.jsp"%>
- JSP_header.jsp与JSP_footer.jsp都包含在JSP04.jsp文件中;
动态包含
- 动态包含:在代码编译阶段,包含和被包含是两个独立的部分,只有当运行时,才会动态包含进来,类比如方法的调用;
- 格式:
- 特点:
- 动态包含相当于方法的调用;
- 动态包含会生成多个源码文件;
- 可定定义同名变量;
- 效率高,耦合度低;
- 使用动态包含传递参数,格式如下:
- name属性不支持表达式,value属性支持表达式;
- 参数获取,通过
request.getParameter("字段名")
- 当动态包含不需要传递参数时,include双标签之间不要有任何内容,否则会疯狂报错;
- 案例代码:
JSP05.jsp
文件,JSP_header.jsp
与JSP_footer.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
头部
头部内容
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
底部
底部内容
<%
String name = request.getParameter("name");
String msg = request.getParameter("msg");
out.print(name + msg);
%>
- JSP05.jsp文件,如下所示:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
动态包含
主体内容
<%
String str = "lisi";
%>
- 运行项目,浏览器中输入
http://localhost:8080/JSP_war_exploded/JSP05.jsp
,结果如下:
JSP的四大域对象
- JSP中提供了四种属性的保存范围,所谓的属性保存范围,是指一个设置的对象,可以再多少个页面中保存并可以继续使用;
- page范围:pageContext只在一个页面中保存属性,跳转之后无效;
- request范围:只在一次请求中保存,服务器跳转之后依然有效;
- session范围:在一次会话范围中,无论何种跳转都可以使用;
- application范围:在整个服务器上保存;
- 跳转方式常见的有两种:
- JSP中服务端跳转,
- 客户端跳转,超链接
跳转
- JSP中服务端跳转,
- 案例代码,创建
JSP06.jsp
文件,JSP07.jsp
文件,如下: - JSP06.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
JSP四大域对象
<%
//page范围
pageContext.setAttribute("name1","yanzi");
//request范围
request.setAttribute("name2","yanzi");
//session范围
session.setAttribute("name3","yanzi");
//application范围
application.setAttribute("name4","yanzi");
%>
<%-- --%>
跳转
- JSP07.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
获取域对象
<%
//page范围
out.println("page范围: " + pageContext.getAttribute("name1") + "
");
//request范围
out.println("request范围: " + request.getAttribute("name2") + "
");
//seesion范围
out.println("seesion范围: " + session.getAttribute("name3") + "
");
//application范围
out.println("application范围: " + application.getAttribute("name4") + "
");
%>
- 首先,执行服务端跳转即
运行,在浏览器中输入http://localhost:8080/JSP_war_exploded/JSP07.jsp
,结果如下:
- 然后执行,客户端那跳转,相当于发送了两次请求,
跳转
,结果如下:
利用JSP实现一个简单的用户登录
- 首先创建
login.jsp
文件即登录首页,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录
- 然后创建服务端处理登录的Java文件
LoginServlet
,内容如下:
package com.sf.controller;
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.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
//接收客户端的参数
String name = req.getParameter("name");
String password = req.getParameter("password");
if (name == null || "".equals(name.trim())) {
//提示用户信息
req.setAttribute("msg","用户名不能为空!!!");
req.getRequestDispatcher("login.jsp").forward(req,resp);
return;
}
if (password == null || "".equals(password.trim())) {
//提示用户信息
req.setAttribute("msg","密码不能为空!!!");
req.getRequestDispatcher("login.jsp").forward(req,resp);
return;
}
if (!"admin".equals(name) || !"admin".equals(password)) {
//提示用户信息
req.setAttribute("msg","登录失败!!!");
req.getRequestDispatcher("login.jsp").forward(req,resp);
return;
}
//登录成功
//设置登录信息到session作用域
req.getSession().setAttribute("name",name);
//跳转到index.jsp
resp.sendRedirect("index.jsp");
}
}
- 登录成功后,跳转到
index.jsp
文件,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
欢迎<%=session.getAttribute("name")%>登录!!!
EL表达式
EL是为了让JSP书写起来更加简单,表达式语言的灵感来自于ECMAScript和XPath表达式语言,它提供了在JSP中简化表达式的方法,让JSP的代码变得更加简化;
语法格式:
${表达式}
;EL表达式一般操作的都是
域对象中的数据
,操作不了局部变量;当需要指定从某个特定的域对象中查找数据时,可以使用四个域对象对应的空间对象,分别为
pageScope
,requestScope
,sessionScope
,applicationScope
,EL默认的查找方式为从小到大
查找,找到即可,当域对象全部找完还未找到就会返回空字符串
;创建
JSP07.jsp
文件,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL表达式
<%
pageContext.setAttribute("name","yanzi1");
request.setAttribute("name","yanzi2");
session.setAttribute("name","yanzi3");
application.setAttribute("name","yanzi4");
//定义局部变量
String str = "Hello";
%>
获取局部变量: ${str}
获取域对象: ${name}
获取指定范围的域对象:
page范围: ${pageScope.name}
request范围: ${requestScope.name}
session范围: ${sessionScope.name}
application范围: ${applicationScope.name}
- 运行项目,在浏览器中输入`http://localhost:8080/JSP_war_exploded/JSP07.jsp,运行结果如下:
- EL表达式默认会去四大域对象中去寻找目标变量,str属于局部变量,域对象中肯定不存在,所以返回为空;
EL表达式的基本使用
- 操作
List
,Map
,JavaBean
对象,创建JSP08.jsp
文件,内容如下:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="com.sf.bean.User" %><%--
Created by IntelliJ IDEA.
User: ljj
Date: 2021/12/11
Time: 下午9:26
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL表达式的基本使用
<%
//list是限域变量名
List 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);
//Java Bean对象
User user = new User();
user.setUserId(1000);
user.setName("yanzi");
user.setPassword("asd123");
request.setAttribute("user",user);
%>
获取list
获取List的size: ${list.size()}
获取List的指定下标的值: ${list[1]}
获取map
获取Map指定key的value值: ${map.aaa} -- ${map.bbb}
获取Java Bean
获取Java Bean对象: ${user}
获取Java Bean中的属性: ${user.name} -- ${user.getPassword()}
- User对象,代码如下:
package com.sf.bean;
public class User {
private Integer userId;
private String name;
private String password;
public User() {
}
public User(Integer userId, String name, String password) {
this.userId = userId;
this.name = name;
this.password = password;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- 运行项目,浏览器中输入
http://localhost:8080/JSP_war_exploded/JSP08.jsp
,结果如下:
- 注意⚠️:EL获取Java Bean对象的属性时,Java Bean对象必须实现属性的get方法;
-
empty判空处理
:表达式为${empty 限域变量名}
- 判断域对象是否为空:
- 为空,返回true;
- 不为空,返回false;
- 若域对象是字符串时;
- 不存在的域对象,返回true;
- 为null时,返回true;
- 若域对象是List集合时;
- 为null时,返回true;
- 为空集合时,返回true;
- 若域对象是Map集合时;
- 为null时,返回true;-
- 为空时,返回true;
- 若区域对象是Java Bean对象时:
- 为null时,返回true;
- 空对象,返回false;
- 判断域对象不为空,表达式为
${!empty 限域变量名}
- 新建
JSP09.jsp
文件,代码如下:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="com.sf.bean.User" %><%--
Created by IntelliJ IDEA.
User: ljj
Date: 2021/12/11
Time: 下午10:37
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
request.setAttribute("str1","aaaa");
request.setAttribute("str2","");
request.setAttribute("str3",null);
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 map1 = null;
Map map2 = new HashMap();
Map map3 = new HashMap();
map3.put("aaa","111");
request.setAttribute("map1",map1);
request.setAttribute("map2",map2);
request.setAttribute("map3",map3);
User user1 = null;
User user2 = new User();
User user3 = new User();
user3.setUserId(123);
request.setAttribute("user1",user1);
request.setAttribute("user2",user2);
request.setAttribute("user3",user3);
%>
判断字符串是否存在
${empty str}
${empty str1}
${empty st2}
${empty str3}
判断List是否存在
${empty list1}
${empty list2}
${empty list3}
判断Map是否存在
${empty map1}
${empty map2}
${empty map3}
判断Java Bean对象是否存在
${empty user1}
${empty user2}
${empty user3}
- 运行项目,浏览器输入
http://localhost:8080/JSP_war_exploded/JSP09.jsp
,结果如下:
-
EL运算
,算术运算符,逻辑运算符等等; - 新建文件
JSP10.jsp
,内容如下:
Created by IntelliJ IDEA.
User: ljj
Date: 2021/12/11
Time: 下午10:37
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%
request.setAttribute("a",10);
request.setAttribute("b",2);
request.setAttribute("c","aa");
request.setAttribute("d","bb");
%>
比较两个值是否相等 返回true,false
${a == b}
${c == d}
${c eq d}
${a == 5}
${c == 'aa'}
加减乘除
${a + b}
${a / b}
${a - b}
${a * b}
大于,小于
${a > b}
${a + 1 > 10}
${a + b >= 10}
${a > b && b > 5}
${a + b > 10 || a - b > 5}
- 运行结果如下:
JSTL
- JSTL全称为Java Server Pages Standard Tag Library,是JSP标准标签库,是一个定制标签类库的集合,用于解决一些常见的问题,例如迭代集合,条件测试,XML处理,数据库操作等等;
- 下面来探索两个重要的标签库:
核心标签库
与格式化标签库
; - 核心标签库:http://java.sun.com/jsp/jstl/core,包括Web应用的常见工作,例如循环,表达式赋值,基本输入输出等;
- 格式化标签库:http://java.sun.com/jsp/jstl/fmt,用来格式化显示数据的工作;
- 为了在JSP页面中使用JSTL类库,必须使用taglib指令,
<%@taglib uri="" prefix="" %>
- 需要导入两个jar包,在此网址下载,
jakarta-taglibs-standard-1.1.2.zip
,然后解压将lib目录下的standard.jar
与jstl.jar
两个jar包拷贝到项目的指定目录下; - 新建项目JSTL,在Web/WEB-INF目录下,新建一个lib目录,然后将
standard.jar
与jstl.jar
两个jar包拷贝到lib目录下,如下所示:
- 然后作如下配置:
- 最后在代码中通过taglib标签引入标签库,就可以使用了,如下所示:
条件动作标签
- 条件动作指令用于处理页面的输出结果,依赖于某些输入值的情况,在Java中是利用if,if-else和switch语句来进行处理的,在JSTL中有4个标签可以执行条件式动作指令:if,choose,when和otherwise;
if标签
- if标签先对某个条件进行测试,如该条件运算结果为true,则处理它的主体内容,测试结果保存在一个Boolean对象中,并
创建一个限域变量来引用Boolean对象
,可以利用var属性设置限域变量名
,利用scope属性来指定其作用范围
; - 语法格式:
说明
- test:条件判断,操作的是域对象,接收返回结果是boolean类型的值(必要属性);
- var:限域变量名(存放在作用域中变量名),用来接收判断结果的值(可选属性);
- scope:限域变量名的范围(可选属性);
- 标签操作的一般都是域对象;
- if标签没有else,如想要else效果,就需要设置两个完全相反的条件;
- 新建
JSTL02.jsp
文件,代码如下:
<%--
Created by IntelliJ IDEA.
User: ljj
Date: 2021/12/11
Time: 下午11:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
if标签
<%
request.setAttribute("num",10);
%>
数值大于0
数值不大于0
${flag} -- ${requestScope.flage}
choose,when与otherwise标签
- choose与when标签的作用域Java中的switch和case关键字相似,
- switch语句中有case,正如choose标签中有when;
- switch语句中default,正如choose标签中有otherwise;
- 语法格式如下:
- choose标签是没有属性的;
- when标签只有一个test属性,必须属性;
- otherwise标签没有属性;
- 创建
JSTL.jsp
文件,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Title
<%
request.setAttribute("score",80);
%>
你是个人渣
可以,你及格了
良好了
你非常的优秀
- choose标签中至少有一个when标签,可以没有otherwise标签;
- otherwise标签必须设置在最后一个when标签之后;
- choose标签中只能设置when标签与otherwise标签,when标签与otherwise标签中是可以嵌套其他标签的;
迭代标签
- forEach是将一个主体内容多次迭代,或者迭代一个集合;
- 语法格式1如下:
- 相当于Java中
for(int i = 0; i< 100; i++)
- 语法格式2如下:
- 相当于Java中
for(String str : list)
- 新建
JSTL04.jsp
文件,内容如下:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: ljj
Date: 2021/12/12
Time: 下午12:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Title
//迭代
${i}
<%
List list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add("A:" + i);
}
pageContext.setAttribute("list",list);
%>
//循环
${item}
- 遍历List与Map,新建
JSTL04.jsp
文件,代码如下:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.sf.bean.User" %>
<%@ page import="javax.jws.soap.SOAPBinding" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %><%--
Created by IntelliJ IDEA.
User: ljj
Date: 2021/12/12
Time: 下午12:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Title
<%
List list = new ArrayList<>();
User user1 = new User(1,"yanzi1","asd123");
User user2 = new User(2,"yanzi2","asd123");
User user3 = new User(3,"yanzi3","123456");
list.add(user1);
list.add(user2);
list.add(user3);
//将数据设置到作用域
request.setAttribute("list",list);
%>
用户编号
用户名称
用户密码
用户操作
${user.userId}
${user.name}
${user.password}
<%
Map map = new HashMap<>();
map.put("map1","aaa");
map.put("map2","bbb");
map.put("map3","ccc");
pageContext.setAttribute("map",map);
%>
key: ${item.key} value: ${item.value}
- Java Bean对象 User文件如下:
package com.sf.bean;
public class User {
private Integer userId;
private String name;
private String password;
public User() {
}
public User(Integer userId, String name, String password) {
this.userId = userId;
this.name = name;
this.password = password;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- 运行项目,浏览器输入
http://localhost:8080/JSTL_war_exploded/JSTL04.jsp
,运行结果如下:
格式化动作标签
- JSTL提供了格式化和解析数字和日期的标签,有formatNumber,formatDate,parseNumber和parseDate;
formatNumber标签
- 用于格式化
数字
,百分比
,货币
,该标签用指定的格式或精度来格式化数字; - 常用属性有:
- value:要格式化的数值;
- type:要格式化的类型,number表示数值型(默认),percent表示百分比类型,currency表示货币类型;
- var:限域变量名,用来接收格式化后的结果;
- scope:var属性的范围;
- 若使用了var属性,标签不会输出结果,需要通过EL表达式获取结果;
- 新建
JSTL05.jsp
文件,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
Title
${num}
- 运行结果如下所示:
forrmatDate标签
- 用于格式化不同形式的日期时间,将Date类型数据转成指定格式的字符串类型;
- 常用属性:
- value:要格式化的日期;
- type:格式化类型,date 日期型(年月日),time 时间型(时分秒),both 日期时间型;
- dateStyle:日期格式;
- timeStyle:日期时间;
- pattern:自定义模式;
- timeZone:时区;
- 新建
JSTL06.jsp
文件,内容如下:
<%@ page import="java.util.Date" %><%--
Created by IntelliJ IDEA.
User: ljj
Date: 2021/12/12
Time: 下午3:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
Title
<%
request.setAttribute("myDate",new Date());
%>
${myDate}
- 运行结果如下:
parseNumber与parseDate标签
- parseNumber标签将指定格式的字符串转成数值型;
- parseDate标签将指定格式的字符串转成Date类型;
- 代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
Title