欢迎来到我的主页:【一只认真写代码的程序猿】
本篇文章收录于专栏【JSP相关】
如果这篇文章对你有帮助,希望点赞收藏加关注啦~
本文所有内容相关代码都可在以下仓库中找到:
https://github.com/Echo-Nie/JSPLearn
1 Idea新建项目
新建项目:
导入Web模块:
配置Artifact:
配置Tomcat:
新建jsp文件:
页面报错:
后缀加上你的项目名字:
发现url很奇怪,直接自定义:
接着会在对应目录下生成class和java文件(用Listary搜JSPTestDay1):
2 基础语法
2.1 注释
<span style="background-color:#f8f8f8"><span style="color:#333333">//单行注释
/*多行注释*/
<!-- HTML风格注释 -->
<%-- JSP注释 --%>
</span></span>
<%--
Created by IntelliJ IDEA.
User: Echo-Nie
Date: 2024/12/9
Time: 20:17
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>
<pre>
JSP有两种的注释:显示注释和隐式注释
1. 显示注释:能够在客户端中查看的注释: <!-- HTML 风格注释 -->
<!--HTML风格注释-->
2. 隐式注释:不能在客户端看到的注释:
2.1 <%--JSP自己的注释--%><%-- JSP自己的注释 --%>
2.2 JAVA注释: //单行与多行
<%-- JAVA脚本段 --%>
<%
//这是单行注释
/*这是多行注释*/
%>
</pre>
</body>
</html>

