一、JSP 概述

  JSP:全称 Java Server Pages,是由 Sun 公司专门为了解决动态生成 HTML 文档的技术。

  JSP 其实就是 Java 服务器页面。页面中既可以指定定义 html标签,也可以定义 Java 代码,但是只能运行在服务器(Web容器中)

  作用:替代 Servlet 程序回传 HTML 页面的数据。

  原因:因为 Servlet 程序回传 HTML 页面数据是一件非常繁琐的事情,开发成本和维护成本都极高,相比于Servlet,JSP更加善于处理显示页面,而Servlet跟擅长处理业务逻辑,两种技术各有专长,所以一般我们会将Servlet和JSP结合使用,Servlet负责业务,JSP负责显示。

二、JSP的本质

  JSP 页面本质上就是一个 Servlet。

  当第一次访问 JSP 页面的时候,Tomcat 服务器会帮我们把 jsp 页面翻译成一个 Java 源文件(Servlet),并且对它进行编译生成 .class 字节码程序。

  

   其中 index_jsp.class 文件是 index_jsp 源文件编译后的字节码文件。

    打开 index_jsp.java 文件查看里面的内容。

   

    可以发现,生成的类继承与 HttpJspBase 类。这个是一个 jsp 文件生成 Servlet 程序要继承的基类!

    关联源码,查看 HttpJspBase 类的内容,从源码的类注释说明中发现:

    HttpJspBase 这个类就是所有 jsp 文件生成 Servlet程序需要去继承的基类,并且这个 HttpJspBase 类 继承了 HttpServlet 类。所以 JSP 也是一个 Servlet 小程序。

    

     再去观察翻译后的 Servlet 程序的源代码,其底层实现,也是通过输入流,把 HTML 页面数据回传给客户端。

 public void _jspService(final javax.servlet.http.HttpServletRequest request, final
javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)
&& !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or
HEAD");
return;
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
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(" a.jsp 页面\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}

     

  原理示意图:

  

   小结:

    xxx.jsp 翻译成 Java 的全面是  xxx_jsp.java 文件;

    xxx_jsp.java 文件就是一个 Servlet 程序,原来 jsp 中的 HTML 内容都被翻译到  Servlet 类的 service 方法中原样输出。

三、JSP 指令

  1、jsp 头部的 page 指令

    jsp 的 page 指令可以修改 jsp 页面的一些重要的属性或行为。

    语法格式:

<%@ page 属性名1=属性值1 属性名2=属性值2 ... %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

   

    常用属性:

     language 属性

      表示 jsp 翻译后是什么语言文件,暂时支持 Java。

    ② contentType 属性

       表示 jsp 返回的数据类型是什么,也是源码中 response.setContentType() 参数值

       作用:设置响应体的 MIME类型以及字符集;

    ③ pageEncoding 属性

      表示当前 jsp 页面文件本身的字符集

    ④ import 属性

      和 Java 源代码中,用于导包、导类。

    ⑤ autoFlush 属性

      设置当 out 输出流缓冲区满了之后,是否自动刷新缓冲区,默认是 true。

    ⑥ buffer 属性

      设置 out 缓冲区的带下,默认是 8KB。

      属性⑤和属性⑥ 都是给 out 输出流使用的。

      缓冲区溢出错误:(如果设置autoFlush=false或buffer过小会报错)

      

    ⑦ errorPage 属性

      设置当前 jsp 页面运行时出错,自动跳转去的错误页面路径。

      注意:errorPage 表示错误后自动跳转去的路径,这个路径一般都是以斜杠打头, 它表示请求地址为 http://ip:port/工程路径/ ,映射到代码的 Web 目录

    ⑧  isErrorPage 属性

      设置当前 jsp 页面是否是错误信息页面。默认是 false,如果是 true 可以获取异常信息

      取值 true:是,可以使用内置对象 Exception

      取值 false:否,默认值,不可以只使用 内置对象 Exception

    ⑨ session 属性

      设置访问当前 jsp 页面,是否会创建 HttpSession对象。默认是 true

    ⑩ extends 

      设置 jsp 翻译出来的 java 类默认继承谁

  2、include 指令

    作用:该指令用于将目标页面包含到当前页面中,用于导入页面的资源文件。

    特点:静态包含,被包含的文件不会被翻译和编译

    语法格式:

<%@include file="top.jsp"%>

  3、tablib 指令

    作用:该指令用于导入标签库。

    语法格式:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

     prefiex 表示自定义的前缀

三、JSP 脚本

  1、声明脚本(极少用)

    作用:可以给 jsp 翻译出来的 java 类定义属性,全局变量,方法甚至是静态代码块、内部类等。

    语法格式:

<%! 声明 java 代码 %>

    Demo:

 <%--1、 声明类属性--%>
<%!
private Integer id;
private String name;
private static Map<String,Object> map;
%>
<%--2、 声明 static 静态代码块--%>
<%!
static {
map = new HashMap<String,Object>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
}
%>
<%--3、 声明类方法--%>
<%!
public int abc(){
return 12;
}
%><%--4、 声明内部类--%>
<%!
public static class A {
private Integer id = 12;
private String abc = "abc";
}
%>

    声明脚本代码翻译对照:

    

  2、表达式脚本(常用)

    作用:向 jsp页面上输出数据。(输出语句中可以定义什么,该脚本中就可以定义什么)

    语法格式:

<%=表达式 %>

    表达式脚本的特点:

     ① 所有的表达式脚本都会被翻译到 _jspService() 方法中;

     ② 表达式脚本都会被翻译成 out.print() 输出到页面上;

     ③ 由于表达式脚本翻译的内容都在_jspService() 方法中,所以_jspService()方法中的对象都可以直接使用;

     ④ 表达式脚本中的表达式不能以分号结束;
     ⑤ 可以输出任意类型

    Demo:

 <%=12 %> <br>
<%=12.12 %> <br>
<%="我是字符串" %> <br>
<%=map%> <br>
<%=request.getParameter("username")%

    翻译对照:

    

  3、代码脚本

    作用:可以在 jsp 页面中,编写需要的功能(写的是Java代码,service方法中可以定义什么,该脚本中就可以定义什么,翻译到 _jspService() 中)

    语法格式:

<%
java 语句
%>

      代码脚本的特点是:

      ① 代码脚本翻译之后都在 _jspService() 方法中;

      ② 代码脚本由于翻译到_jspService()方法中, 所以在_jspService()方法中的现有对象都可以直接使用

      ③ 还可以由多个代码脚本块组合完成一个完整的 java 语句。

      ④ 代码脚本还可以和表达式脚本一起组合使用, 在 jsp 页面上输出数据

    Demo:

   <%--1.代码脚本----if 语句--%>
<%int i = 13 ;
if (i == 12) {
%>
<h1>国哥好帅</h1>
<%
} else {
%>
<h1>国哥又骗人了! </h1>
<%
}
%>
<br>
<%--2.代码脚本----for 循环语句--%>
<table border="1" cellspacing="0">
<%
for (int j = 0; j < 10; j++) {
%>
<tr>
<td>第 <%=j + 1%>行</td>
</tr>
<%
}
%>
</table>
<%--3.翻译后 java 文件中_jspService 方法内的代码都可以写--%>
<%
String username = request.getParameter("username");
System.out.println("用户名的请求参数值是: " + username);
%>

    翻译对照:

    

四、JSP 中的三种注释

  1、HTML 注释

    格式:

<!-- 这是 html 注释 -->      只能注释 HTML代码片段

    HTML 注释会被翻译到 Java 源代码中,在 _jspService() 方法里,以 out.writer 输出到客户端,但是不会在页面上显示。

  2、Java 注释

    格式:

<%
// 单行 java 注释
/* 多行 java 注释 */
%>

    Java 注释会被翻译到 Java 源代码中,不会输出到客户端

  3、jsp 注释

    格式:

<%-- 这是 jsp 注释 --%>

    jsp 注释可以注释掉 jsp 页面中所有的代码。但是这种注释是在服务器端的注释,不会把数据发送给浏览器的,通过源代码不能查看到。

    

    JSP 中三种注释的比较:

JSP注释

Java注释

HTML注释

JSP页面

可见

可见

可见

Java代码

不可见

可见

可见

浏览器

不可见

不可见

可见

五、JSP 的内置对象

  jsp 中的内置对象,是指 Tomcat 在翻译 jsp 页面称为 Servlet 源代码后,内部提供的 九大对象,称为 内置对象

  在 jsp 页面中不需要获取和创建,可以直接使用的对象。

  

  jsp 一共有9个内置对象。

变量名 真实类型 作用
pageContext PageContext 当前页面共享数据,还可以获取其他八个内置对象(Servlet中没有此对象)
request HttpServletRequest 一次请求访问的多个资源(转发)
session HttpSession 一次会话的多个请求间
application ServletContext(唯一) 所有用户间共享数据
response HttpServletResponse 响应对象
page Object 当前页面(Servlet)的对象  this
out JspWriter 输出对象,数据输出到页面上
config ServletConfig Servlet的配置对象
exception Throwable 异常对象

 

六、JSP 四大域对象

  域对象是可以向 Map 一样存取数据的对象,四个域对象功能一样,不同的是它们对数据的存取范围。

  四个域对象分别是:

  

域对象 真实类型 存取范围
pageContext PageContextImpl类 当前 jsp 页面范围内有效(Servlet中没有)
request HttpServletRequest类 一次请求内有效
session HttpSession类

一个会话范围内有效

(打开浏览器访问服务器,知道关闭浏览器)

application ServletContext类

整个Web 工程范围呢都有效

(只要Web工程不停止,数据就在)

  虽然四个域对象都可以存取数据,但是在使用上是有优先顺序的。

  四个域在使用的时候,优先顺序分别是:它们从小到大的方位的顺序:

pageContext ====>>> request ====>>> session ====>>> application

七、JSP 中的 out 输出和 response.getWriter 输出的区别

    response 表示响应,经常用于设置返回给客户端的内容(输出)

    out 也是给用户做输出使用的。

    两个缓冲流工作原理:

    

       out 的 writer() 方法 和 print() 方法

             

    由于 jsp 翻译之后, 底层源代码都是使用 out 来进行输出, 所以一般情况下,我们在 jsp 页面中统一使用 out 来进行输出,避免打乱页面输出内容的顺序。  

    response.getWriter()和out.write()的区别:

      ① 在 Tomcat 服务器真正给客户端做出响应之前,会先找 response 缓冲区数据,再找out缓冲区数据。

      ② response.getWriter()数据输出永远在out.write()之前

    out.write() 输出字符串没有问题(出去其他如int,会先转化为char类型,可能乱码)
    out.print() 输出任意数据都没有问题(都转换成为字符串后调用的 write 输出)

    小结:在jsp 页面中,可以统一使用 out.print() 来进行输出。

八、jsp的常用标签

  1、jsp 静态包含

       作用:把其他的页面包含到当前页面中

    格式:

<%@ include file=""%> 
<%@ include file="/include/footer.jsp"%>

      file 属性指定要包含的 jsp 页面的路径;

       地址中第一个斜杠 / 表示为 http://ip:port/工程路径/ 映射到代码的 web 目录
     静态包含的特点:

      (1)静态包含不会翻译被包含的 jsp 页面。

      (2)静态包含其实是把被包含的 jsp 页面的代码拷贝到包含的位置执行输出。

  2、动态包含

    作用:动态包含会把包含的 jsp 页面单独翻译成 servlet 文件, 然后在执行到时候再调用翻译的 servlet 程序。 并把计算的结果返回。

       动态包含是在执行的时候,才会加载,所以叫动态包含。

    格式:

<jsp:include page=""></jsp:include> 动态包含

            page 属性是指定要包含的 jsp 页面的路径

      动态包含也可以向静态包含一样,把被包含的内容执行输出到包含位置

    动态包含的特点:

      (1)动态包含会把包含的 jsp 页面也翻译成为 java 代码

      (2)动态包含底层代码使用如下代码去调用被包含的 jsp 页面执行输出

          JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);

      (3)动态包含, 还可以传递参数

     Demo:

 <jsp:include page="/include/footer.jsp">
