温馨提示: 由于CSDN没有jsp代码块,这里jsp代码我一致使用的java代码块编写。所以大家再查看之余要注意一下jsp代码中的注释!
一、JSP简介
1.1 什么是JSP?
JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。
1.2 JSP的特点
JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。可以通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。
JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。
JSP标签有多种功能,比如访问数据库、记录用户选择信息、访问JavaBeans组件等,还可以在不同的网页中传递控制信息和共享信息。
1.3 JSP为什么也是Servlet
当jsp页面显示后,会在在tomcat中有一个目录叫work,它里面就存储了jsp页面生成的源代码。jsp文件会转义成对应的java文件
比如:demo01.jsp转义成demo01_jsp.java,类demo01_jsp会继承于HttpJspPage,HttpJspPage又继承了HttpServlet。也就可以说demo01.jsp就是Servlet(所有的jsp都是Servlet)
1.4 tomact服务器中的资源分析
tomact服务器资源中可以分为静态技术资源和动态技术资源
1.4.1 tomact服务器中的静态资源分析
- 静态资源分为:
- HTML:静态页面
- CSS:渲染美化静态HTML页面的样式
- Java Script:动态修改HTML页面和CSS样式
1.4.2 tomact服务器中的动态资源分析
- Servlet:运行在服务器上的Java小程序。适合编写Java代码,适合业务处理,写网页比较困难
- Servlet的三个用途:接受浏览器发送的数据、负责调用业务层、请求转发及重定向的使用
- JSP:适合编写动态内容,不适合写java代码,主要用于显示页面
1.5 为什么要使用JSP
- JSP性能好,可以在html页面中动态嵌入元素
- 服务器调用的是已经编译好的JSP文件
- JSP基于Java Servlet Api,有很多强大企业的支持
- JSP可以与处理业务逻辑的Servlet一起使用,该模式被Java Servlet模版引擎所支持
1.6 JSP的优点
与纯 Servlet 相比:JSP可以很方便的编写或者修改HTML网页而不用去面对大量的println语句
与JavaScript相比:虽然JavaScript可以在客户端动态生成HTML,但是很难与服务器交互,因此不能提供复杂的服务,比如访问数据库和图像处理等等
与静态HTML相比:静态HTML不包含动态信息
1.7 JSP的原理
- 当在浏览器上输入http://localhost/jspdemo/index.jsp
- 服务器tomcat得到请示,会通过JspServlet将后缀名是.jsp的请求处理
- 处理将index.jsp翻译成index_jsp.java文件
- 再将index_jsp.java文件编译成index_jsp.class文件
- jvm将.class加载运行
- 服务器生成响应,响应信息中就包含了jsp页面上的html代码
二、JSP的基本结构
2.1 JSP的结构
JSP页面中可以包含指令、Java语句、变量、方法或表达式、静态内容(HTML、CSS、Java Script)
- 脚本元素(Scripting Elements):声明、脚本段、表达式
- 注释指令(Comment Elements):HTML注释、Java注释、JSP隐式注释
- 指令元素(Directive Elements):page、include、taglib等
- 动作元素(Action Elements):jsp:include、jsp:forward、jsp:useBean等
2.2 JSP脚本元素
2.2.1 JSP脚本的作用
可以在页面上编写java代码,实现页面与Java代码数据的交互
2.2.2 JSP脚本的分类
声明脚本: <%! Java代码 %>
片段脚本: <% Java代码 %>
输出脚本: <%= 变量值 %>
2.2.2.1 声明脚本
声明脚本里的变量是全局变量,也就是在jsp对应java类中,生成一个成员变量
<%!
定义方法
%>
2.2.2.2 片段脚本
在jsp对应的java类的_jspService方法中,生成一个局部变量
<% int i=10; %>
2.2.2.3 输出脚本
向浏览器输出内容,相当于response.getWriter().write()
<%= 2+3 %>
2.3 JSP页面中的注释
2.3.1 JSP页面中的注释分类
JSP页面中可以包含以下几种注释种类:Java代码注释、HTML网页注释、JSP页面注释
2.3.2 Java代码注释
Java代码注释用来注释Java代码,会将注释内容生成到jsp对应的java文件中。也就是说注释内容在Java文件中可见。所以不安全 、比较耗费流量
//Java代码注释
2.3.3 HTML网页注释
HTML网页注释用来注释HTML代码,会将注释内容生成到jsp对应的java文件中。也就是说和HTML文件类似,在网页查看源代码中,注释可见。所以不安全 、比较耗费流量
<!-- HTML网页注释 -->
2.3.4 JSP页面注释
JSP页面注释用来注释HTML代码,不会将注释内容生成到jsp对应的java文件中。所以,安全、省流量、仅在JSP文件中可见
<%-- JSP页面注释 --%>
2.4 JSP指令
2.4.1 JSP中指令分类
JSP中的指令分为三种:page指令、taglib指令、include指令
2.4.2 JSP中的指令的作用
JSP指令用于指示jsp执行某些操作 、用于指示jsp表现特定行为或效果
2.4.3 page指令
page指令用于定义JSP页面的各种属性
属性 | 描述 |
---|---|
session | 是否会自动创建session对象;默认值为true |
buffer | JSP中有javax.servlet.jsp.JspWriter输出字符流。设置输出数据的缓存大小;默认8kb |
errorPage | 如果页面中有错误,跳转到指定的资源;errorPage=“项目资源路径” |
isErrorPage | 是否创建throwable对象;默认是false |
contentType | 等价于response.setContentType(“text/html”;charset=utf-8);告知浏览器应该以utf-8解码响应正文,以utf-8对响应正文进行编码 |
pageEncoding | Jsp文件自身的编码 |
isELIgnored | 是否支持EL表达式。 默认是false,支持表达式;true表示不支持表达式;例如:${1+1}; 为false时,输出结果为2;为true时按照原样输出 |
import | 与Java代码中无差别,等价于导包;例如:<%@ page import=“java.util.Date,java.util.List”%> 或者分开导入需要的包<%@ page import=“java.util.List”%> |
2.4.4 taglib指令
taglib指令用于在当前jsp页面中导入jstl标签库
例如:导入jstl标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2.4.5 include指令
include指令用于将外部引入到jsp文件中
2.4.5.1 include指令引入静态资源
例如:引入静态资源
<%@ include file="static.jsp"%>
2.4.5.2 include指令引入动态资源
例如:引入动态资源
<jsp:include page=“dynamic.jsp"></jsp:include>
2.5 JSP的九大内置对象
对象名 | 描述 | 类型 |
---|---|---|
request | 请求对象 | javax.servlet.http.HttpServletRequest |
response | 响应对象 | javax.servlet.http.HttpServletResponse |
session | Session会话对象 | javax.servlet.http.HttpSession(由session=“true”开关) |
application | Servlet上下文对象 | javax.servlet.ServletContext |
config | ServletConfig对象 | javax.servlet.ServletConfig |
exception | 异常对象 | java.lang.Throwable(由isErrorPage=“false”开关) |
out | JspWriter对象 | javax.servlet.jsp.JspWriter |
pageContext | 当前页面上下文对象 | javax.servlet.jsp.PageContext |
page | 当前页面对象 | java.lang.Object(当前页面对象,this为当前servlet实例) |
<%--
Created by IntelliJ IDEA.
User: Ziph
Date: 2020/4/27
Time: 12:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
<title>jsp九大内置对象的使用</title>
</head>
<body>
<%
/**
* Request对象
* 在地址栏中以GET请求的方式拼即可获取到request对象中的username参数
*/
String username = request.getParameter("username");
System.out.println(username);
/**
* Response对象
* 可以实现响应浏览器内容
*/
response.getWriter().println("username : " + username);
/**
* Session对象
* 在Session域中存储username,可以实现在另一个jsp中取出Session域中的username参数
*/
request.getSession().setAttribute("username", "ziph");
/**
* application对象(ServletContext)
* 在application对象中存储一个username参数,可以实现在另一个jsp中取出application对象中的username参数
*/
application.setAttribute("username", "ziph");
/**
* 使用out对象在浏览器上输出内容
*/
out.write("<br>out : ziph");
/**
* config配置对象
* 可以获取初始化参数ServletName名称为jsp
*/
System.out.println("config : " + config.getServletName());
/**
* exception异常对象
* 可以获取异常对象(此时没有异常对象所以打印null)
*/
System.out.println("exception : " + exception);
/**
* page当前页面对象
* 打印了当前页面对象
*/
System.out.println(page.getClass());
/**
* pageContext页面上下文对象
*/
pageContext.setAttribute("pageContext", "ziph");
System.out.println(pageContext.getAttribute("pageContext"));
%>
</body>
</html>
test.jsp
<%
/**
* 可以取出另一个jspSession中域中的username参数值
*/
String username = (String) request.getSession().getAttribute("username");
System.out.println("Session : " + username);
/**
* 可以取出application对象中的username参数值
*/
String applicationAttribute = (String) application.getAttribute("username");
System.out.println("application : " + applicationAttribute);
%>
2.5.1 jsp的out和getWriter()方法的区别
- out是JspWriter类型;getWriter()是PrintWriter类型
- out输出到缓冲区中,没有写到response中;getWriter()直接写到response中
- out一般用在jsp中;getWriter()用在Servlet中
2.5.2 为什么jsp可以直接使用内置对象
在jsp对应的java文件中,已经提前声明好了这些内置对象,所以可以直接使用
2.5.3 怎样找到jsp页面的class文件
jsp页面的class文件一般都保存在tomact目录下的,路径为:\apache-tomcat-8.5.45\work ;是在work文件夹中
但是使用IDEA的小伙伴也知道,IDEA部署后的项目资源是保存在IDEA自动生成的镜像中的。所以我们要去找到镜像的位置。一般IDEA镜像位置会在电脑的C盘中放置,你可以在启动tomact 服务器的时候去找镜像的路径所在,找到镜像就好办了,就可以找到jsp页面的class文件了!
这是我电脑中IDEA自动生成项目资源镜像的位置:(大家可以在tomact启动的时候,去寻找类似的路径!)
C:\Users\Ziph\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Tomcat_8_5_45_webdemoplus\work\Catalina\localhost\webdemoplus\org\apache\jsp
2.6 JSP中的域对象
2.6.1 JSP中有哪几个域对象
jsp中有四个域对象分别是pageContext、request、session、application
2.6.2 JSP四大域对象的作用范围及描述
域对象 | 域对象描述 | 作用范围 | 应用场景 |
---|---|---|---|
request | 等价于HttpServletRquest域对象 | 一次请求 | 本次请求后数据不再使用,可用于查询 |
session | 等价于HttpSession域对象 | 一次会话 | 同一个会话中共享数据,可用于登录信息 |
application | 等价于ServletContext域对象 | 整个项目 | 所有用户共享数据,可用于程序的配置信息 |
pageContext | JSP独有的域对象 | 当前页面 | 单独作用于JSP当前页面 |
注意:pageContext域对象可以操作其他三个域对象的数据!
2.6.3 pageContext域对象获取内置对象和操作其他域对象
- pageContext域对象可以获取其他内置域对象
- pageContext域对象不仅可以操作page域对象,还可以操作request、session和application域对象
- 使用pageContext域对象实现转发
pageContext.forward(“test.jsp”);
- 使用pageContext域对象实现动态包含
pageContext.include(“dynamic.jsp”);
<%--
Created by IntelliJ IDEA.
User: Ziph
Date: 2020/4/27
Time: 13:36
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>
<%
/**
* pageContext域对象获取jsp中九大内置对象
*/
pageContext.getPage();
pageContext.getRequest();
pageContext.getResponse();
pageContext.getSession();
pageContext.getServletConfig();
pageContext.getServletContext();
pageContext.getException();
pageContext.getOut();
%>
<%
/**
* 操作Request域对象
* <p>
* 方法:setAttribute(String name, Object value, int scope);
* 参数说明:
* String name:参数名称
* Object value:参数值
* int scope:操作的域
* <p>
* 指定操作域的参数,可以传入操作域对象的对应数字编号
* public static final int PAGE_SCOPE = 1;
* public static final int REQUEST_SCOPE = 2;
* public static final int SESSION_SCOPE = 3;
* public static final int APPLICATION_SCOPE = 4;
* <p>
* 也可以使用PageContext域对象获取该参数传入
* 例如:PageContext.REQUEST_SCOPE
*/
pageContext.setAttribute("request", "request", PageContext.REQUEST_SCOPE);
//因为本次操作的是Request对象,操作页面的默认重定向是不在Request对象的作用范围的,所以我们使用请求转发
//Request对象作用范围是一次请求;请求转发是内部操作,所以符合Request对象的作用范围
pageContext.forward("/test.jsp");
//等价于request.getRequestDispatcher("/test.jsp").forward(request, response);
/**
* 操作Session域对象
*/
pageContext.setAttribute("session", "session", PageContext.SESSION_SCOPE);
/**
* 操作application域对象
*/
pageContext.setAttribute("application", "application", PageContext.APPLICATION_SCOPE);
%>
</body>
</html>
test.jsp
<%
/**
* 操作Reuqest域对象(获取)
*/
String requestAttribute = (String) request.getAttribute("request");
System.out.println(requestAttribute);
String pageContextAttribute = (String) pageContext.getAttribute("request", PageContext.REQUEST_SCOPE);
System.out.println(pageContextAttribute);
/**
* 操作Session域对象(获取)
*/
String pageContextAttribute1 = (String) pageContext.getAttribute("session", PageContext.SESSION_SCOPE);
System.out.println(pageContextAttribute1);
/**
* 操作application域对象(获取)
*/
String pageContextAttribute2 = (String) pageContext.getAttribute("application", PageContext.APPLICATION_SCOPE);
System.out.println(pageContextAttribute2);
%>
三、EL表达式
3.1 什么是EL表达式
表达式语言(Expression Language),或称EL表达式,简称EL,是Java中的一种特殊的通用编程语言,借鉴于JavaScript和XPath。 主要作用是在Java Web应用程序嵌入到网页(如JSP)中,用以访问页面的上下文以及不同作用域中的对象,取得对象属性的值,或执行简单的运算或判断操作。
3.2 了解EL表达式和注意事项
EL表达式简化JSP中Java代码开发,代替脚本表达式<%=输出脚本%>。它不是一种开发语言,是jsp中获取数据的一种规范。格式:
${EL表达式}
等价于pageContext.findAttribute(name)
3.3 EL表达式获取域数据
域 | EL表达式 |
---|---|
page域 | ${pageScope.name} |
request域 | ${requestScope.name} |
session域 | ${sessionScope.name} |
application域 | ${applicationScope.name} |
3.3.1 EL表达式基本获取域数据
使用最基本的方式来获取域数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL获取域数据</title>
</head>
<body>
<%
//设置page域
pageContext.setAttribute("username1", "pageScope");
//设置request域
request.setAttribute("username2", "request");
//设置session域
session.setAttribute("username3", "session");
//设置application域
application.setAttribute("username4", "application");
%>
<%--使用el表达式从page域中获取usernmae1变量--%>
${
pageScope.username1}<br>
<%--使用el表达式从request域中获取username2变量--%>
${
requestScope.username2}<br>
<%--使用el表达式从session域中获取username3变量--%>
${
sessionScope.username3}<br>
<%--使用el表达式从application域中获取username4变量--%>
${
applicationScope.username4}<br>
</body>
</html>
3.3.2 EL表达式简单获取域数据
使用简单的方法来获取域数据
自动精确匹配: 使用${username}没有指明域,那么就按照此顺序
pageScop->requestScop->sessionScop- >applicationScop
从中依次查找。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式获取域数据</title>
</head>
<body>
<%
request.setAttribute("username", "request");
%>
<%--自动精确匹配:从pageScope、requestScope、sessionScope、applicationScope逐个找拥有username变量的域数据--%>
${
username}
</body>
</html>
3.3.3 EL表达式获取复杂域数据(数组、集合、Java对象)
使用EL表达式获取数组、List集合、Map集合和Java对象
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="com.mylifes1110.java.bean.User" %><%--
Created by IntelliJ IDEA.
User: Ziph
Date: 2020/4/27
Time: 20:19
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>
<%--数组--%>
<%
String[] username = {
"Ziph", "Join", "Marry", "Jack"};
pageContext.setAttribute("username", username);
%>
<%--JSP输出脚本取出数组中下标0的username值--%>
<%--步骤:取数组中的域数据、强转为字符串数组、取出下标为0的域数据--%>
<%=
((String[]) pageContext.getAttribute("username"))[0]
%>
${
username[0]}
<%--List集合--%>
<%
List<String> fruits = new ArrayList<>();
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橘子");
request.setAttribute("fruitsName", fruits);
%>
<%--取出List的集合中的第一个数据--%>
<%=
((List<String>) request.getAttribute("fruitsName")).get(0)
%>
<%--两种方法都可以,相同作用--%>
${
fruitsName.get(0)}
${
fruitsName[0]}
<%--Map集合--%>
<%
Map<String, String> vegetables = new HashMap<>();
vegetables.put("tomato", "西红柿");
vegetables.put("cucumber", "黄瓜");
vegetables.put("lettuce", "莴笋");
session.setAttribute("vegetablesName", vegetables);
%>
<%--取出Map集合中的西红柿--%>
<%=
((Map<String, String>) session.getAttribute("vegetablesName")).get("tomato")
%>
${
vegetablesName.tomato}
<%--Java对象--%>
<%
User user = new User(1, "Ziph", "123456");
application.setAttribute("user", user);
%>
<%--获取User对象的用户名--%>
<%=
((User) application.getAttribute("user")).getUsername()
%>
${
user.username}
</body>
</html>
public class User {
private int id;
private String username;
private String password;
public User(int id, String username, String password) {