目录

  • 1、什么是JSP
  • 2、JSP原理
  • 3、JSP基础语法
    • jsp表达式
    • jsp脚本片段
    • jsp声明
    • jsp注释
  • 4、JSP指令
  • 5、JSP行为
  • 6、9大内置对象
  • 7、EL表达式
    • 格式
    • 变量
    • [ ]与.运算符
  • 8、JSTL表达式
  • 9、JSP标签

ps:本文着重于一些重点(第二点原理)哦~ 毕竟2020了 ,JSP很少用到了!

1、什么是JSP

Java Server Pages:Java服务器端页面,和Servlet一样,用于动态Web技术!

JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。

特点:

  • JSP 技术是以 Java 语言作为脚本语言的,JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于HTTP的应用程序。因此JSP里可以直接写Java代码!

  • 写JSP就像写HTML

    • HTML页面是静态页面,固定内容,不会变,由web服务器向客户端发送。
    • JSP页面是有JSP容器执行该页面的Java代码部分然后实时生成动态页面,可动态更新页面上的内容。
    • JSP页面中可以嵌入Java代码,为用户提供动态数据

2、JSP原理

JSP是怎么执行的?

在IDEA中使用Tomcat会在IDEA目录下的tomcat中产生一个work目录

IDEA的工作目录位置:

C:\Users\zsr204\AppData\Local\JetBrains\IntelliJIdea2020.1

或者C:\Users\zsr204.IntelliJIdea2019.3

点进去,可以看到我们使用过tomcat的项目

点入一个项目,就可以看到对应的work目录

继续点开,可以发现index.jsp页面转换成了Java程序

我们打开.java文件,发现继承了HttpJspBase

而HttpJspBase继承了JspPage,JspPage又继承了Servlet

所以:JSP最终会被转换为Java类,JSP本质上就是Servlet,浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet

经过以上分析,我们可以得出以下原理图


接下来我们分析一下index.java类

有以下三个主要的方法:

//初始化jsp页面
public void _jspInit() {}//关闭jsp页面
public void _jspDestroy() {}//JspService
public void _jspService(HttpServletRequest request,HttpServletResponse response)