<jsp:param name="username" value="bbj"/>
<jsp:param name="password" value="root"/>
</jsp:include>

      动态包含的底层原理:

     

   两种包含的区别:

  

  静态包含   动态包含
是否生成 java 文件 不生成 生成
service 方法中的区别 把包含的内容原封拷贝到 service 中 JspRuntimeLibrary.include 方法
是否可以传递参数 不能 可以
编译次数 1 包含的文件 + 1
适用范围 适用包含纯静态内容(CSS,HTML,JS), 或没有
非常耗时操作。 或大量 java 代码的 jsp
包含需要传递参数。 含有大量 java代码

      静态包含应用较多。

九、JSP 动作标签

    JSP 动作标签是由 服务器(Tomcat)来运行的。

    动作标签语法:

<jsp: 动作名称  属性=属性值></jsp:动作名称>

  

  1、jsp 标签— 转发

    作用:处理请求转发操作

    不带参数格式:

<jsp:forward page="/scope2.jsp"></jsp:forward>

    page 属性设置请求转发的路径。注意:开始标签与结束标签之间不能有任何内容。

     带参数格式:

<jsp:forward page="NewFile.jsp">
<jsp:param value="18" name="age"/>
</jsp:forward>

    上面的 <jsp:include> 也是一个动作标签。

