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

目录
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

image-20200710103000739

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

image-20200710103206756

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

image-20200710103316042

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

image-20200710103831103

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

image-20200710105608854

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

image-20200710105817593

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

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

image-20200710115159320

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

有以下三个主要的方法:

//初始化jsp页面
public void _jspInit() {}

//关闭jsp页面
public void _jspDestroy() {}

//JspService
public void _jspService(HttpServletRequest request,HttpServletResponse response)
1
2
3
4
5
6
7
8
关于**_jspService**方法:有几个部分组成

判断请求
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
2
3
4
5
6
7
8
9
10
11
12
内置一些对象

这些对象我们可以直接在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
2
3
4
5
6
7
8
输出页面前增加的代码
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
2
3
4
5
6
7
8
输出当前页面
out.write("\n");
out.write("\n");
out.write(“

Hello World!

\n”);
out.write("\n");
out.write("\n");
1
2
3
4
5
这时候,如果我们在IDEA中新加一个hello.jsp,我们点击运行

image-20200711102142627

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

image-20200711100540893

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

image-20200711101528851

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

image-20200711102251091

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

image-20200711101641848

我们再点开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");

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
我们观察这段段代码,可以发现

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

out.write("<html?\r\n");
1
3、JSP基础语法
jsp表达式
用来将程序输出到客户端

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

<%=new Date()%>
1
image-20200711111211730
jsp脚本片段
脚本程序可以包含任意量的Java语句、变量、方法或表达式,只要它们在脚本语言中是有效的。
<% 代码片段 %>

等价于

jsp:scriptlet
代码片段
</jsp:scriptlet>
1
2
3
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
out.print(“

总和为” + sum + “

”);
%>
1
2
3
4
5
6
7
image-20200711111934864
脚本片段的嵌套

<%
int x = 10;
out.print(x);
%>

这是一个jsp文档

<% out.println(x); %> <% for (int i = 0; i < 5; i++) { %>

helloworld

<% } %> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 image-20200711143609113 jsp声明 一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用 <%! declaration; [ declaration; ]…%>

等价于

jsp:declaration
代码片段
</jsp:declaration>
1
2
3
<%!
static {
System.out.println(“加载中”);
}

private int count = 0;

public void function() {
    System.out.println("进入了方法");
}

%>
1
2
3
4
5
6
7
8
9
10
11
会被编译到jsp生成的Java类index_jsp中!

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

image-20200711144758534

jsp注释
<%–注释–%>
1
语法 描述
<%-- 注释 --%> JSP注释,注释内容不会被发送至浏览器甚至不会被编译
HTML注释,通过浏览器查看网页源代码时可以看见注释内容
image-20200711151307742 image-20200711151245562
4、JSP指令
JSP指令用来设置与整个JSP页面相关的属性。

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

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

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

<%–定制错误页面–%>
<%@ page errorPage=“error/500.jsp” %>

出现错误 <% int x = 1/0; %> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 500.jsp(自定义500错误页面,显示500错误图片)

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

Title 500 1 2 3 4 5 6 7 8 9 10 11 测试:点击运行,输入地址localhost:8080/error.jsp,就会跳转到自定义的500错误页面

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

404 /error/404.jsp 500 /error/500.jsp 1 2 3 4 5 6 7 8 实例二 :效仿正常页面,利用<%@ include … %>指令包含一个头部一个尾部

image-20200712100904493
header.jsp

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

页面头部

1 2 footer.jsp

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

页面尾部

1 2 common.jsp

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

包含头部尾部常规页面

<%–将两个页面合二为一–%>
<%@include file=“common/header.jsp” %>

网页主体

<%@include file="common/footer.jsp" %> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 测试:点击运行,输入localhost:8080/common.jsp,发现如下结果

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

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

<jsp:action_name attribute=“value” />
1
行为标签基本上是一些预先就定义好的函数,下表罗列出了一些可用的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”/>

网页主体

1 2 3 4 5 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的层级关系图:

image-20200712122528776

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

案例测试:

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

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

内置对象的测试 <% 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表达式输出--%>

取出的值为:

${name1}

${name2}

${name3}

${name4}

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 然后我们点击运行,输入localhost:8080/test.jsp,可以看到下图所示结果

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

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

内置对象的测试

<%
//从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表达式输出–%>

取出的值为:

${name1}

${name2}

${name3}

${name4}

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 然后我们点击运行,输入localhost:8080/test2.jsp,可以看到下图所示结果

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

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

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

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

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

内置对象的测试 <% 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表达式输出–%>

取出的值为:

${name1}

${name2}

${name3}

${name4}

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 然后我们点击运行,输入localhost:8080/test.jsp,可以看到下图所示结果

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

7、EL表达式
EL(Expression Language) 是为了使JSP写起来更加简单

taglibs standard 1.1.2 1 2 3 4 5 6 7 作用:

获取数据
执行运算
获取web开发的常用对象
格式
1 例 如 , {} 1 例如, 1{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”]}

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

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

8、JSTL表达式
JSTL(Java server pages standarded tag library,即JSP标准标签库)

JSTL标签库的使用就是为了弥补HTML标签的不足;他自定义许多标签供使用,功能和Java代码一样。

taglibs standard 1.1.2 javax.servlet.jsp.jstl jstl-api 1.2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 菜鸟教程JSTL

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

核心标签
格式化标签
SQL 标签
XML 标签
JSTL 函数
JSTL标签库的使用步骤:

引入对应的taglib

使用其中的方法

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

image-20200712193321390 image-20200712193416094
示例:

coreif.jsp(测试用户登录)

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

Title
if测试

<%-- EL表达式获取表单中的数据 ${param.参数名} --%>

<%–判断如果提交的用户名是管理员,则登录成功–%>
<c:if test=" p a r a m . u s e r n a m e = = ′ a d m i n ′ " v a r = " i s A d m i n " > < c : o u t v a l u e = " 管 理 员 欢 迎 你 " / > < / c : i f > < c : o u t v a l u e = " {param.username=='admin'}" var="isAdmin"> <c:out value="管理员欢迎你"/> </c:if> <c:out value=" param.username==admin"var="isAdmin"><c:outvalue=""/></c:if><c:outvalue="{isAdmin}"/>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
点击运行,打开 http://localhost:8080/coreif.jsp,出现如下结果

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

image-20200712202657821
9、JSP标签
一共以下几种标签

image-20200712184918383
实例:

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

Title

<jsp:forward page=“jsptag2.jsp”>
<jsp:param name=“name” value=“zsr”/>
<jsp:param name=“age” value=“20”/>
</jsp:forward>

1 2 3 4 5 6 7 8 9 10 11 12 13 jsptag2:(取出请求参数)

<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>

Title <%--取出参数--%> 名字:<%=request.getParameter("name")%> 年龄:<%=request.getParameter("age")%> 1 2 3 4 5 6 7 8 9 10 11 然后点击运行,在浏览器访问 http://localhost:8080/jsptag.jsp,可以看到对应结果

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值