2.2 Scrptlet
在JSP中很重要,Scriplet(脚本小程序),所有嵌入在HTML代码中的Java程序。
在JSP中有三种Scriptlet带阿米,必修用Scriptlet标出来。
<span style="background-color:#f8f8f8"><span style="color:#333333">第一种:<% %>:Java脚本段,可以定义局部变量,编写语句。
第二种:<%! %>:可以定义全局变量,方法,类。
第三种:<%= %>:表达式,数据一个变量或者具体内容。</span></span>
<%--
Created by IntelliJ IDEA.
User: Echo-Nie
Date: 2024/12/9
Time: 20:17
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Scriptlet</title>
</head>
<body>
<%--第一种:<% %>:Java脚本段,可以定义局部变量,编写语句。--%>
<%--生成的代码在servlet的service方法体中--%>
<%
String s = "hello";
// 将s输出到控制台
// System.out.println(s);
out.print(s);//将s输出到浏览器
out.write("---");
out.print("输出全局变量:num="+num);
out.write("---");
%>
<%--第二种:<%! %>:可以定义全局变量,方法,类。--%>
<%--生成的代码在servlet的类体中--%>
<%!
//声明全局变量
int num = 0;
//没有sout
%>
<%-- 第三种:<%= %>:表达式,数据一个变量或者具体内容。 --%>
<%-- 生成的代码在servlet的service方法体中,相当于out.print() --%>
<%= s %>
</body>
</html>
2.3 JSP的指令标签
使用包含操作,将一些重复的代码包含进来使用,从正常的页面组成来看,有可能分为几个区域,其中有一些区域可能一直不需要改变,改变的就其中一个具体的内容区域。
方法1:每个JSP页面(HTML)都包含工具栏、头部信息、尾部信息、具体内容。
方法2:将工具栏、头部、尾部信息都分成各个独立文件,使用的时候直接导进去。
我们发现第一种方法会有代码重复,修改也不方便,所以在JSP中实现包含操作我们一般是静态包含和动态包含。静态包含使用include就行,动态包含需要使用include动作标签。
好比一个网站,有head和foot,中间是Body,将head和foot封装起来这种感觉。
2.3.1 静态包含
<%@ include file ="url" %> <!--相对路径 -->
静态包含就是将内容进行直接替换,好比程序中定义变量一样,在servlet引擎转译的时候,把这个文件包含进去了(将两个文件的源代码整合到一起,全部放到jspService方法中),所以只生成了一个servlet,所以两个页面不能有同名变量,耦合性高但是不够灵活。
特点:
-
将内容进行直接替换
-
静态包含只会生成一个源码文件,最终内容均在jspService方法中
-
因为是一个源码文件,所以不能出现同名变量
-
运行效率高一点,但是耦合高不灵活
<%--
Created by IntelliJ IDEA.
User: Echo-Nie
Date: 2024/12/9
Time: 21:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Header头部</title>
</head>
<body>
---------<br>
这是头部<br>
---------<br>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: Echo-Nie
Date: 2024/12/9
Time: 21:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>include</title>
<%--
include静态包含:<%@include file="header.jsp" %>
特点:
1、将内容进行直接替换
2、静态包含只会生成一个源码文件,最终内容均在jspService方法中
3、因为是一个源码文件,所以不能出现同名变量
4、运行效率高一点,但是耦合高不灵活
--%>
</head>
<body>
<%@include file="header.jsp" %>
<h2>主体部分</h2>
<%
int num = 10;
out.print(num);
%>
<%@include file="footer.jsp" %>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: Echo-Nie
Date: 2024/12/9
Time: 21:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Footer底部</title>
</head>
<body>
<%
int num = 11;
%>
-------------<br>
这是尾部<br>
-------------<br>
</body>
</html>
2.3.2 动态包含
动态包含在代码的编译阶段,包含和被包含是两个独立的部分,只有当运行时,才会动态包含进来,有点像java的方法调用。所以会有多个源码文件。
<jsp:include page="include.jsp"></jsp:include>
PS:动态包含中间,也就是include标签之间不要加任何内容(空格也不能加),除非你确定要使用参数。如果有内容它就认为你有参数,就会去找你带参数的标签。
特点:
-
相当于方法的调用
-
会生成多个源码文件
-
可以定义同名变量
-
效率高耦合度低
2.3.3 动态包含带参数
<span style="background-color:#f8f8f8"><span style="color:#333333"><jsp:param name="str" value="string"/>
<jsp:param name="str" value="<%=str%>"/></span></span>
name属性不支持表达式,而value支持表达式。
<span style="background-color:#f8f8f8"><span style="color:#333333"><%--
User: Echo-Nie
Date: 2024/12/9
Time: 21:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>include动态包含</title>
</head>
<%--
使用动态包含:
<jsp:include page="url">
<jsp:param name="参数名" value="参数值"/>
</jsp:include>
注意:name不支持表达式;value支持表达式
获取参数:
request.getParameter(name);通过指定参数获取变量名字
--%>
<jsp:include page="header.jsp"></jsp:include>
<h2>主体内容</h2>
<%
int a = 10;
%>
<jsp:include page="footer.jsp"></jsp:include>
<%--第一次footer的时候,没有传参,所以取到的是null--%>
<%--动态包含传参--%>
<%
String str = "hello";
%>
<%--第二次footer的时候传参,所以取到的是admin和hello--%>
<jsp:include page="footer.jsp">
<jsp:param name="uname" value="admin"/>
<jsp:param name="msg" value="<%=str%>"/>
</jsp:include>
<body>
</body>
</html></span></span>
2.4 JSP的四大域对象
2.4.1 四种属性范围
在JSP中提供了四种属性的保存范围,就是一个设置的对象,可以在多少个页面中保存并使用。
1.page范围
pageContext:只在一个页面中保存属性,跳转之后无效。
2.request范围:
request:只在一次请求中保存,服务器跳转后依然有效。
3.session范围
session:在一次会话范围中,无论何种跳转都可以使用。
4.application范围:
application:在整个服务器上保存。
method | type | description |
---|---|---|
public void setAttributes(String name,Object o) | 普通 | 设置属性的名称及内容 |
public Object getAttribute(String name) | 普通 | 根据属性名称取属性 |
public void removeAttribute(String name) | 普通 | 删除指定操作 |
2.4.2 属性范围特点
1.page
本页面取得服务器跳转<jsp :forward>后无效
2.request
服务器跳转有效,客户端跳转无效。
如果是客户端跳转,则相当于发生了两次请求,那么第一次的请求将不存在了;如果希望不管是客户端还是服务器跳转,都能保存的话需要扩大范围。
3.session
无论客户端还是服务器都可以取得,但是如果重新开新的浏览器,则无法取得之前设置的session,因为每一个session只保存在当前浏览器中,并在相关页面取得。
如果想让属性设置一次之后,不管是否是新的浏览器都可以取得,用application
4.application
所有的application属性直接保存在服务器上,所有的用户(每一个session)都可以直接访问取得。
只要是通过application设置的属性,则所有的session都可以取得,表示公共的内容,但是如果此时服务器重启了,则无法取得了,因为关闭服务器后,所有的属性都消失了,所以需要重新设置。
使用:在合理的范围内尽可能小。
3 login简单页面
3.1 loginTest编写
<span style="background-color:#f8f8f8"><span style="color:#333333"><%--
User: Echo-Nie
Date: 2024/12/10
Time: 9:39
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login页面-简易版</title>
</head>
<body>
<form action="loginServlet" method="post">
姓名:<input type="text" name="uname"></br>
密码:<input type="text" name="upwd"></br>
<button>登录</button>
<%--获取后台设置在作用域中的数据并且显示--%>
<span style="color: dodgerblue;font-size: 12px"><%=request.getAttribute("msg")%></span>
</form>
</body>
</html></span></span>
3.2 LoginServlet编写
<span style="background-color:#f8f8f8"><span style="color:#333333">package com.ynu.controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @ClassName LoginService
* @Description
* @Author Echo-Nie
* @Date 2024/12/10 9:46
* @Version V1.0
*/
@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", "用户姓名不能为空");
//请求转发跳转到loginTest.jsp
request.getRequestDispatcher("07-loginTest.jsp").forward(request, response);
return;
} else if (upwd == null || "".equals(upwd.trim())) {
//提示用户信息
request.setAttribute("msg", "密码不能为空");
//请求转发跳转到login.jsp
request.getRequestDispatcher("07-loginTest.jsp").forward(request, response);
return;
}
//判断账号密码是否正确
if(!"nyx".equals(uname)){
//提示用户名错误
request.setAttribute("msg","用户名错误,登录失败");
request.getRequestDispatcher("07-loginTest.jsp").forward(request, response);
return;
}
//判断密码
if(!"nyx".equals(upwd)){
request.setAttribute("msg","密码错误,登录失败");
request.getRequestDispatcher("07-loginTest.jsp").forward(request, response);
return;
}
//登录成功
//设置登录时的信息到session作用域
request.getSession().setAttribute("uname",uname);
//跳转到登录页面
response.sendRedirect("07-index.jsp");
}
}</span></span>
4 EL表达式
4.1 EL基本语法
首先发现上面提示信息那一块是null,影响美观,能不能换成空串?引出EL表达式。
EL(Expression Language)是为了使JSP 写起来更加简单。表达式语言的灵感来自于ECMAScript 和XPath 表达式语言,它提供了在JSP 中简化表达式的方法,让Jsp 的代码更加简化。
语法结构:${expression}
EL表达式操作的一般是域中的数据,操作不了局部变量。
域对象的概念在JSP 中一共有四个:pageContext、request、session、application;范围依次是:
本页面
一次请求
一次会话
整个应用程序。
当需要指定从某个特定的域对象中查找数据时可以使用四个域对象对应的空间对象,分是:pageScope,requestScope,sessionScope,applicationScope。
EL 默认的查找方式为从小到大查找,找到即可。当域对象全找完了还未找到则返回空字符串""。
<span style="background-color:#f8f8f8"><span style="color:#333333"><%--
User: Echo-Nie
Date: 2024/12/10
Time: 16:11
To change this template use File | Settings | File Templates.
Description:
EL表达式
作用:简化JSP代码
格式:
${域对象的名称}
操作对象:
EL表达式一般操作的是域对象,不能操作局部变量。
操作范围:
page范围在当前页面
request范围在一次请求
session范围在一次会话
application范围在整个应用程序
可通过pageScope、
PS:如果EL表达式获取的域对象值为空,默认是空串;
EL表达式默认从小到大的范围去找,找到即可,如果四个范围都没找到,显示空字符串。
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式</title>
</head>
<body>
<%--设置数据--%>
<%
pageContext.setAttribute("uname", "zs");
request.setAttribute("uname", "ls");
session.setAttribute("uname", "ww");
application.setAttribute("uname", "zl");
// 局部变量
String str = "hello";
%>
<%--获取数据--%>
获取局部变量:${str} </br>
获取域对象:${uname}<br>
<%--
输出如下:
获取局部变量:
获取域对象:zs
--%>
<%--获取指定域的数据--%>
<br>获取指定域的数据:<br>
page域数据:${pageScope.uname}<br>
request域数据:${requestScope.uname}<br>
session域数据:${sessionScope.uname}<br>
application域数据:${applicationScope.uname}<br>
</body>
</html></span></span>
4.2 EL获取数据
设置域对象中的数据
<span style="background-color:#f8f8f8"><span style="color:#333333"><%
/*page*/
// 本页面取得服务器跳转<jsp :forward>后无效
pageContext.setAttribute("uname","zs");
/*request*/
// 服务器跳转有效,客户端跳转无效。
request.setAttribute("uname","ls");
/*session*/
// 如果重新开新的浏览器,则无法取得之前设置的session
session.setAttribute("uname","ww");
/*application*/
// 服务器重启了,则无法取得了
application.setAttribute("uname","lmz");
%></span></span>
获取域对象的值
${uname} <!-- 输出结果为:zs -->
获取指定域对象的值
<%--获取指定域的数据--%>
<br>获取指定域的数据:<br>
page域数据:${pageScope.uname}<br>
request域数据:${requestScope.uname}<br>
session域数据:${sessionScope.uname}<br>
application域数据:${applicationScope.uname}<br>
获取List
<span style="background-color:#f8f8f8"><span style="color:#333333"><%
//List
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list", list);
%>
<h4>获取List</h4>
获取list的size:${list.size()};<br>
获取list的指定下标值list[1]:${list[1]}<br></span></span>
获取Map
<span style="background-color:#f8f8f8"><span style="color:#333333"><%
//Map
Map map = new HashMap<>();
map.put("aaa", "111");
map.put("bbb", 111);
map.put("ccc", 33);
request.setAttribute("map", map);
%>
<h4>获取Map</h4>
获取map指定的key的value:${map.aaa} 或者 ${map["bbb"]};</span></span>
获取JAVABean
<span style="background-color:#f8f8f8"><span style="color:#333333"><%
//JavaBean
User user = new User(1, "nyx", "123");
request.setAttribute("user", user);
%>
<h4>获取JAVABean</h4>
${user}<br>
获取JAVABean中属性:uname=${user.uname}或者getUname=${user.getUname()}
<%--
输出如下:
com.ynu.po.User@62adb472
获取JAVABean中属性:uname=nyx或者getUname=nyx
--%></span></span>
4.3 Empty与一些运算
<span style="background-color:#f8f8f8"><span style="color:#333333"><%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="com.ynu.po.User" %><%--
User: Echo-Nie
Date: 2024/12/11
Time: 23:35
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>10-empty与EL运算.jsp</title>
<%--
empty
判断域对象是否为空,为空返回true,否则为false
${empty 限域变量名}
判断对象是否不为空
${!empty 限域变量名}
对于字符串:
不存在返回true
有值返回false
空串true
null也是true
对于List:
null返回true
没有长度size的也返回true
对于Map:
null返回true
空Map对象返回true
对于JAVABean:
null返回true
空对象返回false
--%>
</head>
<body>
<%
//字符串
request.setAttribute("str1", "abc");
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 map = new HashMap<>();
Map map1 = null;
Map map2 = new HashMap<>();
map2.put(1, 2);
request.setAttribute("map", map);
request.setAttribute("map1", map1);
request.setAttribute("map2", map2);
//JAVABean
User user = null;
User user1 = new User();
User user2 = new User(1, "nyx", "123");
request.setAttribute("user", user);
request.setAttribute("user1", user1);
request.setAttribute("user2", user2);
%>
<h4>判断字符串是否不存在</h4>
${empty str}返回true<br>
${empty str1}返回false<br>
${empty str2}返回true<br>
${empty str3}返回true<br>
<br>
<h4>判断List是否为空</h4>
${empty list1}返回true<br>
${empty list2}返回true<br>
${empty list3}返回false<br>
<h4>判断Map是否为空</h4>
${empty map}返回true<br>
${empty map1}返回true<br>
${empty map2}返回false<br>
<h4>判断JAVABean</h4>
${empty user}返回true<br>
${empty user1}返回false<br>
${empty user2}返回false<br>
-----------------------比较两个值是否相等,==或eq----------------
<%
request.setAttribute("a", 10);
request.setAttribute("b", 2);
request.setAttribute("c", "aa");
request.setAttribute("d", "bb");
%>
${a==b}
${c==d}
${c eq d}
${a ==5}
${c =="aa"}
<br>
</body>
</html></span></span>