Java 之 JSP的更多相关文章

  1. java的JSP技术

    java的JSP技术 [toc] 1.JSP简介 Jsp技术是用来开发java web的页面显示的,所有MVC模型里面的视图层,所以视图层的开发 jsp不是编程语言,三个英文是java server ...

  2. java之jsp页面语法

    jsp页面相比静态页面html来说,就是多了一些脚本,利用这些脚本来动态地改变页面内容的显示. 1.JSP脚本写法 <% 这里写java代码; %> <%! JSP声明,用来声明变量 ...

  3. Java基础——JSP(一)

    一.JSP的由来 在很多动态网页中,绝大多部分内容是不变的,只有局部内容需要动态产生和改变.例如, 一个新闻的浏览次数,只有这个次数是动态改变的,而Servlet程序返回客户端的代码全是java程序动 ...

  4. JAVA记录-JSP内容

    JSP(JavaServer Pages )是什么? JavaServer Pages(JSP)是一种支持动态内容开发的网页技术它可以帮助开发人员通过利用特殊的JSP标签,其中大部分以<%开始并 ...

  5. Java 和 JSP 实现网站访问量统计 (刷新过滤)

    java 和 JSP 实现的统计网站访问量,不需要数据库,将数据存储在 指定位置的 txt 文件中,代码块分为两部分 首先, java 部分: import java.io.File; import ...

  6. Java EE JSP内置对象及表达式语言

    一.JSP内置对象 JSP根据Servlet API规范提供了一些内置对象,开发者不用事先声明就可使用标准变量来访问这些对象. JSP提供了9种内置对象: (一).request 简述: JSP编程中 ...

  7. 常见指令与功能介绍-java之JSP学习第二天(非原创)

    文章大纲 一.JSP 指令二.JSP 动作元素三.JSP 隐式对象四.JSP 客户端请求五.JSP 服务器响应六.JSP HTTP 状态码七.JSP 表单处理八.JSP 过滤器九.JSP Cookie ...

  8. 杂项-Java:JSP

    ylbtech-杂项-Java:JSP 1.返回顶部 1. JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它是由Sun Micros ...

  9. Java开源JSP标签库

    01displytag 与Struts结合使用最出名的一个tag主要是显示表格数据很漂亮.完善. 02cewolf tag 用来在web上显示复杂图形报表的一个jsp tag. 03Loading T ...

  10. java:JSP(JSPWeb.xml的配置,动态和静态导入JSP文件,重定项和请求转发,使用JSP实现数据库的增删改查实例)

    1.JSP的配置: <%@ page language="java" import="java.util.*" pageEncoding="UT ...

