(八)JSP 技术知识点总结(来自那些年的笔记)
目录
可能是JSP
知识总结的最全的博客之一了,你想要寻找的知识,这里都有 ;
作者:淮左白衣
来源:笔者当时学web的笔记
时间:-2018年5月4日21:25:09
什么是 jsp
JSP
全称是 java servlet pages
,它和 servlet
技术一样,都是Sun公司定义的一种用于开发动态web页面的技术
为什么
jsp
也是一种动态web资源的开发技术呢?写
jsp
,虽然就像是在写HTML
,但是jsp
允许在页面中编写java
代码,并且允许开发人员在页面中获取request
、response
等web
开发常用对象,实现与浏览器的交互,所以jsp也是一种动态web资源的开发技术;例子:输出当前时间
Date date = new Date();
//这个out对象是可以直接使用的,它是JspWriter的实例
out.write(date.toLocaleString());
Jsp
调用和运行原理(简略版)
浏览器访问 jsp
页面时,Web
服务器是如何调用并执行一个jsp页面的?
首先知道,我们访问服务器的资源时,无论访问的是什么?比如访问的是HTML、jsp,其实我们访问的都是一个servlet,而不是真正的jsp、html ,因此,我们访问 jsp
其实就是去访问 servlet
;
Jsp
在被访问的时候,服务器会将它 翻译为 servlet
,转换后的servlet
,被保存在服务器目录下的work/项目名/apache/…
提问:
web 服务器在执行jsp页面时,是如何把jsp页面中的HTML排版标签输出给浏览器的?
这里其实是
jsp
对应的servlet
的功劳,我们知道服务器会将jsp
转为一个servlet
对象,我们去访问jsp
的时候,实际访问到的也是这个servlet
对象;在这个
servlet
对象对应的类中。它是通过out.writer()
语句将jsp
中的HTML
语句,原封不动的打给浏览器;遇到<%java代码%>
,就直接执行;jsp页面中的java代码,服务器是如何执行的?
是原封不动的,代码最后都在在
servlet
类中执行了;Web服务器在调用jsp时,会给jsp提供一些什么java对象?
会提供许多对象;
request、response、out、application、session
等这些对象,在jsp
中是直接可以使用的,因为在jsp对应的servlet类中已经提供好了;
如果想要获得jsp
对应的servlet
类的对象的自身,使用page
,也是它内置提供的;
上面的几个问题,其实都可以翻看对应的 servlet 类的源码,,找到答案;
Jsp语法
Jsp模板元素
Jsp
页面中的HTML
内容称之为jsp
模板元素。Jsp的模板元素定义了网页的基本骨架,即定义了页面的结构和外观;
下面的几个概念,分清楚了,别混淆;
Jsp脚本表达式
语法:
<%= xxxx %>
jsp脚本表达用于将程序数据输出到客户端,只能写在一行;
Jsp
引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应的位置用out.print(...)
,将数据输出给客户端。Jsp脚本表达式的变量或者表达式后面不能有
分号
,其实原因很简单,脚本表达式是要被放到out.print(...)
里面的,在结尾加上一个 ; 会被输出,而我们并不想输出这个分号;Jsp脚本片段
jsp脚本片段用于在jsp页面中编写 多行 java代码;
语法:
<%
多行java代码
%>
注意:jsp
脚本片段中只能出现java
代码,不能出现其他模板元素
,因为,jsp引擎
在翻译jsp
页面时,会将jsp脚本片段
中的 java
代码原封不动的放到 servlet
的 _jspService
方法中。
jsp脚本片段中的java代码,必须严格遵守java语法!废话,最后被转到servlet中,java代码原封不动的;
在一个jsp页面中可以有多个脚本片段,在脚本片段之间是可以写上模板元素的;并且多个脚本片段之间的数据是共享的;(了解下底层原理,就知道为啥共享了
)
单个脚本片段中的java代码可以是不完整的,但是多个脚本片段中,java代码必须完整了 ;
Jsp声明
在jsp中,脚本片段中java代码,都被翻译到servlet的jspService方法中了;
那么假如,我们想要将java代码,写到jspService方法外面的话,就需要使用
jsp声明
了;
<%!
java代码
%>
我们就可以为servlet
类添加方法
、字段
等属性了,但是一般没啥人使用这个技术;
Jsp注释
格式:
<%--
注释信息
--%>
JSP引擎在将 jsp
页面翻译成 servlet
程序时,会 忽略jsp
页面中被注释的内容 ;注意是被jsp引擎翻译时,就抛弃了,也就是在servlet类中将没有这个注释的内容;但是你要是使用HTML的注释,就不行了;
Jsp指令
jsp指令
是为jsp引擎
而设计的。它们并不直接产生任何可见输出,而只是告诉引擎如何处理jsp页面中的其余部分。
在jsp2.0
规范中共定义3个指令:今天2018年4月23日,jsp规范,早就不是2.0点了。需要注意下,但是不影响你学习JSP
page指令
Include指令
taglib指令
Jsp指令简介
- jsp指令的基本语法格式:
<%@ 指令 属性名=“值” %>
举例:
<%@ page contentType="text/html; ISO-8859-1" %>
如果一个指令有多个属性,这多个属性可以写在一个指令中,用 空格
分隔多个属性,也可以分开写 ;
下面讲解3大指令;
Page指令
page指令
用于定义jsp页面的各种属性,无论page指令出现在jsp页面中的什么地方,它作用的都是整个jsp页面;
为了保持程序的可读性和遵循良好的编程习惯,page指令
最好是放在整个jsp页面的初始位置。
Jsp2.0规范中定义的 page指令
的完整语法:
属性名 = “值 ” |
作 用 |
---|---|
pageEncoding = "xxx" |
指明翻译 jsp 的时候,使用 xxx 码表 |
contentType = "text/html;charset=UTF-8" |
指明jsp 翻译成的 servlet 文件,里面的 response 使用的码表 |
language = "java" |
指明 jsp 页面中的语言是 java |
extends = "xxx.class" |
表名生成jsp 翻译的servlet 类继承自xxx ,不过一般,继承自默认类,即可。不需要改动 |
import = "xxx" |
表示,我们的java 语句,需要导入的包,一般自动导包就好了,不用我们手动去指定这个属性 |
session = "false / true " |
false 表示,翻译过去的servlet 中不要自动创建session 对象,目的是为了,在不需要 session 的情况下,避免生成 session ,减轻服务器的压力。或者我们需要session 对象,但是,我们想手动让服务器创建session 对象的 |
buffer = "8kb / none / xx kb" |
out.print() 的数据,不是直接写到浏览器中(效率太慢),还是先写到缓冲区中,再写到浏览器,buffer 指定缓冲区的大小,默认是8kb |
autoFlush = "false / true" |
是否自动刷新缓冲区,默认为true |
isThreadSafe = "true" |
翻译过去的servlet 是否是线程安全的,这个最TM奇怪了,默认为true。但是表示默认线程不安全 |
isErrorPage = "true" |
表示该jsp 是页面 错误处理 页面,属性值置为true 时,jsp 翻译为 servlet 时,会传进去一个异常对象,表示错误的异常;作用 当服务器出错了,跳到错误页面(404页面),然后返回给浏览器,但这404是个正确的页面,服务器就会返回200状态码,我们 为了告知浏览器我们出错了,就在页面中加上这个属性值,服务器将返回500 |
isELIgnored = "true" |
是否忽略 EL表达式 |
errorPage = "url" |
用来指定当前页面出错时,跳转的界面。属性值必须使用相对路径,以 / 开头则相对当前 web 应用;没有 / 打头,则相对于当前页面;当然,我们也可以在服务器的 web.xml 文件 使用<error-page> 元素为整个web 应用指定错误处理页面,其中的两个子标签,一个用于指明异常的类型(写全名),这个子标签还可以写成状态码,一个用于指明出现该异常。跳准的界面地址;如果我们在 jsp 中写明了 errorPage 属性,那么web.xml 文件中的错误处理配置,对此jsp 不生效 |
Include指令
include
指令用于引入 jsp
页面,如果使用 include
引入其他 jsp
页面,那么 jsp
引擎将把这两个jsp
翻译为一个servlet
,所以,include
指令引入通常也称为 静态导入;
属性名 = “值 ” |
作 用 |
---|---|
file = "url" |
其中的file 属性用于指定被引入文件的路径。路径以“/” 开头,来表示当前web 应用; |
细节:
- 被引入的文件必须遵循
jsp
语法 - 被引入的文件可以使用任意的扩展名,即使是
HTML
扩展名,jsp引擎
还是会按照处理jsp
页面的方式处理页面的内容;为了,见名思意,jsp规范
建议使用.jspf
作为静态导入文件的扩展名; - 由于使用
.jspf
指令会涉及到两个jsp页面,并会把2个jsp翻译为一个servlet,所有这两个jsp页面的指令不能冲突; - 被导入的页面,不要包含
HTML
语句了,否则页面将不是一个完成的页面,会出现两个<head>
这样的标签;
动态包含:
语法: request.getRequestDispatcher("url").include(request,response);
这是在运行时包含,会将 每一个 jsp
都对应生成一个servlet
,也就是最终生成不止一个 servlet
;
我们一般选择静态导入
,性能高 ;
taglib指令
在讲标签库的时候,再讲;
Jsp乱码问题
乱码产生的根由:无外乎两种
jsp文件
保存的编码和服务器翻译servlet
的时候的编码不一致- 浏览器的编码和翻译的
servlet
的response
的编码编码不一致;
解决方法: <%@ page pageEncoding="utf-8" contentType="text/html;charset=UTF-8" %>
我们发现只要这两个地方使用相同的编码,乱码就不会产生;
pageEncoding=”xxx”
告诉服务器翻译时使用什么码表;
contentType="text/html;charset=UTF-8"
再告诉浏览器用什么码表打开 ;
其实可以不告诉浏览器用什么码表,因为 只要告诉服务器翻译的码表,服务器会自动将servlet的response的码表设为一致的;但是,我们还是写上吧
jsp运行原理(详细版)
每个jsp
页面在 第一次 被访问时,web容器
都会把请求交给 jsp引擎
(即一个java程序)去处理。Jsp引擎
先将 jsp
翻译成一个_jspServlet
(实际上就是一个servlet),然后按照 servlet
的调用方式进行调用 ;
由于JSP
第一次访问时,会被翻译成servlet,所有第一次访问通常会比较慢,但是第二次访问,JSP引擎
如果发现 JSP
没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响;
JSP中的九大隐式对象
JSP引擎
在调用 JSP
对应的 _JspServlet
时,会 传递或创建 9个与WEB开发相关的对象供_JspServlet
使用。
JSP
技术的设计者为了方便web
开发人员在编写JSP
页面时,获得这些对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这9个变量就可以快速的获得这9大对象的引用;
这九大隐式对象就是:response
、request
、session
、application(ServletContext)
、page
(jsp
对象自身)、config(servlertConfig)
、exception
、out(JspWriter)
、PageContext
前面7个,在学JSP之前,都已经学过了,这里重点讲最后两个;
Out隐式对象
作用:
Out隐式对象
用于向客户端发送文本数据;Out对象
是通过调用PageContext
对象的getOut()
方法返回的,其作用和用法与servletResponse.getWriter
方法返回的PrintWriter
对象非常相似。JSP
页面中的out
隐式对象的类型为JspWriter
,JspWriter
相当于一种带缓存功能的PrintWriter
,设置JSP
页面的page
指令的buffer
属性可以调整它的缓存大小,甚至关闭它的缓存(buffer
属性的值为none
);只有向
out
对象中写入了内容,且 满足如下任何一个条件时(相当于刷新缓冲区),out
对象才会去调用servletResponse.getWriter
方法,并且通过该方法返回PrinterWriter
对象将out
对象缓冲区中的内容 真正的写入 到servlet
引擎提供的缓冲区中(response
缓冲区):条件
:
√ 设置page
指令的buffer属性关闭了out
对象的缓存功能
√out
对象的缓冲区已满 ;
√ 整个JSP
页面结束;备注
:
Out
对象输出的数据 可能滞后于response.getWriter
对象输出的数据,原因就在于out对象自己的缓冲区;out对象的缓存区满了,才将数据刷新到response的缓冲区;服务器发现response缓冲区有数据,才会将数据发送到客户端;
PageContext对象
是jsp
技术中最重要
的一个对象,它代表jsp
页面的运行环境
;
生命周期
是一个jsp
页面;
这个对象自身就封装可其他8大隐式对象的引用;(这个最厉害了)
它自身还是一个域对象,可以用来保存数据;
这个对象中,还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其他资源、检索其他域对象中的属性;
通过PageContext
对象获得其他对象
通过 getXXX()
方法;
PageContext
对象中包含其他8大隐式对象的引用;
首先知道一个事实:JSP
页面中是不应该出现java
代码,良好的jsp
中,是不应该出现一行java
代码的;
但是有些时候,我们为了获取servlet
传过来的数据,不得已要使用java
代码,这时候,我们就需要一个技术:自定义标签;(以后会讲这个技术)
我们把java
代码替换成一个自定义标签
,这个标签对应着一个java
类,我们需要把web中的这些对象传给java
类,一个一个传,很麻烦的,因此,我们就直接传一个pageContext
对象过去;
Javaweb的四个域
域 | 范围(从小到大 ) |
---|---|
Page 域: |
pageContext,最小的域,只能在页面中使用 |
Request 域: |
请求域 |
Session 域: |
会话级别的域 |
ServletContext 域: |
最大的域,在整个应用程序中可用 |
PageContext域的方法
获取数据
pageContext.getAttribute(String) ;
设置数据
pageContext.setAttribute(String,String);
移除数据
pageContext.removeAttribute(String);
PageContext跨域访问的方法
获取id对应的域的数据
pageContext.getAttribute(String,id) ;
设置id对应的域数据
pageContext.setAttribute(String,String,id);
移除id对应的域数据
pageContext.removeAttribute(String,id);
PageContext查找属性的方法
pageContext.findAttribute(String)
用于查找某个属性的属性值,它会依次从page
、request
、session
、application
四个域,从小到大的查找,在某个域中查到数据,即刻返回这个数据,不会再继续查下去。如果四个域都没查到,则返回null;
这个方法,便利于我们可以在jsp
中直接使用这个方法来查找数据,而不要去关注数据在哪一个域中;
引入和跳转到其他资源
PageContext
类中定义了一个forward
方法和两个include
方法来分别简化和替代RequestDispatcher(...).forward
方法和RequestDispatcher(...).include
方法。
原始的操作
:
// forward
request.getRequestDispatcher("/xxx").forward(request, response);
// include
request.getRequestDispatcher("/xxx").include(request, response);
使用pageContext
简化:
// forward
pageContext.forward("/xxx");
// include
pageContext.include("/xxxx");
方法接受的资源如果以 /
开头,/
代表当前web
应用;
JSP标签
JSP Action (JSP动作)
,它用于jsp
页面中提供业务逻辑功能,避免在JSP
页面中直接编写java
代码,造成jsp
页面难以维护;
常用的三种标签:
// 动态包含
<jsp:include page=""> </jsp:include>
//跳转页面
<jsp:forward page="">
// 负责带数据到另一个JSP页面中,value的值,可以是脚本表达式
// 一般和包含include便签一起使用
<jsp:param name="" value=""></jsp:param>
// 将数据带到xxx.jsp 中
<jsp:include page="xxxx.jsp">
<jsp:param name="xxx" value="xxx"/>
</jsp:include>
其中 </jsp:forward>
Jsp跳转
应用场景:
在配置欢迎首页的时候,是不让配置servlet的,只能配置成jsp。 因此,在jsp中进行跳转页面;
映射JSP
<servlet>
<servlet-name>myform</servlet-name>
<!--Jsp的路径需要 / 来指认 -->
<jsp-file>/form.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>myform</servlet-name>
<url-pattern>/myform.html</url-pattern>
</servlet-mapping>
JSP抽风时好时坏的原因
如果访问JSP
的时候,出现服务器报错,紧接着再次访问,服务器又不报错的情况,像神经病一样一时好一时坏;
出现这样的问题的原因在于:JSP
文件被我们写错了;并其写错之前,这个JSP曾经被我们正确写对过,并且在服务器中有翻译过的servlet,这样,当我们把JSP
修改出错以后,再次访问,服务器发现JSP
被修改过,就会重新翻译一次,生成新的servlet,覆盖之前的servlet。但是由于,JSP
语法有错,无法被正确的翻译为servlet
,这样旧的servlet
就不会被覆盖掉。还存在在服务器中;
这样,当我们第一次访问的时候,服务器翻译JSP
失败,就会爆错,但是我们紧接着,再次访问,服务器发现,这人怎么回事啊,我刚翻译完这个servlet
啊,它就不会再次翻译servlet,而是把之前旧的servlet当成上一次翻译的servlet
(这个过程,跟JSP变没变,没有任何关系,应该是JSP设计者,为了减轻服务器的压力设计的),给我们;这就是我们第一次报错,紧接着再次访问,就正确的原因;
当我们,过一会再次访问,服务器就会发现,我曹这个JSP,我并没有翻译啊,就会再次翻译,然后,就会再次报错,周而复始,给我们的感觉就是JSP在抽风,时好时坏;
仿佛一下子回到了90年代的夏天,你光着上身,穿着大裤衩,一双简单的人字拖,摇着一把破旧的芭蕉扇,VCD里转动着盗版的碟片,满满都是广东香港泛滥到内地的流行歌曲和港片,手里的冰激凌在融化,碟片偶尔会卡,你拿起遥控摁了一下快进键,一下子就这么快进了十几年。
写的真好!
《over》
(八)JSP 技术知识点总结(来自那些年的笔记)的更多相关文章
- jsp技术知识点
1.jsp被Tomcat翻译成.java文件后,会被放在Tomcat安装目录下的\work\Catalina\localhost\station\org\apache\jsp文件夹下 2.El表达式表 ...
- (一)HTTP协议的一些知识点(来自那些年的笔记)
目录 http协议1.0.1.1两个版本的区别 访问几次服务器? Http请求行和请求方式详解 可以在超链接上传一些数据 HTTP请求头各个头字段的详解 HTTP响应和响应行状态详解 断点下载 HTT ...
- java的JSP技术
java的JSP技术 [toc] 1.JSP简介 Jsp技术是用来开发java web的页面显示的,所有MVC模型里面的视图层,所以视图层的开发 jsp不是编程语言,三个英文是java server ...
- Servlet,jsp,JSP技术 ,JSP编程
一.Servlet 思考 1 浏览器可以直接打开JAVA/class文件吗? 不可以 2浏览器可以打开HTML.JS 文件吗? 可以 3 JAVA程序可以生成HTML文件吗?可以的,用IO流. 4 ...
- Jsp技术总结
这节我们总结一下Jsp的相关技术. 1. 什么是JSP JSP即Java Server Pages,它和servlet技术一样,都是sun公司定义的一种用于开发动态web资源的技术.该技术的最大特点在 ...
- atitit 商业项目常用模块技术知识点 v3 qc29
atitit 商业项目常用模块技术知识点 v3 qc29 条码二维码barcodebarcode 条码二维码qrcodeqrcode 条码二维码dm码生成与识别 条码二维码pdf147码 条码二维码z ...
- java web学习总结(二十八) -------------------JSP中的JavaBean
一.什么是JavaBean JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法 ...
- Java Web之JSP技术
JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比htm ...
- JSP技术
1. JSP技术简介 JSP全称是Java Server Pages,它和servlet技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.是sun公司定义的一种规范,JSP实际上就是Se ...
随机推荐
- hadoop2.9.2 调整jvm
错误:namenode挂掉 查看hadoop的日志文件,发现存在大量的GC,导致namenode挂掉 命令行执行错误信息: 解决: 查看系统内存: # /data1/hadoop/hadoop/etc ...
- 网页表格导入导出Excel
用JS实现网页表格数据导入导出excel. 首先是JS文件中的代码 (function($){ function getRows(target){ var state = $(target).data ...
- mybatis bind标签
开门见山的说,平时写模糊查询,一直用${name},例如: select * from table where name like '%${name}%' 后来知道了,这样写可能会引发sql注入,于是 ...
- Json序列化指定输出字段 忽略属性
DataContract 服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型. 一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务 ...
- 导入GoogleClusterData到MySQL
本篇随笔记录如何导入google-cluster-data-2011-1-2的 job_events和task_events到MySQL 1. 下载数据 download_job_events: im ...
- osg 加载 fbx文件
#ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include <osg/Group> #include <os ...
- ubuntu 17.04 Tomcat安装
安装Tomcat分为两步: JDK和Tomcat 安装jdk 1.在oralce官网下载jdk
- java中快速读写图片到BufferedImage对象
java7读取文件到BufferedImage对象 BufferedImage bufferedImage = ImageIO.read(Files.newInputStream(Paths.get( ...
- ElasticSearch——冷热(hot&warm)架构部署
背景 最近在做订单数据存储到ElasticSearch,考虑到数据量比较大,采用冷热架构来存储,每月建立一个新索引,数据先写入到热索引,通过工具将3个月后的索引自动迁移到冷节点上. ElasticSe ...
- docker:如何查看容器的挂载目录
docker inspect container_name | grep Mounts -A 20 docker inspect container_id | grep Mounts -A 20 [r ...