一文搞定JSP的基础知识

JSP 全称 Java Server Pages,是一种动态网页开发技术JSP是一种 Java Servlet,通过结合 HTML、XHTML、XML以及嵌入 JSP 操作命令编写 JSP,主要实现 Java Wed 应用程序的用户界面显示。

1 工作原理

前言:在Tomcat中访问任何资源实际上都是在访问 Servlet。JSP实质上是一个 Servlet。Tomcat 服务器中的 web.xml 文件中配置了以 JSP 为后缀的 url-pattern ,服务器接收到 JSP 类型的文件,在第一次访问时,会通过 JspServlet 转化为一个 类文件,并编译成 class 文件。

2 生命周期

JSP的生命周期就是从创建到销毁的整个过程,类似 Servlet 生命周期,区别在于 JSP 生命周期还包括将 JSP 文件编译成 servelt;

  • 编译阶段

    servlet 容器编译 servelt 源文件,生成 servlet 类;

  • 初始化阶段

    加载与 JSP 对应的 servlet 类,创建其实例,并调用它的初始化方法;

  • 执行阶段

    调用与 JSP 对应的 servelt 实例的服务方法;

  • 销毁阶段

    调用与 JSP 对应的 servlet 实例的销毁方法,然后销毁 servlet 实例;

3 JSP语法

JSP 代码可分为两部分:

  1. 模板数据:即HTML代码;
  2. 元素:JSP 页面中的 java代码、JSP指令、JSP标签;

3.1 脚本

JSP 脚本指的是 JSP 页面中的 java 代码。JSP脚本必须使用 <% %> 括起来。JSP脚本有三种方式:

  1. <% %>:用于定义局部变量、编写语句;

  2. <%! %>:用于定义类或方法;

  3. <%= %>:表达式输出;用于输出各种类型变量,基本类型或对象;

  4. scriptlet 标签,该标签与 <% %> 有相同的功能;

    
        String s = "hello world";
        System.out.println(s);
    
    

3.2 注释

<%--JSP注释--%>

//java 行注释
/*java多行注释*/



<%--其中java和HTML注释会随JSP一起转译到类文件中--%>

3.3 指令

JSP指令用来设置整个 JSP 页面相关的属性,例如编码方式、文档类型等;语法格式为:

<%@directive attribute="value" %>

指令可以有多个属性,它们以键值对形式存在,并用逗号隔开;JSP 中有三种指令标签:


一文搞定JSP的基础知识_第1张图片
JSP指令标签
Ⅰpage指令

Page 指令时容器提供当前页面的使用说明。一个JSP页面可以包含多个Page指令。常用的 page 属性有:


一文搞定JSP的基础知识_第2张图片
page指令常用属性
Ⅱ include指令

include 指令用来包含其他文件。被包含的文件可以是 JSP 文件、HTML文件或文本文件。包含的文件就像是 JSP 文件的一部分,会被同时编译执行

语法格式: <% @include file="文件相对 URL 地址" %> 。指令中的文件名实际上是一个相对 URL 地址。如果没有给文件关联路径,JSP 编译器会默认在当前路径寻找。

静态导入

上述所说即为静态导入——将一个 JSP 文件的内容与另一个 JSP 文件内容拼接在一起,转化成一个类文件。会导致的问题:两个JSP文件中声明相同的java变量,会产生错误。

动态引入

导入的 JSP 文件会独立转化为一个类文件。动态导入属于JSP动作元素——动态包含。后面会讲述。

Ⅲ Taglib指令

JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。Taglib指令引入一个自定义标签集合的定义,包含库路径、自定义标签。

语法格式:<%@ taglib uri="标签库位置" prefix="指定标签库的前缀" %>

4 JSP动作元素

JSP动作元素是 JSP 内置的预定义函数,是对JSP功能的抽象和封装。

常见的动作元素

一文搞定JSP的基础知识_第3张图片
JSP常见动作元素

所有的动作元素都有两个属性:

  • id属性:动作元素的唯一标识。可由 PageContext 调用;
  • scope属性:识别动作元素的生命周期。scope属性定义了相关联 id 对象的寿命;

4.1