随机推荐

  1. docker 镜像制作(jupyter)

    docker pull centosdocker run -it -d --name test-centos1 centosdocker exec -it test-centos1 /bin/bash ...

  2. sqlserver cdc用法

    SELECT top(10)  * from (SELECT  sys.fn_cdc_map_lsn_to_time([__$start_lsn])  'addtime',* FROM cdc.dbo ...

  3. Qt 组合框QComboBox的定制

    转载:https://www.cnblogs.com/csuftzzk/p/qss_combobox.html 转载:https://www.bbsmax.com/A/E35pLgRK5v/ 转载:h ...

  4. CentOS7下安装Mariadb 10.3.17

    1. install lsb packagesudo yum install -y redhat-lsb 2.install net-tools packagesudo yum install -y ...

  5. 将pip源设置国内源

    windows (1)打开文件资源管理器(文件夹地址栏中) (2)地址栏上面输入 %appdata% (3)在这里面新建一个文件夹 pip (4)在pip文件夹里面新建一个文件叫做 pip.ini , ...

  6. LwIP应用开发笔记之七:LwIP无操作系统HTTP服务器

    前面我们实现了TCP服务器和客户端的简单应用,接下来我们实现一个基于TCP协议的应用协议,那就是HTTP超文本传输协议 1.  HTTP协议简介   超文本传输协议(Hyper Text Transf ...

  7. [LeetCode] 769. Max Chunks To Make Sorted 可排序的最大块数

    Given an array arr that is a permutation of [0, 1, ..., arr.length - 1], we split the array into som ...

  8. 在Django中显示操作数据库的语句

    需要在配置中加上这个 LOGGING = { 'version':1, 'disable_existing_loggers':False, 'handlers':{ 'console':{ 'leve ...

  9. JS系列:数据类型详细讲解

    ctrl+B加粗 ### 数据类型: - 1.number数字类型 NaN:not a number 不是一个数 ,但他是数字类型 isNaN:检测当前值是否不是有效数字,返回true代表不是有效数字 ...

  10. 【转】python测试框架--doctest

    转自https://my.oschina.net/lionets/blog/268542 doctest 是一个 Python 发行版自带的标准模块.有两种模式可供使用. ##1 doctest 的概 ...