一、基本介绍
1.前言
- 目前主流的技术是 前后端分离**(比如:Spring Boot + Vue/React)**
- JSP技术使用在逐渐减少,但使用少和没有使用是两个意思,一些老项目和中小公司还在使用JSP**,工作期间,你很有可能遇到****JSP**
- **JSP使用在减少(但是现阶段还是有必要学一下,让我们的技术栈更加全面),我们最佳技术策略 :**JSP (能基本使用,能看懂,能维护相关项目,不用深入)
2 为什么需要****JSP
程序员在开发过程中,发现servlet做界面非常不方便
3 JSP****基本介绍
- JSP 全称是 Java Server Pages ,Java 的服务器页面
- JSP 这门技术的最大的特点在于,写 JSP 就像在写 HTML
- 相比 html 而言,html 只能为用户提供静态数据,而 JSP 技术允许在页面中嵌套 java 代码,为用户提供动态数据
- 相比 Servlet 而言,Servlet 很难对数据进行排版,而jsp 除了可以用 java 代码产 生动态数据的同时,也很容易对数据进行排版
- jsp 技术基于 Servlet, 你可以理解成 JSP 就是对 Servlet 的包装
- 会使用 JSP 的程序员, 再使用 thymeleaf 是非常容易的事情, 几乎是无缝接轨
4 JSP****快速入门
4.1 应用实例
创建hspedu_jsp WEB项目,并引入****jar
创建****D:\idea_java_projects\hspedu_jsp\web\sum.jsp
java
<%--
Created by IntelliJ IDEA.
User: 29942
Date: 2024/3/16
Time: 11:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP的简单求和计算器</title>
</head>
<body>
<h1>hsp的简单计算器</h1>
<%
//在jsp文件的这个标签中,就代表识别为java程序
int i=10;
int j=30;
int res=i+j;
out.print(i+" + "+j+" = "+res);
//在jsp中,内置了对象,可以直接使用,比如out
%>
</body>
</html>
4.2 注意事项和细节
- jsp页面不能像HTML页面,直接用浏览器运行。只能通过浏览器访问Tomcat来访问jsp****页面
- 如何设置jsp模板
5 JSP****运行原理
- **jsp页面本质是一个Servlet程序,其性能是和java关联的,**只是长得丑
- 第1次访问jsp页面的时候。Tomcat服务器会把jsp页面解析成为一个java源文件。并 且 对 它 进 行 编 译 成 为.class字 节 码 程 序 。 看 下Cal.jsp对 应 的cal_jsp.java和cal_jsp.class****文件
二、JSP基本使用
1 page指令(常用的)
-
language表示jsp翻译后是什么语言文件,只支持java
-
**contentType表示jsp返回的数据类型,对应源码中response.setContentType()**参数值
-
pageEncoding属性 表示当前jsp****页面文件本身的字符集
-
import属性 跟java****源代码中一样。用于导包,导类
2 JSP****三种常用脚本
2.1 声明脚本基本语法****statement_jsp
- 声明脚本的格式是:<%!声明java代码**%>**
- 作用:定义jsp的需要属性、方法、静态代码块和内部类等
java
<%--
User: Linran
Date: 2024/3/16
Time: 11:54
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP声明脚本</title>
</head>
<body>
<h1>jsp声明脚本</h1>
<%!
//这里我们可以声明该jsp需要使用的属性,方法,静态代码块,内部类
//也就是给statement.jsp对应的statement_jsp 类定义
//1.属性
private String name="jack";
private int age;
private static String company;
//2 方法
public String getName(){
return name;
}
//静态代码块
static {
company="字节跳动";
}
%>
</body>
</html>
2.2 表达式脚本基本语法
- 表达式脚本的格式是:****<%=表达式%>
- 表达式脚本的作用是:在jsp页面上输出数据
- 表达式脚本中的表达式不能以分号结束。
java
<%--
User: Linran
Date: 2024/3/16
Time: 15:10
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>表达式脚本</title>
</head>
<body>
<%
String name="林然";
%>
用户名:<%=name%>
</body>
</html>
2.3 代码脚本基本语法
-
代码脚本的语法是:<%java代码%>
-
代码脚本的作用是:可以在jsp页面中,编写我们需要的功能(使用java)
-
可以由多个代码脚本块组合完成一个完整的java语句。
-
代码脚本还可以和表达式脚本一起组合使用,在jsp页面上输出数据
java
package com.hspeud.entity;
public class Monster {
private Integer id;
private String name;
private String skill;
public Monster(Integer id, String name, String skill) {
this.id = id;
this.name = name;
this.skill = skill;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
java
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.hspeud.entity.Monster" %><%--
User: Linran
Date: 2024/3/16
Time: 15:21
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>演示代码脚本</title>
</head>
<body>
<h1>演示代码脚本</h1>
<%
//先创建ArrayList,添加两个monster
ArrayList<Monster> monsters = new ArrayList<>();
monsters.add(new Monster(1,"牛魔王","芭蕉扇"));
monsters.add(new Monster(2,"蜘蛛精","吐口水"));
%>
<table border="1px" width="300px" bgcolor="#f0f8ff">
<tr>
<td>id</td>
<td>名字</td>
<td>技能</td>
</tr>
<%
for (int i = 0; i <monsters.size() ; i++) {
//先取出Monster对象
Monster monster =monsters.get(i);
%>
<tr>
<td><%=monster.getId()%></td>
<td><%=monster.getName()%></td>
<td><%=monster.getSkill()%></td>
</tr>
<%
}
%>
</table>
</body>
</html>
3 JSP****注释
4 JSP****内置对象
4.1 基本介绍
- JSP内置对象(已经创建好的对象,直接使用inbuild),是指Tomcat在翻译jsp页面成为Servlet****后,内部提供的九大对象,叫内置对象
- 内置对象,可以直接使用,不需要手动定义
- JSP****九大内置对象:
- out 向客户端输出数据,out.println("");
- response****响应对象
- request客户端的http 请求 ;
- session 会话对象 ;
- application对应ServletContext
- **pageContext jsp页面的上下文,是一个域对象,可以setAttribue(),**作用范围只是本页面
- exception异常对象, getMessage()
- page代表jsp****这个实例本身
- config对应ServletConfig
5 JSP****域对象
5.1 JSP****四大域对象介绍
. pageContext (域对象,存放的数据只能在当前页面使用)
. request (域对象,存放的数据在一次request请求有效)
. session(域对象,存放的数据在一次会话有效),
. application(域对象,存放的数据在整个web应用运行期间有效,范围更大),
5.2 小结
- 域对象是可以像Map一样存取数据的对象。四个域对象功能一样。不同的是它们对数****据的存储范围
- 从存储范围**(作用域范围看) pageContext < request < session < application**
6 JSP****请求转发标签
7 课后作业
使用jsp完成一个简单的计算器
思路
代码
calUI.jsp
html
<%--
User: Linran
Date: 2024/3/27
Time: 13:32
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP计算器</title>
<%-- 使用js+正则表达式完成数据校验--%>
<script type="text/javascript">
function check() {
// alert("check被调用")
var num1 = document.getElementById("num1").value;
var num2 = document.getElementById("num2").value;
//验证正则表达式
var reg=/^[-]?([1-9]\d*|0)$/;
if(!reg.test(num1)){
//如果不满足验证条件
alert("num1不是一个整数");
return false;
}
if(!reg.test(num2)){
//如果不满足验证条件
alert("num2不是一个整数");
return false;
}
return true;
}
</script>
</head>
<body>
<h1>JSP计算器</h1>
<form action="<%=request.getContextPath()%>/calServlet" method="post" onsubmit="return check()">
num1:<input type="text" name="num1" id="num1"><br>
num2:<input type="text" name="num2" id="num2"><br>
<input type="submit" value="提交计算">
运算符号:
<select name="oper">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
</form>
</body>
</html>
calServlet
java
package com.hspeud.servlet;
import com.hspeud.utils.WebUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CalServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("CalServlet被调用");
//是servlet
//接收数据
String num1 = request.getParameter("num1");
String num2 = request.getParameter("num2");
//进行转换
int i = WebUtils.parseInt(num1, 0);
int j = WebUtils.parseInt(num2, 0);
String oper = request.getParameter("oper");
double res=0;
//完成计算
if("+".equals(oper)){
res=i+j;
}else if("-".equals(oper)){
res=i-j;
}else if("*".equals(oper)){
res=i*j;
}else if("/".equals(oper)){
res=i*1.0/j;
}else {
System.out.println("oper不正确");
}
//保存到域对象[request session servletContext
//因为一个请求一次计算,所以建议将结果保存到页面中
//把结果组织到一个字符串中,方面在下一个页面显示
String formatRes = String.format("%s %s %s = %s", num1, oper, num2, res);
request.setAttribute("res",formatRes);
// request.setAttribute("num1",num1);
// request.setAttribute("num2",num2);
// request.setAttribute("res",res);
// System.out.println("formatRes: "+formatRes);
//转发到显示页面
request.getRequestDispatcher("/cal/calRes.jsp").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
utils
java
package com.hspeud.utils;
public class WebUtils {
public static int parseInt(String strNum,int defaultVal){
try {
return Integer.parseInt(strNum);
} catch (NumberFormatException e) {
System.out.println(strNum+"不能转换成整数");
}
return defaultVal;
}
}
calRes.jsp
html
<%--
User: Linran
Date: 2024/3/27
Time: 15:36
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>计算结果</title>
</head>
<body>
<h1>计算结果</h1>
<%= request.getAttribute("res")%><br>
<a href="<%=request.getContextPath()%>/cal/calUI.jsp">返回再计算一次</a>
</body>
</html>
三、EL
1.基本介绍
- EL****表达式全称:Expression Language,是表达式语言
- EL表达式主要是代替jsp页面的表达式脚本<%=request.getAttribute("xx")%>
- EL表达式输出数据的时,比jsp****的表达式脚本简洁
- EL表达式基本语法:${key1} **,**你可以理解就是一个语法糖
html
<%--
User: Linran
Date: 2024/3/27
Time: 20:04
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el表达式的快速入门</title>
</head>
<body>
<h1>el表达式快速入门</h1>
<%
request.setAttribute("name","林然学java");
%>
<h1>
jsp表达式脚本
</h1>
名字=<%=request.getAttribute("name")%><br>
<h1>el表达式</h1>
名字=${name}
</body>
</html>
- EL表达式在输出null时,输出的是""
- **jsp表达式脚本输出null的时,输出的是"null"**字符串
2 EL****常用输出形式
EL表达式常用输出Bean【javabean】的普通属性、 数组属性、List集合属性和map****集合属性
html
<%@ page import="com.hspeud.entity.Book" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %><%--
User: Linran
Date: 2024/3/27
Time: 20:18
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el 表达式输出数据演示</title>
</head>
<body>
<h1>el 表达式输出数据演示</h1>
<%
//创建Book对象,放入相关的属性
// private String name;
// private String[] writer;//作者
// private List<String> reader;//读者
// private Map<String, Object> topics;//话题
Book book=new Book();
book.setName("昆虫总动员");
book.setWriter(new String[]{"jack,tom"});
ArrayList<String> readers = new ArrayList<>();
readers.add("林然1");
readers.add("林然2");
book.setReader(readers);
HashMap<String, String> topics = new HashMap<>();
topics.put("topic1","很好看");
topics.put("topic2","不错的电影");
book.setTopics(topics);
//把book放入request对象
request.setAttribute("bookId",book);
%>
book对象:${bookId}<br>
book.name:${bookId.name}<br>
book.writer:${bookId.writer}<br>
book.writer[0]:${bookId.writer[0]}<br>
book.readers: ${bookId.reader}<br>
book.readers[1]:${bookId.reader.get(1)}<br>
book.topics:${bookId.topics}<br>
book.topics(topic1):${bookId.topics.get("topic1")}
</body>
</html>
java
package com.hspeud.entity;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class Book {
private String name;
private String[] writer;//作者
private List<String> reader;//读者
private Map<String, String> topics;//话题
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getWriter() {
return writer;
}
public void setWriter(String[] writer) {
this.writer = writer;
}
public List<String> getReader() {
return reader;
}
public void setReader(List<String> reader) {
this.reader = reader;
}
public Map<String, String> getTopics() {
return topics;
}
public void setTopics(Map<String, String> topics) {
this.topics = topics;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", writer=" + Arrays.toString(writer) +
", reader=" + reader +
", topics=" + topics +
'}';
}
}
3 EL****运算操作
基本语法语法:****${运算表达式}
3.1 关系运算
3.2 逻辑运算
3.3 算数运算
4 EL的empty****运算
- empty运算可以判断一个数据是否为空,如果为空,返回true**,否则返回****false**
- 以下几种情况为空
5 EL****的三元运算
6 EL的11****个隐含对象
EL的11****个隐含对象,可以直接使用
6.1 EL****获取四个特定域中的属性
6.2 应用实例
html
<%--
User: Linran
Date: 2024/3/27
Time: 22:28
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL 获取四个特定域中的属性</title>
</head>
<body>
<h1>EL 获取四个特定域中的属性</h1>
<%
pageContext.setAttribute("key1", "pageContext_key1 的值");
pageContext.setAttribute("key2", "pageContext_key2 的值");
request.setAttribute("key1", "request_key1 的值");
session.setAttribute("key1", "session_key1 的值");
application.setAttribute("key1", "application_key1 的值");
%>
request域中的k1= ${requestScope.key1}<br>
application 的 key1: ${applicationScope.key1 }<br/>
pageContext 的 key1: ${pageScope.key1 }<br/>
session 的 key1: ${sessionScope.key1 }<br/>
request 的 key1: ${requestScope.key1 }<br/>
</body>
</html>
6.3 pageContext****对象的使用
6.3.1 pageContext****对象介绍
6.3.2 应用实例
html
<%--
User: Linran
Date: 2024/3/27
Time: 22:40
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>pageContext 对象的使用</title>
</head>
<body>
<h1>pageContext 对象的使用</h1>
<%--//通过 request 对象来获取和 HTTP 协议相关的数据
request.getScheme() 它可以获取请求的协议
request.getServerName() 获取请求的服务器 ip 或域名
request.getServerPort() 获取请求的服务器端口号
getContextPath() 获取当前工程路径
request.getMethod() 获取请求的方式(GET 或 POST)
request.getRemoteHost() 获取客户端的 ip 地址
session.getId() 获取会话的唯一标识--%>
<hr/>
协议: ${ pageContext.request.scheme }<br>
服务器 ip:${ pageContext.request.serverName }<br>
服务器端口:${ pageContext.request.serverPort }<br>
工程路径:${ pageContext.request.contextPath }<br>
请求方法:${ pageContext.request.method }<br>
客户端 ip 地址:${ pageContext.request.remoteHost }<br>
会话 id :${ pageContext.session.id }<br>
<h1>使用 jsp 表达式脚本获取如上信息</h1>
ip 地址: <%=request.getRemoteHost() %> <br>
<h1>使用 el 表达式形式获取信息</h1>
<%
pageContext.setAttribute("req", request);
%>
<%-- 简化--%>
ip 地址: ${req.remoteHost} <br>
获取请求方法: ${req.method} <br>
</body>
</html>
四、JSTL
1.基本介绍
-
JSTL标签库 是指JSP Standard Tag Library JSP****标准标签库
-
EL表达式是为了替换jsp中的表达式脚本,JSTL是为了替换代码脚本。这样jsp页面变得更佳简洁
-
JSTL****由五个标签库组成
- 使用JSTL,需要导入相关的jar包
2 快速入门
taglib****引入标签,要放在行首
导入jstl jar包后,要重新发布web工程,否则不识别****jstl
html
<%--
User: Linran
Date: 2024/3/28
Time: 8:24
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSTL快速入门</title>
</head>
<body>
<%--
c:if 类似
if(10>2){
输出
}
--%>
<h1>jstl快速入门</h1>
<c:if test="${10>2}">
<h1>10>2 成立</h1>
</c:if>
</body>
</html>
3 core****核心库
3.1 <c:set />
<c:set scope="request" var="username" value="java**~"/>**
3.2 <c:if />
介绍**: <c:if test="${ 10 > 2 }">hello</c:if>**
**3.3 <c:choose> <c:when> <c:otherwise>**标签
多路判断
html
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
User: Linran
Date: 2024/3/28
Time: 9:07
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>c:choose的使用</title>
</head>
<body>
<%
request.setAttribute("score",90);
%>
<%-- 如果${requestScope.score} 那么就明确的指定从request域对象取出数据
如果${score},那么就按照从小到大的域范围去获取
--%>
<c:choose>
<c:when test="${requestScope.score>=80}">
<h1>成绩优秀</h1>
</c:when>
<c:when test="${requestScope.score>=60}">
<h1>成绩及格</h1>
</c:when>
<c:otherwise>
<h1>没有及格,下次努力</h1>
</c:otherwise>
</c:choose>
</body>
</html>
3.4 **<c:forEach />**标签
c:forEach标签 用来遍历输出,主要有4****种形式
html
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="com.hspeud.entity.Monster" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
User: Linran
Date: 2024/3/28
Time: 9:56
Version: 1.0
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>c:forEach 标签</title>
</head>
<body>
<h1>c:forEach 标签</h1>
<hr/>
<h1>第 1 种遍历方式从 i 到 j</h1>
<ul>
<%-- 1.遍历 1 到 5,
2. 输出 begin 属性设置开始的索引 end 属性设置结束的索引
3. var 属性表示循环的变量(也是当前正在遍历到的数据)
4. 等价 for (int i = 1; i <= 5; i++) {}
--%>
<c:forEach begin="1" end="5" var="i" step="1">
<li>排名=${i}</li>
</c:forEach>
</ul>
<hr/>
<h1>第 2 种遍历方式:遍历数组</h1>
<%
request.setAttribute("sports", new String[]{"打篮球", "乒乓球"});
%>
<%--<c:forEach items="${ requestScope.sports }" var="item"/>
1. items 遍历的集合
2. var 遍历到的数据
3. 等价 for (Object item: arr) {}
--%>
<c:forEach items="${requestScope.sports}" var="sport">
运动名称=${sport}<br>
</c:forEach>
<hr/>
<h1>第 3 种遍历方式:遍历 Map</h1>
<%
Map<String, Object> map = new HashMap<>();
map.put("key1", "北京");
map.put("key2", "上海");
map.put("key3", "天津");
request.setAttribute("map", map);
%>
<%--1. items 遍历的 map 集合
2. var 遍历到的数据
3. entry.key 取出 key
4. entry.value 取出值
--%>
<hr/>
<c:forEach items="${requestScope.map}" var="city">
城市信息:${city.key}---${city.value}<br>
</c:forEach>
<h1>第 4 种遍历方式:遍历 List</h1>
<%
List<Monster> monsters = new ArrayList<>();
monsters.add(new Monster(100, "小妖怪", "巡山的"));
monsters.add(new Monster(200, "大妖怪", "做饭的"));
monsters.add(new Monster(300, "老妖怪", "打扫位置的"));
request.setAttribute("monsters", monsters);
%>
<%--
items 表示遍历的集合
var 表示遍历到的数据
begin 表示遍历的开始索引值 ,从 0 开始计算
end 表示结束的索引值
step 属性表示遍历的步长值
varStatus 属性表示当前遍历到的数据的状态,可以得到 step,begin,end 等属性值
--%>
<c:forEach items="${requestScope.monsters}" var="monster">
妖怪的信息:${monster.id}---${monster.name}--${monster.skill}<br>
</c:forEach>
</body>
</html>