用于包含静态或动态的文件。与 include 指令不同,如果包含的文件为 JSP,那该 JSP 会先转化为类文件,再写入。


<%--
    page:包含页面的相对url地址;
    flush:在包含资源前是否刷新缓存区;
--%>

4.2

把请求转到另一个页面;

< jsp:forward page="相对URL地址" />
<%--传递参数,请内嵌param元素--%>

    

相当于 servlet 中调用 request.getRequestDispatcher("url").forward(req,resp);

4.3 JavaBean

JavaBean是一个普通的java类,也称为简单java对象——POJO(Plain Ordinary Java Object),是Java程序设计中一种设计模式,是一种基于 Java 平台的软件组件思想。

JavaBean遵循特定的写法,通常有以下的规则:

  • 有无参的构造函数;
  • 成员属性私有化;
  • 封装的属性如果需要被外部操作,必须编写 public 权限的 setter、getter 方法;

好处——封装、重用、可读

  • 作为数据传递的载体,在 Java 端和 Web 页面之间传递,实现界面和 Java 代码分离;
  • 解决代码重复编写,减少冗余;
Ⅰ JavaBean的三种行为元素
行为元素 描述
< jsp:useBean > 在JSP页面中查找JavaBean对象或实例化JavaBean对象
< jsp:setProperty > 设置JavaBean的属性
< jsp:getProperty > 获取JavaBean的属性
Ⅱ < jsp: useBean >
<%--(1)未使用 JSP 行为元素--%>
<% @page import="pojo.User" %>
<%
    User user = new User();
    user.setName("name");
%>
<%=user.getName()%>

<%--(2)使用 JSP 行为元素--%>

<%
    User user = new User();
    user.setName("name");
%>
<%=user.getName()%>

注意:使用 JavaBean时,POJO类中需要定义无参构造函数;如果没有无参构造函数,使用 JavaBean 动作元素会错误。原因是因为:内部在实例化对象时使用无参构造函数

Ⅲ < jsp:setProperty >

设置 JavaBean 中私有属性的动作元素。语法如下:


案例:获取表单数据

<%--login.jsp--%>

    用户名:
密码:
年龄:
<%--main.jsp--%>




//pojo.User.java
public class User{
    private String name;
    private String password;
    private int age;
}

从上述的案例可发现,这三处的属性名需要一致。具体的原理是通过反射机制,可查看编译后的 java 文件。

introspecthelper(_jspx_page_context.findAttribute("person"), "name", request.getParameter("name"), request, "name", false);
Ⅳ < jsp:getProperty >

获取 JavaBean 类的属性值。语法如下


5 内置对象

JSP 引擎将 JSP 文件转化为对应的 JspServlet 时,会创建9个与 web 开发相关的对象,便于在编写 JSP 时直接使用。JSP 内置对象有9个,分别为:


一文搞定JSP的基础知识_第4张图片
JSP内置对象

PageContext对象

pageContext 对象是javax.servlet.jsp.PageContext类的实例,代表整个 JSP 页面,主要作用是访问页面信息。通过pageContext 可以获取其他的8个内置对象。

四个域对象

  1. Request:一次请求中保存属性,服务器跳转有效,浏览器跳转无效;
  2. Session:一次会话范围中保存属性,关闭浏览器即无效
  3. pageContext:一个页面中保存属性,页面跳转无效
  4. ServletContext:曾哥服务器中保存属性,所有用户都可以使用;

以上域对象都有以下三个方法:

  • setAttribute(String name,Object o):设置属性
  • getAttribute(String name):获取属性
  • removeAttribute(String):移除属性

PageContext对象有所不同。重载了上述三个方法:

  • setAttribute(String name,Object o,int scope):在指定域设置属性
  • getAttribute(String name,int scope):在指定域获取属性
  • removeAttribute(String,int scope):在指定域移除属性

其中,scope 参数是 pageContext 中封装域对象的静态变量,当想在指定的域中操作属性,调用对象的 scope 变量。如若不指定,则默认是 page。

  • PageContext.APPLICATION_SCOPE
  • PageContext.SESSION_SCOPE
  • PageContext.REQUEST_SCOPE
  • PageContext.PAGE_SCOPE