关于**_jspService**方法:有几个部分组成

  1. 判断请求
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {final java.lang.String _jspx_method = request.getMethod();if ("OPTIONS".equals(_jspx_method)) {response.setHeader("Allow","GET, HEAD, POST, OPTIONS");return;}if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {response.setHeader("Allow","GET, HEAD, POST, OPTIONS");response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");return;}}
  1. 内置一些对象

    这些对象我们可以直接在JSP页面中使用~

final javax.servlet.jsp.PageContext pageContext;//页面上下文,包含整个页面相联系的数据
javax.servlet.http.HttpSession session = null; //session(服务端会话)对象
final javax.servlet.ServletContext application; //applicationContext
final javax.servlet.ServletConfig config;       //config配置
javax.servlet.jsp.JspWriter out = null;            //out输出对象,用来写入响应流的数据
final java.lang.Object page = this;                //page,servlet自身
HttpServletRequest request                      //HTTP request(请求)对象
HttpServletResponse response                    //HTTP response(响应)对象
  1. 输出页面前增加的代码
response.setContentType("text/html");                  //设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);                                                     //初始化pageContext对象
_jspx_page_context = pageContext;                      //赋值
application = pageContext.getServletContext();         //获取servlet上下文
config = pageContext.getServletConfig();               //获取配置对象
session = pageContext.getSession();                        //获取session对象
out = pageContext.getOut();                                //获取out输出对象
_jspx_out = out;                                       //赋值
  1. 输出当前页面
out.write("<html>\n");
out.write("<body>\n");
out.write("<h2>Hello World!</h2>\n");
out.write("</body>\n");
out.write("</html>\n");

这时候,如果我们在IDEA中新加一个hello.jsp,我们点击运行

我们会发现,刚才打开index.jsp所在的的目录不存在了,其实是原先的整个work目录没了,并生成了一个新的work目录

我们继续点开新的work目录,同样可以看到之前的index.jsp和index.java

这时候我们在浏览器访问hello.jsp页面,发现页面输出了我们jsp中用java代码定义的name

然后可以发现,我们多了hello.jsphello.java两个文件

我们再点开hello.java,可以发现除了输出页面的代码变成对应hello.jsp的代码以外,其他没有区别

      out.write("\r\n");out.write("<html>\r\n");out.write("<head>\r\n");out.write("    <title>Title</title>\r\n");out.write("</head>\r\n");out.write("<body>\r\n");out.write("hello\r\n");out.write('\r');out.write('\n');String name = "zsr";out.write('\r');out.write('\n');out.write("\r\n");out.write("name:");out.print(name);out.write("\r\n");out.write("</body>\r\n");out.write("</html>\r\n");

我们观察这段段代码,可以发现

在JSP页面中:Java代码会原封不动的输出,如果是Html代码,就会被转换为以下形式

out.write("<html?\r\n");

3、JSP基础语法


jsp表达式

用来将程序输出到客户端

<%= 变量或者表达式 %>

<%=new Date()%>


jsp脚本片段

  • 脚本程序可以包含任意量的Java语句、变量、方法或表达式,只要它们在脚本语言中是有效的。

<% 代码片段 %>

等价于

<jsp:scriptlet>代码片段
</jsp:scriptlet>
<%int sum = 0;for (int i = 0; i < 100; i++) {sum += i;}out.print("<h1>总和为" + sum + "</h1>");
%>

脚本片段的嵌套

<%int x = 10;out.print(x);
%>
<p>这是一个jsp文档</p>
<%out.println(x);
%>
<%for (int i = 0; i < 5; i++) {
%>
<h1>helloworld</h1>
<%}
%>


jsp声明

  • 一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用

<%! declaration; [ declaration; ]…%>

等价于

<jsp:declaration>代码片段
</jsp:declaration>
<%!static {System.out.println("加载中");}private int count = 0;public void function() {System.out.println("进入了方法");}
%>

会被编译到jsp生成的Java类index_jsp中!

而上述jsp表达式和脚本片段都会生成到**_jspService**方法中


jsp注释

<%--注释--%>
语法 描述
<%-- 注释 --%> JSP注释,注释内容不会被发送至浏览器甚至不会被编译
HTML注释,通过浏览器查看网页源代码时可以看见注释内容


4、JSP指令

JSP指令用来设置与整个JSP页面相关的属性。

指令 描述
<%@ page … %> 定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等
<%@ include … %> 包含其他文件
<%@ taglib … %> 引入标签库的定义,可以是自定义标签

实例1:定制500错误页面,利用<%@ page … %>指令跳转

error.jsp(1/0会出现500错误,会跳转到500错误页面)

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%--定制错误页面--%>
<%@ page errorPage="error/500.jsp" %><html>
<head><title>出现错误</title>
</head>
<body>
<%int x = 1/0;
%>
</body>
</html>

500.jsp(自定义500错误页面,显示500错误图片)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><img src="../img/500.jpg" alt="500"></body>
</html>

测试:点击运行,输入地址localhost:8080/error.jsp,就会跳转到自定义的500错误页面

实现错误页面的跳转还可以再web.xml中配置

<error-page><error-code>404</error-code><location>/error/404.jsp</location>
</error-page>
<error-page><error-code>500</error-code><location>/error/500.jsp</location>
</error-page>

实例二 :效仿正常页面,利用<%@ include … %>指令包含一个头部一个尾部

header.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %><h1>页面头部</h1>

footer.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>页面尾部</h1>

common.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>包含头部尾部常规页面</title>
</head>
<body><%--将两个页面合二为一--%>
<%@include file="common/header.jsp" %>
<h1>网页主体</h1>
<%@include file="common/footer.jsp" %></body>
</html>

测试:点击运行,输入localhost:8080/common.jsp,发现如下结果


5、JSP行为

JSP行为标签使用XML语法结构来控制servlet引擎。它能够动态插入一个文件,重用JavaBean组件,引导用户去另一个页面,为Java插件产生相关的HTML等等。

行为标签只有一种语法格式,它严格遵守XML标准

<jsp:action_name attribute="value" />

行为标签基本上是一些预先就定义好的函数,下表罗列出了一些可用的JSP行为标签:

语法 描述
jsp:include 用于在当前页面中包含静态或动态资源
jsp:useBean 寻找和初始化一个JavaBean组件
jsp:setProperty 设置 JavaBean组件的值
jsp:getProperty 将 JavaBean组件的值插入到 output中
jsp:forward 从一个JSP文件向另一个文件传递一个包含用户请求的request对象
jsp:plugin 用于在生成的HTML页面中包含Applet和JavaBean对象
jsp:element 动态创建一个XML元素
jsp:attribute 定义动态创建的XML元素的属性
jsp:body 定义动态创建的XML元素的主体
jsp:text 用于封装模板数据

例如上述实现正常页面包含头部尾部还可以通过以下代码来实现

<%--jsp标签--%>
<%--拼接页面,本质还是三个页面--%>
<jsp:include page="common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="common/footer.jsp"/>

6、9大内置对象

对象 描述
request HttpServletRequest类的实例**(存东西)**
response HttpServletResponse类的实例
out PrintWriter类的实例,用于把结果输出至网页上
session HttpSession类的实例**(存东西)**
application ServletContext类的实例,与应用上下文有关**(存东西)**
config ServletConfig类的实例
pageContext PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问**(存东西)**
page 类似于Java类中的this关键字
Exception Exception类的对象,代表发生错误的JSP页面中对应的异常对象

其中request、session、application、pageContext可以存相应信息

关于request、session、application、pageContext的层级关系图:

作用域(scope)从低到高:pageContext—>request—>session—>application


案例测试:

test.jsp(用来存东西,并取出显示)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>内置对象的测试</title>
</head>
<body>
<%pageContext.setAttribute("name1", "zsr");//保存的数据只在一个页面中有效request.setAttribute("name2", "barry");//保存的数据只在一次请求中有效,请求转发会携带这个数据session.setAttribute("name3", "gcc");//保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器application.setAttribute("name4", "marry");//保存的数据只在服务器中有效,从打开服务器到关闭服务器
%>
<%//从pageContext中取,利用寻找的方式//从底层到高层(作用域)String name1 = (String) pageContext.findAttribute("name1");String name2 = (String) pageContext.findAttribute("name2");String name3 = (String) pageContext.findAttribute("name3");String name4 = (String) pageContext.findAttribute("name4");
%>
<%--使用EL表达式输出--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3></body>
</html>

然后我们点击运行,输入localhost:8080/test.jsp,可以看到下图所示结果

我们再新建一个页面test2.jsp,取出上述test.jsp存进去的东西

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>内置对象的测试</title>
</head>
<body><%//从pageContext中取,利用寻找的方式//从底层到高层(作用域)String name1 = (String) pageContext.findAttribute("name1");String name2 = (String) pageContext.findAttribute("name2");String name3 = (String) pageContext.findAttribute("name3");String name4 = (String) pageContext.findAttribute("name4");
%>
<%--使用EL表达式输出--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3></body>
</html>

然后我们点击运行,输入localhost:8080/test2.jsp,可以看到下图所示结果

发现只取出了name3和name4,也就是存在session和application里的东西,这就是因为作用域的原因

  • pageContext的作用域最小,只在当前页面有效,所以换了新页面,就找不到了

  • request的作用域其次,因为没有进行转发,所以内容也丢失了,所以没有找到


这时候如果我们在test1.jsp里面加入转发,转发到test2.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>内置对象的测试</title>
</head>
<body>
<%pageContext.setAttribute("name1", "zsr");//保存的数据只在一个页面中有效request.setAttribute("name2", "barry");//保存的数据只在一次请求中有效,请求转发会携带这个数据session.setAttribute("name3", "gcc");//保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器application.setAttribute("name4", "marry");//保存的数据只在服务器中有效,从打开服务器到关闭服务器
%>
<%//从pageContext中取,利用寻找的方式//从底层到高层(作用域)String name1 = (String) pageContext.findAttribute("name1");String name2 = (String) pageContext.findAttribute("name2");String name3 = (String) pageContext.findAttribute("name3");String name4 = (String) pageContext.findAttribute("name4");pageContext.forward("/test2.jsp");
%>
<%--使用EL表达式输出--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3></body>
</html>

然后我们点击运行,输入localhost:8080/test.jsp,可以看到下图所示结果

可以发现我们取出了存在request里的name2,这是因为我们进行了转发


7、EL表达式

EL(Expression Language) 是为了使JSP写起来更加简单

<!--standard 标签库-->
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>

作用:

  • 获取数据
  • 执行运算
  • 获取web开发的常用对象

格式

${}
  • 例如,${info}代表获取变量info的值。

  • 当EL表达式中的变量不给定范围时

    则默认在page范围查找,然后依次在request、session、application范围查找。

  • 可以用范围作为前缀表示属于哪个范围的变量

    例如:${ pageScope. info}表示访问page范围中的info变量。


变量

  • EL存取变量数据的方法很简单,例如:${name}。它的意思是取出某一范围中名称为name的变量。

  • 因为并没有指定哪一个范围的name,所以会依序从Page、Request、Session、Application范围查找。

  • 假如找到name,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传""。

EL表达式的属性如下:

属性范围在EL中的名称
Page PageScope
Request RequestScope
Session SessionScope
Application ApplicationScope

[ ]与.运算符

  • EL 提供“.“和“[ ]“两种运算符来存取数据。

  • 当要存取的属性名称中包含一些特殊字符,如 . 或 - 等并非字母或数字的符号,就一定要使用“[ ]“。

    例如:user.My−Name应当改为{ user. My-Name}应当改为user.My−Name应当改为{user[“My-Name”]}

  • 如果要动态取值时,就可以用“[ ]“来做,而“.“无法做到动态取值。

    例如:${sessionScope.user[data]}中data 是一个变量


8、JSTL表达式

JSTL(Java server pages standarded tag library,即JSP标准标签库)

  • JSTL标签库的使用就是为了弥补HTML标签的不足;他自定义许多标签供使用,功能和Java代码一样。
<!--standard 标签库-->
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>
<!--JSTL表达式的依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency><groupId>javax.servlet.jsp.jstl</groupId><artifactId>jstl-api</artifactId><version>1.2</version>
</dependency>

菜鸟教程JSTL

根据JSTL标签所提供的功能,可以将其分为5个类别

  • 核心标签
  • 格式化标签
  • SQL 标签
  • XML 标签
  • JSTL 函数

JSTL标签库的使用步骤:

  1. 引入对应的taglib

  2. 使用其中的方法

  3. 在Tomcat的lib目录下也要引入对应jstl的jar包,否则会报错:JSTL解析错误

示例:

coreif.jsp(测试用户登录)

<%@ 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>
<h4>if测试</h4>
<hr>
<%--EL表达式获取表单中的数据${param.参数名}
--%>
<form action="coreif.jsp" method="get"><input type="text" name="username" value="${param.username}"><input type="submit" value="登录">
</form><%--判断如果提交的用户名是管理员,则登录成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin"><c:out value="管理员欢迎你"/>
</c:if>
<c:out value="${isAdmin}"/>
</body>
</html>

点击运行,打开 http://localhost:8080/coreif.jsp,出现如下结果

如果我们输入admin再点击登录


9、JSP标签

一共以下几种标签

实例:

jsptag:(携带参数,请求转发到 jsptag2

<html>
<head><title>Title</title>
</head>
<body><jsp:forward page="jsptag2.jsp"><jsp:param name="name" value="zsr"/><jsp:param name="age" value="20"/>
</jsp:forward></body>
</html>

jsptag2:(取出请求参数)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<%--取出参数--%>
名字:<%=request.getParameter("name")%>
年龄:<%=request.getParameter("age")%>
</body>
</html>

然后点击运行,在浏览器访问 http://localhost:8080/jsptag.jsp,可以看到对应结果

到这就结束了!!谢谢大家支持哦~

2020了,还要学JSP嘛?入个门呗!毕竟Servlet亲兄弟~相关推荐

  1. 到底还要学什么才能成为2020年前端架构师!?(用图说话)

    整理参考自某培训机构,内容很全面,作为学习方向指导很不错,建议大家收藏,可以通过以下知道自己该学什么,该掌握什么. 希望大家可以一起进步一起加油! 详细内容见:到底还要学什么才能成为2020年前端架构 ...

  2. 不写情书,程序员为什么还要学写作?

    跟小伙伴们一样,老兵哥也年轻过,在花季雨季也写过情书,不过经常石沉大海.当时特别希望自己的文笔好一些,像小说影视作品中的男猪脚那样一封书信就可以俘获菇凉的芳心.现今娃娃都能打酱油了,原来情书的效用早就 ...

  3. 西北工业大学计算机有调剂,2020年西北工业大学微电子学院硕士研究生调剂工作方案...

    我院部分专业一志愿生源不足,现接收调剂,具体通知如下: 一.调剂专业及指标 专业代码 专业名称 调剂计划 085400 电子信息 28 080900 电子科学与技术 2 二.调剂要求 根据2020年西 ...

  4. 福州理工学院C语言期末,如果有2020的毕业学弟学妹想考虑这个福州理工学院的话 作...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 如果有2020的毕业学弟学妹想考虑这个福州理工学院的话 作为2019届的哥哥姐姐们劝你们快点逃!!!! 这个学校真的是我见过最奇葩的学校 说说这个学校在生 ...

  5. 都说了多少遍,不要再学 JSP 了!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:在滴滴和头条干了 2 年后端开发,太真实-个人原创100W+访问量博客:点击前往,查看更多 陈龙|https:/ ...

  6. 2020河南工业大学计算机考研科目,你知道2020年河南工业大学硕士研究生考研有哪些复试科目...

    [摘要] 考必过小编为大家整理了关于你知道2020年河南工业大学硕士研究生考研有哪些复试科目的信息,希望可以帮助到大家,下面我们就一起来看下你知道2020年河南工业大学硕士研究生考研有哪些复试科目的具 ...

  7. 计算机改考408的学校,2020考研 河北工业大学计算机改考408

    2020考研 河北工业大学计算机改考408~今年,改考408的学校真的是越来越多了!又有一所211大学,计算机专业改考408了,这回是--河北工业大学. 河北工业大学虽然名字上带"河北&qu ...

  8. 学了python还要学什么,学python先学什么

    最近学习Python,网上学习资料挺多的,这篇写的不错,关于学了python还要学什么和学python先学什么,大家有需要也可以看看. 1.弄清楚你的动机是什么 在开始深入学习Python在线之前,值 ...

  9. 数据科学家为什么还要学藏语?这不科学。首份藏文数字数据集出炉

    数据科学家:为什么还要学藏语?这不科学. 亲,结论别下得这么早. 这是一个杠精式的对话. 藏语应当从西藏讲起,西藏是全世界人民群众最喜欢的文化边区之一. 仓央嘉措曾说,住进布达拉宫,我是雪域最大的王. ...

最新文章

  1. 活见鬼,明明删除了数据,空间却没减少!
  2. jdk1.8和tomcat9.0、maven3.5.0配置教程
  3. UA MATH567 高维统计I 概率不等式3 亚高斯性与亚高斯范数
  4. python文件选择:tkFileDialog 基础
  5. Python logging模块切分和轮转日志
  6. 【BZOJ3174】【codevs25442075】拯救小矮人,DP+贪心
  7. java i o是什么流_Java I/O 流,输入流、输出流
  8. mysql mycat docker_docker-mycat-mysql
  9. 设计模式---适配器模式(C++实现)
  10. Java 核心系列教程
  11. 13G311-1 混凝土结构加固构造 免费下载
  12. 惠普企业级服务器型号,惠普企业级服务器HP rx8640
  13. VMware Workstation 8.0 序列号
  14. wps怎么把边框加粗_怎么设置WPS表格边框线加粗 - 卡饭网
  15. 3dmax最基础的建模教程,初学者福利
  16. c语言编程求广义逆矩阵,求大神解答求广义逆矩阵的问题 拜谢了!!
  17. 用python预测小孩的身高_Python 孩子身高预测
  18. 华为办公协作与远程视频会议软件Link Now停止运营 请及时备份数据
  19. 图形渲染——伽马矫正
  20. java ee框架技术进阶式教程_《JavaEE框架技术进阶式教程》新版任务式教案

热门文章

  1. 2022-2028年中国DMF行业市场研究及前瞻分析报告
  2. 2022-2028年中国软件测试行业市场研究及前瞻分析报告
  3. python3+ 解决写入中文乱码的问题
  4. 提高班第五周周记(国庆第二天)
  5. 三层交换机原理:01路由器如何隔离广播域?
  6. pandas数据框,统计某列或者某行数据元素的个数
  7. MXNet 图优化与算子融合
  8. 端到端TVM编译器(上)
  9. Amazon SageMaker和NVIDIA NGC加速AI和ML工作流
  10. 人脸真伪验证与识别:ICCV2019论文解析