JSP基础知识学习详解!

12 篇文章 0 订阅
6 篇文章 0 订阅

JSP基础知识学习

一、JSP是什么

JSP(全称JavaServer Pages)是由[Sun](https://baike.baidu.com/item/Sun Microsystems)公司主导创建的一种动态网页技术标准。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。JSP文件在运行时会被其编译器转换成更原始的Servlet代码。

二、JSP原理

说到原理,我们就会思考JSP是怎么执行的!以IDEA为例,我们使用tomcat启动web服务时,会在电脑的 .IntelliJIdea文件里生成一个tomcat文件,里面会有一个它的工作目录work,里面会生成一个org包,会发现里面会有一个所访问的jsp对应的Java文件和class文件。如下图:

image-20220720110139878

image-20220720110442791

在我的电脑盘上目录为:

C:\Users\86183\.IntelliJIdea\system\tomcat\Tomcat_10_0_181_JavaWeb-jsp-maven\work\Catalina\localhost\JavaWeb_jsp_maven_war\org\apache\jsp

可见,JSP最终都会被转换为一个JAVA类,浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!

工作原理图如下:

image-20220720103415515

  1. 客户端通过浏览器向服务器发出请求,请求访问的JSP文件。
  2. 服务器根据接收到的客户端的请求来加载相应的JSP文件。
  3. Web服务器中的JSP引擎会将被加载的JSP文件转化为Servlet文件(.java)。
  4. 将生成的Servlet文件编译成Class文件,Servlet容器(引擎)会像处理其他Servlet一样处理它。
  5. 服务器执行这个Class文件。即,执行jspService()方法处理客户端的请求。对于每一个请求,JSP容器都会创建个新的线程处理它。
  6. 最后服务器将执行结果发送给浏览器进行显示。

注意:JSP引擎本身也是一个servlet!

分析一下服务器最终响应的index_jsp.java

  • 该Java类继承的是HttpJspBase(它继承的就是HttpServlet)

    image-20220720111256406

  • 该java类里面就有servlet的三个生命周期方法

    //初始化
    public void _jspInit() {
      }
    //销毁
    public void _jspDestroy() {
      }
    //service()处理客户端请求阶段
    public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response){
    
  • 该java类的内置对象

    final jakarta.servlet.jsp.PageContext pageContext;  //页面上下文
    jakarta.servlet.http.HttpSession session = null;  //session
    final jakarta.servlet.ServletContext application;  //application
    final jakarta.servlet.ServletConfig config;        //配置
    jakarta.servlet.jsp.JspWriter out = null;          //out输出
    final java.lang.Object page = this;                  //当前页面 
    servlet.http.HttpServletRequest request;          //请求
    servlet.http.HttpServletResponse response;          //响应
    
  • 输出页面前增加的代码

    //设置响应的页面类型
    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;
    

所以,JSP本质就是一个servlet!

三、JSP基础语法

四个基本语法

<%= %>表达式
<%  %>脚本
<%! %>声明
<%----%>注释

JSP表达式

<%--1.JSP表达式
作用:将程序的结果输出到客户端
格式:<%= 变量或表达式%>
--%>
<%= new java.util.Date()%>

JSP脚本

<%--2.JSP脚本片段
格式:<%  %>
作用范围:都是编译在那个tomcat项目index_jsp的  _jspService()方法里
--%>
<%--用法1--%>
<%
    int sum =0;
    for (int i = 0; i < 100; i++) {
        sum+=i;
    }
    out.println("<h1>sum="+sum+"</h1>");
%>
<%--用法2--%>
<%
    int x = 100;
    out.println(x);
%>
<h1>这是HTML</h1>
<%
    //一样可以输出上面定义的x变量
    out.println(x);
%>
<%--用法3--%>
<%
    for (int i = 0; i < 10; i++) {
%>
<h2>我是html <%= i%></h2>
<%
    }
%>

JSP声明

<%--3.JSP声明
格式:<%! %>
作用范围:是编译在那个tomcat项目index_jsp的类上面 不在_jspService()方法里面的
--%>
<%!
    static {
        System.out.println("load Servlet!");
    }
    int globalVar = 99;
    private void play(){
        System.out.println("进入了play方法!");
    }
%>

JSP注释

<%--4.JSP注释
格式:<%-- -->
不同:与html的注释相比,JSP的注释不会在客户端显示,html的会!
--%>
<!--我是html注释-->
<%--我是jsp注释--%>

四、JSP指令

指令是向容器提供指示和说明,告诉容器如何处理JSP处理的请求和响应。有三种类型指令标签:

<%@ page args... %>     //定义页面相关属性,如脚本语言,错误页面和缓冲要求。
<%@ include args... %>  //在编译阶段包括文件
<%@ taglib args... %>   //声明页面中使用的包含自定义操作的标签库

page 指令

page指令用于向容器提供说明。这些说明涉及当前的JSP页面。可以在JSP页面的任何位置编写page指令。按照惯例,page指令被编码在JSP页面的顶部。

  • 基本语法
<%@ page 属性="值" %>
对应的jsp动作语法为:
<jsp:page 属性 = "值" />
  • 常用属性
属性说明
errorPage定义另一个报告Java未检查运行时异常的JSP的URL。
import指定JSP中使用的包或类的列表,就像Java的import语句一样。
contentType定义字符编码方案。
info定义可以使用servlet的getServletInfo()方法访问的字符串。
extends指定生成的servlet必须扩展的超类。

更多详情了解可看这

include 指令

include指令用于在编译阶段包括一个文件。这个指令告诉容器在编译阶段将其他外部文件的内容合并到当前JSP文件中。可在JSP页面的任何位置使用include指令进行编码 。

  • 最常用的属性用法
<%@ include file = "relative url" >
对应的jsp动作语法为:
<jsp:include file = "relative url" >
<%--两者不同:指令是把文件合并为一个了,而jsp标签是拼接了文件--%>

taglib 指令

SP API允许自定义的JSP标签,如:HTML或XML标签,标签库是一组实现自定义行为的用户定义标签。taglib指令声明JSP页面使用一组自定义标签,标识库的位置,并提供了在JSP页面中标识自定义标签的方法。

  • 唯一属性用法
<%@ taglib uri="uri" prefix = "prefixOfTag" >
对应的jsp动作语法为:
<jsp:taglib uri = "uri" prefix = "prefixOfTag" />

这里,uri属性值解析为容器理解的位置,并且prefix属性通知容器什么位置的标记是自定义操作。

五、JSP内置对象

了解内置对象

JSP提供了由容器实现和管理的内置对象,也可以称之为隐含对象。由于JSP使用Java作为脚本语言,所以JSP将具有强大的对象处理能力,并且可以动态创建Web页面内容。Java语法在使用一个对象前,需要先实例化这个对象,非常的繁琐。JSP为了简化开发,提供了一些内置对象,用来实现很多JSP应用。在使用JSP内置对象时,不需要先定义这些对象,直接使用即可

九大内置对象

  1. HttpServletRequet类的Request对象:代表请求对象,主要用于接受客户端通过HTTP协议连接传输服务器端的数据。
  2. HttpSevletResponse类的Response对象:代表响应对象,主要用于向客户端发送数据。
  3. JspWriter类的out对象:主要用于向客户端输出数据。
  4. HttpSession类的session对象:主要用来分别保存每个月的信息与请求关联的会话;会话状态的维持是web应用开发者必须面对的问题。
  5. ServletContext类的application对象:主要用于保存用户信息,代码片段的运行环境;它是一个共享的内置对象,即一个容器中的多个用户共享一个application,故其保存的信息被所有用户所共享
  6. PageContext类的PageContext对象:管理网页属性,为jsp页面包装页面的上下文,管理对属于jsp的特殊可见部分中已经命名对象的访问,它的创建和初始化都是由容器来完成的
  7. ServletConfig类的Config对象:代码片段配置对象,标识Servlet的配置。
  8. Object类的Page对象:处理jsp页面,是object类的一个实例,指的是jsp实现类的实例。
  9. Exception对象:处理jsp文件执行时发生的错误和异常,只有在错误页面里才使用,前提是在页面指令里要有isErrorPage=true。

四大作用域

  • page范围:只在一个页面保留数据(javax.servlet.jsp.PageContext(抽象类)),它的有效范围仅限于用户请求的当前页面。
  • request范围:只在一个请求中保存数据(javax.servlet.httpServletRequest),一个请求可以包含多个页面。它的有效范围是这个一个请求。请求转发注意:
    1. 转发是服务器行为,而重定向是客户端行为。
    2. 无论在服务器上如何转发,浏览器地址栏中显示的仍然是最初那个Servlet的地址。
  • Session范围:在一次会话中保存数据,仅供单个用户使用(javax.servlet.http.HttpSession),它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。
  • Application范围:在整个服务器中保存数据,全部用户共享(javax.servlet.ServletContext),它的有效范围是整个应用。整个应用是指从应用启动,到应用结束。

特殊内置对象 PageContext

pageContetx对象是jsp页面中所有对象功能的最大集成着,使用他可以访问所有的jsp内置对象。pageContext对象的创建和初始化都是由容器来完成的,JSP页面中可以直接使用pageContext对象。

PageContext方法:

方法名说明
forward重定向到另一页面或Servlet组件
getAttribute重定向到另一页面或Servlet组件
findAttribute按范围搜索指定名字的属性
removeAttribute删除某范围中指定名字的属性
setAttribute设定某范围中指定名字的属性值
getException返回当前异常对象
getRequest返回当前请求对象
getResponse返回当前响应对象
getServletConfig返回当前页面的ServletConfig对象
getSession返回当前页面的会话对象
getServletContext返回所有页面共享的ServletContext对象

九大内置对象更详细了解

六、JSP动作、JSTL标签与EL表达式

  1. jsp动作

    与JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用。JSP动作元素是用XML语法写成的,利用JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。

    JSP动作元素只有一种语法,它符合XML标准:

    <jsp:action_name(动作名称) attribute(属性)="value(值)" />
    
    • JSP规范定义了一系列的标准动作,它用JSP作为前缀,可用的标准动作元素如下:image-20220721170208475
    • 所有动作都有常见的两个属性:id属性和scope属性。
      • **id属性:**id属性是动作元素的唯一标识,可以在JSP页面中引用。动作元素创建的id值可以通过PageContext来调用
      • **scope属性:**该属性用于识别动作元素的生命周期。 id属性和scope属性有直接关系,scope属性定义了相关联id对象的寿命。 scope属性有四个可能的值: page, request, session, 和 application。对应着四大作用域。

    具体的动作方法,属性这些可以上菜鸟编程学习:https://www.runoob.com/jsp/jsp-actions.html

  2. jstl标签

    什么是jstl标签呢?

    JSTL(JSP标准标签库)是一个JSP标签集合,它封装了JSP应用的通用核心功能。支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。

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

    • core 核心标签 (重点)
    • fmt 格式化标签**(了解)**
    • SQL 标签
    • XML 标签
    • JSTL 函数

    如何使用呢?

    • 导包

      在pom.xml文件引入这两个依赖

      <!-- JSTL表达式 依赖 -->
      <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.1.2</version>
      </dependency>
      <!-- standard 标签库 -->
      <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
      </dependency>
      
    • 在使用标签的JSP页面中使用taglib指令导入标签库;

      <%@ taglib prefix="引用的标志" uri="标签库相应的uri" %>
      <!--
      prefix=" ":指定标签库的前缀,这个前缀可以随便给值,但大家都会在使用core标签库时指定前缀为c;
      uri=" ":指定标签库的uri,可以让JSP找到标签库的描述文件;
      -->
      

    !注意:报tomcat异常–java.lang.ClassNotFoundException: org.apache.taglibs.standard.tlv.JstlCoreTLV。是由于tomcat服务器的原因,通过maven导入的jstl和standard包可能并没有被打包进入tomcat下web应用(即webapps)的WEB-INF\lib目录下,所以要手动复制过去!

    core 核心标签库

    core标签库是最常用的标签库,含有很多java常用关键字对应标签,引用语法如下:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
    1. out、set与remove标签(存取删)

      <c:out value=”${aaa}” default=”xxx”/>当${aaa}不存在时,输出xxx字符串
      <c:set var=”a” value=”hello” scope=”session”/>在session中添加name为a,value为hello的数据。默认scope为page
      <c:remove var=“a” scope=”page”/>删除pageContext中name为a的数据 。默认是删除所有
    2. if标签、choose、when与otherwise标签(判断)

      <!-- if标签等价于java里面的if,test属性为boolen类型,为true的话则执行下面的语句-->
      <c:set var="a" value="aaa"/>
      <c:if test="${ a }">
      	<c:out value="${ a }"/>
      </c:if>
      
      <!-- choose标签等价于java里面的switch,when和otherwise为choose的子标签,相对于case和default-->
      <c:set var="score" value="${param.score}"/>
      <c:choose>
      	<c:when test="${score > 100 || score < 0}">错误的分数:${score }</c:when>
      	<c:when test="${score >= 90 }">A级</c:when>
      	<c:when test="${score >= 80 }">B级</c:when>
      	<c:when test="${score >= 70 }">C级</c:when>
      	<c:when test="${score >= 60 }">D级</c:when>
      	<c:otherwise>不及格</c:otherwise>
      </c:choose>
      
    3. forEach(迭代)

      forEach就是循环标签,有两种使用方式:

      • 使用循环变量,指定开始和结束值,类似for(int i = 1; i <= 10; i++) {};
      <c:set var="sum" value="0" />  
      <c:forEach var="i" begin="1" end="10" step ="1">  <!--相当于for(int i = 1; i <= 10; i++)-->
      	<c:set var="sum" value="${sum + i}" />
      </c:forEach>
      <c:out value="sum = ${sum }"/>
      
      • 循环遍历集合,类似for(Object o : 集合);
      <%
      	List<String> names = new ArrayList<String>();
      	names.add("张三");
      	names.add("李四");
      	names.add("王五");
      	pageContext.setAttribute("names", names);
      %>
      <c:forEach var="item" items="${ names }">
      	<c:out value="${item.key }: ${item.value }"/><br/>  <!--相当于for(String item : names)-->
      </c:forEach>
      
    4. param、redirect和url标签

      <c:param name=“username” value=“abc”/>用来给包含或重定向的页面传递参数
      <c:redirect url=“url”/ >重定向至一个新的URL.
      <c:url value=“url” var=“a” scope=“request”/>使用可选的查询参数来创造一个URL,然后赋值给变量a.范围为request

    fmt 格式化标签

    JSTL格式化标签用来格式化并输出文本、日期、时间、数字。引用格式化标签库的语法如下:

    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    
    1. 格式化时间:

      <%
      	double d1 = 1.1;
      	pageContext.setAttribute("d1", d1);
      %>
      <fmt:formatNumber value="${d1 }" pattern="0.00"/><br/>
      

      pattern属性可以让您在对数字编码时包含指定的字符。下面列出了这些字符:

      image-20220722113920798

    2. 格式化数字:

      <%
      	Date date = new Date();
      	pageContext.setAttribute("d", date);
      %>
      <fmt:formatDate value="${d}" pattern="yyyy-MM-dd HH:mm:ss"/>  <!--pattern与上面格式化数字类同,具体的一些日期字符描述自行上网学习-->
      

    其他几个内容的格式化标签可自行上网学习:推荐菜鸟编程

  3. el表达式

    EL的介绍:

    EL(Expression Language) 是表达式语言,为了使JSP写起来更加简单 ,是一种在JSP页面获取数据的简单方式(只能获取数据,不能设置数据),在JSP2.0时引入。

    EL语法:

    所有EL表达式的格式都是以“${}”表示,可获取JSP页面任何静态部分的表达式的值。

    EL获取数据:

    !只能从四大域中获取属性

    • 属性值默认在page范围查找,然后依次在request、session、application范围查找。例如,${userinfo}代表获取变量userinfo的值。

    • 用指定域作为前缀获取数据表示属于哪个范围的变量,提高查找速率。例如:${ pageScope. userinfo}表示访问page范围中的userinfo变量。

      <%
         pageContext.setAttribute("yg","宇哥1");
         request.setAttribute("yg","宇哥2");
         session.setAttribute("yg","宇哥3");
         application.setAttribute("yg","宇哥4");
      %>
      <%--默认获取域为page--%>
      <h2>${yg}</h2>
      <%--指定域获取--%>
      <hr>
      <h2>${pageScope.yg}</h2>
      <h2>${requestScope.yg}</h2>
      <h2>${sessionScope.yg}</h2>
      <h2>${applicationScope.yg}</h2>
      

      输出结果:image-20220722145757340

    EL 中的运算符

    • 常用运算符

      • 算术运算符:+、-、*、/、%(不支持++、–)
      • 关系运算符:==、!=、>、>=、<、<=
      • 逻辑运算符:!、&&、||、not、and、or
      • 条件运算符:?:
      • 取值运算符:[]、点号
    • empty运算符

      用法为${empty 变量},结果为布尔值。

      • 对于没有定义的变量,结果为true。
      • 对于null,结果为true。
      • 对于字符串空串,结果为true。
      • 对于没有元素的数组或集合,结果为true。

    EL 总结

    • EL表达式不能出现在Java代码块、表达式块等JSP动态代码部分
    • EL只能从四大域属性空间中获取数据(pageContext、request、session、application)
    • EL不会抛出空指针异常,只会不显示
    • EL不会抛出数组越界异常,只会不显示

七、JSP JavaBean

什么是javabean?

是一种JAVA语言写成的可重用组件,在JSP的开发中可以使用JavaBean减少重复代码,使整个JSP代码的开发更简洁。它本质就是一个实体,遵循着特定的写法:

  • 必须有一个无参构造函数
  • 属性必须私有化
  • 私有化的属性必须有public类的get/set方法

属性名称符合这种模式,其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性。

javabean示例:

//people实体类
public class people {
    
    //属性私有化
    private int id;
    private String name;
    private int age;

    //无参构造
    public people() {
    }

    //有参构造
    public people(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    //get/set方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
    //重写toString方法用于调写
    @Override
    public String toString() {
        return "people{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

JSP 中JavaBean的使用

对应于JavaBean,有以下三个JSP标签使用:

  • useBean标签:用于在JSP页面中查找或实例化一个JavaBean组件。
  • setProperty标签:用于在JSP页面中设置一个JavaBean组件的属性。
  • getProperty标签:用于在JSP页面中获取一个JavaBean组件的属性。

对应着Java里面的new一个类,然后使用类里面的set方法对设置属性的值,再使用类里面的get方法去获得属性的值。

示例用法:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%--id 为bean的名字; class 为自己编写的JavaBean实体类; scope 为bean的作用域--%>
<jsp:useBean id="people" class="com.yg.pojo.people" scope="page" />

<%--name 为useBean的id; property 为JavaBean实体类的属性; value 为设置属性的值--%>
<jsp:setProperty name="people" property="id" value="1" />
<jsp:setProperty name="people" property="name" value="宇哥" />
<jsp:setProperty name="people" property="age" value="18" />

<%--name 为useBean的id; property 为JavaBean实体类的属性;--%>
<jsp:getProperty name="people" property="id" />
<jsp:getProperty name="people" property="name" />
<jsp:getProperty name="people" property="age" />

</body>
</html>

useBean标签的执行原理

对于这个对象是怎么实例化出来的呢?我们肯定很好奇,我们打开前面 JSP原理 所提到的项目启动后所生成的jsp转换为java的那个文件,即目录:“C:\Users\86183.IntelliJIdea\system\tomcat\Tomcat_10_0_181_JavaWeb-jsp-maven\work\Catalina\localhost\JavaWeb_jsp_maven_war\org\apache\jsp”。查看一下useBean的原理,在_jspService()方法中可以看到people对象的创建过程,如下所示:

com.yg.pojo.people people = null;
people = (com.yg.pojo.people) _jspx_page_context.getAttribute("people", jakarta.servlet.jsp.PageContext.PAGE_SCOPE);
if (people == null){
  people = new com.yg.pojo.people();
  _jspx_page_context.setAttribute("people", people, jakarta.servlet.jsp.PageContext.PAGE_SCOPE);
}

可以看到**<jsp:useBean id=“people” class=“com.yg.pojo.people” scope=“page” />**的执行原理就是:首先在指定的域范围内查找指定名称的JavaBean对象,如果存在则直接返回该JavaBean对象的引用,如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。

总结:

以上就是对于JSP中JavaBean的基本内容,学会三大JSP标签的使用即可掌握!JavaBean一般和数据库做字段映射(ORM) ,往往都是在操作数据库中用于使用!

ORM:对象关系映射

  • 表---->类
  • 字段---->属性
  • 行记录---->对象

本次JSP的基础学习就到这了。文章内容是我个人参考多篇文章及视频的理解,有个别错误地方欢迎大家指出纠正,谢谢!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值