PageContext 中还存在一个方法:findAttribute(String name);。查找各域的属性,查找顺序为:page --> request --> session --> application 。

6 EL表达式

EL(Expression Language) 表达式语言,用于读取数据、运算或逻辑表达式,并显示内容。EL表达式能够便捷地读取数据。

EL表达式格式:${expr}

6.1 获取域属性

获取域属性:未指定作用域时,查找顺序为:page --> request --> session --> application,直到找到为至。若均未找到,返回的是空字符串,而不是null;

当然,除了指定域获取属性,还可以获取 JavaBean 对象的内容。

<%--未指定作用域查找--%>
${属性名}
<%--指定作用域查找--%>
${pageScope.属性名}
${sessionScope.属性名}
${requestScope.属性名}
${applicationScope.属性名}
<%--获取JavaBean对象数据--%>
${对象名.属性/方法}

6.2 获取集合数据

<%--读取list集合数据--%>
${list[index]}
<%--如果list存储的是对象--%>
${list[index].对象名}

<%--读取map集合数据--%>
${map[key]}
${map.key.对象名}
${map[key].对象名}

问题:在IDEA中创建泛型内容时,出现如下错误:

一文搞定JSP的基础知识_第5张图片
错误

原因是:编译版本较低不支持泛型特性。但是,根据排查,项目配置的java编译版本和JDK版本为1.8,原来Tomcat服务器中编译 JSP 的版本配置为低版本。

解决方法:在Tomcat服务器的配置文件中添加 JSP 编译版本设置:


    jsp
    org.apache.jasper.servlet.JspServlet
    
        fork
        false
    
    
        xpoweredBy
        false
    
    3
    
        compilerSourceVM
        1.8
    
    
        compilerTargetVM
        1.8
    

6.3 表达式操作

在EL表达式中可以进行运算、逻辑运算表达式,并返回显示结果。在EL表达式中允许以下操作符

一文搞定JSP的基础知识_第6张图片
EL表达式运算符

6.4 EL内置对象

一文搞定JSP的基础知识_第7张图片
EL表达式内置对象

以上对象存储数据的结构均为Map集合,其中,paramValues 对象和 headerValues 对象中key对应的 value 值使用一个 String[] 数组,用于保存多个参数值。比如,提交数据时,含有多选框数据。

补充:

  1. 获取Cookie时,${cookie.key} 获取的是一个 Cookie 对象;如果想获取Cookie下的属性,请使用 ${cookie.key.property}。其中,key 为创建Cookie对象时的key(如下)。

    Cookie c = new Cookie(key,value);
    

7 JSTL标签库

JSTL全称 JSP Standard Tag Library,JSP标准标签库。JSTL作为基本的标签库,提供了一系列的 JSP 标签,能够实现基本的功能:集合的遍历、数据的输出、字符串处理、数据格式化等;

JSTL使用XML标签格式的语句代替逻辑代码,可以提升 JSP 页面的逻辑代码编码效率,使得JSP页面整洁、易读;

标准标签库种类

  1. 核心标签
  2. 格式化标签
  3. SQL标签
  4. XML标签
  5. JSTL函数

7.1 使用步骤

  1. 下载标准标签库,解压并将 standard.jar 和 jstl.jar 文件拷贝到 /WEB-INF/lib 目录下,在项目中jar包,并将所需的 tld 文件复制到 lib 目录;

  2. 在 web.xml 文件中配置标签库信息;

    
        
            http://java.sun.com/jsp/jstl/core
            /WEB-INF/c.tld
        
        
            http://java.sun.com/jsp/jstl/core-rt
            /WEB-INF/c-1_0-rt.tld
        
    
    
  3. 在 JSP 页面上使用 taglib 指令引用标签库;完成以上步骤就可以使用JSTL标签库了;

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

7.2 core标签库

< c:out >

在 JSP 中显示数据,就像 <%= ... %>

属性名 是否支持EL 属性类型 描述
value true Object 指定要输出的内容
escapeXml true Boolean 指定是否将>、<、&、'、" 等特殊字符进行HTML编码转换后再进行输出。默认为true
default true Object Value值为null时锁输出的默认值
< c:set >

用于保存数据。var 属性操作Integer、Double、String等可以直接操作的数据,target 属性操作 JavaBean 或 Map 对象的数据。

属性名 是否支持EL 属性类型 描述
value true Object 指定属性的值
var false String 用于要指定设置作用域属性的名称
scope false String 用于指定属性所在的作用域
target true Object 用于指定要设置属性的对象
property true String 用于指定对象的属性名称
<%--两种设置数据的方式--%>


<%
    String a = null;
    pageContext.setAttribute("a",a);
%>



< c:remove >

删除域范围的属性。var 表示要删除的属性或对象;scope 表示属性所在作用域。


< c:catch >

捕获标签内语句的产生的异常。var 属性用来存储错误信息的变量。


    <% int i = 10/0;%>

< c:if>

用于判断表达式的值,相当于 if 语句。

属性名 是否支持EL 属性类型 描述
test true boolean 条件表达式,true则处理标签内语句
var false String 将条件表达式的结果保存到变量中
scope false String var 属性的作用域
< c:choose>< c:when>

多条件判断语句,相当于 if ... else if ... else ... 语句。


    
        执行语句 ...
    
    
        执行语句 ...
    
    
        执行语句 ...
    

< c:forEach>

循环标签,相当于 java 中 while 和 for 循环。

属性名 是否支持EL 属性类型 描述
var false String 当前条目的变量名称
items true 任意类型 要被循环的信息
begin true int 开始元素,以0开始
end true int 结束元素,以0开始
step true int 每一次迭代的步长
varStatus false LoopTagStatus 代表循环状态的变量名称

varStatus为存储当前迭代信息的变量,其具有以下属性:

  • index:当前对象的索引值,从0开始;
  • count:记录遍历对象的个数,从1开始;
  • current:记录当前对象;
  • last:是否第一个,返回布尔值;
  • first:是否最后一个,返回布尔值;
  • begin:开始遍历位置,标签中未指定 begin ,该属性为空字符串;
  • end:结束遍历位置,标签中未指定 end,该属性为空字符串;
  • step:步长;
< c:forTokens>

该标签类似 String 类中的 split() 和 for 循环的一种集合。它与 都含有 begin、end、step、items、var、varStatus属性,不同的是 多了 delims 属性, items 属性接收是字符串,items 的字符串会按 delims 字符进行分割并遍历。

<%--代码--%>

    ${str} 
<%--输出结果--%> Hello World I am from China I love China
< C:import>

类似 JSP 中的静态导入 <% @include file=""> 和动态导入

属性

  • URL:导入资源的URL,可以是相对路径和绝对路径,亦可以其他主机资源;
  • context:访问当前web应用的其他资源,以 / 开头;
  • var:保存导入文件的内容,String 类型;
  • scope:保存作用域,默认为 page;
  • charEncoding:引入数据的字符编码,默认 ISO-8859-1;
  • varReader:保存导入文件的内容,java.io.Reader对象变量;

导入外部资源

导入内部资源

< c:param>
  • 可嵌套在 URL 地址标签后,为 URL 地址附加参数;

  • 自动对嵌套的参数进行 URL 编码。


< c:url>

将 URL 格式化一个字符串,然后存储到一个变量中。该标签知识用于调用 response.encodeURL() 方法的一种方法。

属性名 是否支持EL 属性类型 描述
value true String URL 字符串
var false String 存储 URL 字符串的变量名
scope false String 保存 URL 的作用域
context true String web应用的名称

案例


    

点击进入百度
< c:redirect>

通过自动重写 URL 来讲浏览器重定向到一个新的 URL 。可以配合 param 标签使用;实现页面跳转和数据传递。

属性名 是否支持EL 属性类型 描述
url true String 指定要转发或重定向的目标 URL
context true String 当使用相对路径重定向到同一个服务器下的其他web应用资源时,context为其他web应用的名称

简单用法


    

除了 core 标签库之外,JSP 中还存在其他标签库,比如:格式化标签库、SQL标签库、XML标签库、JSTL函数库等,以及自定义标签内容等,后续有所使用再学习。

参考文章

  • 菜鸟教程-JSP教程
  • java3y - GitHub
    可关注大佬微信公众号:java3y

你可能感兴趣的:(一文搞定JSP的基础知识)