9-JSP

JSP原理

JSP本质上跟Servlet是一样的,可以看作是Servlet的扩展。

JSP页面包括HTML标签和JSP标签。相比Servlet,JSP更容易维护,因为我们可以分离设计和开发。JSP提供了额外的特性,比如Expression Language,、Custom Tags等等

在这里插入图片描述
JSP经过 JSP translator 会变为Servlet(java文件)。JSP translator是web服务器的一部分。这个java文件会被编译器编译为class文件。之后会按照Servlet流程,像初始化、提交响应、销毁等等

启动tomcat,进入JSP页面,然后我在主机C:\Users\Bi\AppData\Local\JetBrains\IntelliJIdea2021.2\tomcat\05551e6e-aedf-4778-b8d6-655f016681e2\work\Catalina\localhost\ROOT\org\apache\jsp,找到了被编译好的java和class文件,这是idea创建的tomcat工作空间。

在这里插入图片描述

打开这个java文件,我们会发现这个类继承了HttpJspBase,而HttpJspBase又继承了HttpServlet
在这里插入图片描述

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports

此外,我们还可以发现初始化、销毁以及Service操作,以及请求和响应
在这里插入图片描述

一些内置对象与赋值

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;

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中写的HTML代码,会被逐行输出
在这里插入图片描述

因此对于jsp,会被转为一个Servlet java文件,文件中的类继承HttpJspBase,创建了很多对象和方法。此外对于jsp中的HTML代码,会被以out.write的形式输出到前端上,而对于java代码,则会原封不动的输出,因此java代码甚至可以直接使用现成的创建好的对象,比如application等

JSP基础语法和指令

依赖

   <!--Servlet依赖-->
   <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>2.5</version>
   </dependency>
   <!--jsp依赖-->
   <dependency>
       <groupId>javax.servlet.jsp</groupId>
       <artifactId>javax.servlet.jsp-api</artifactId>
       <version>2.3.3</version>
   </dependency>
   <!--standard标签库-->
   <dependency>
       <groupId>taglibs</groupId>
       <artifactId>standard</artifactId>
       <version>1.1.2</version>
   </dependency>
   <!--jstl表达式依赖-->
   <dependency>
       <groupId>javax.servlet.jsp.jstl</groupId>
       <artifactId>jstl-api</artifactId>
       <version>1.2</version>
   </dependency>

jstl包有时候即使导入进来,存在于本地仓库中,但在项目发布时仍然报错,有可能是Tomcat问题,发布时没有把jar包带上。因此可以把此jar包拷贝到Tomcat的lib目录下即可

JSP语句

jsp注释
html注释会被输出到前端去,而jsp注释不会

<%--我是jsp注释--%>
<!--我是HTML注释-->

jsp表达式
在java代码中,是out.print( new java.util.Date());
<%= %>

  <%--JSP表达式:用来将程序的输出,输出到客户端上
  		<%= 变量或者表达式%>
  --%>
  <%= new java.util.Date()%>

通常我们一般使用 EL 表达式进行输出

${new java.util.Date()}

用EL表达式的好处在于,当输出的对象不存在时,前端不会显示。而jsp表达式输出时,前端会显示null

jsp脚本片段
<% %>

  <%--JSP脚本片段--%>
  <%
    int sum = 0;
    for (int i = 0; i < 100; i++) {
      sum+=i;
    }
    out.println("<h1>sum=" + sum + "</h1>");
  %>

jsp声明
jsp声明会被编译到生成的java类中,而像jsp脚本片段和jsp表达式这些都被生成到_jspService方法中
<%! %>

  <%--JSP声明--%>
  <%!
    static{
      System.out.println("Loading Servlet!");
    }

    private int globalVar = 0;

    public void kuang(){
      System.out.println("方法kuang");
    }
  %>

jsp指令
<%@ %>

<%@ page import="java.util.Date" %>   <%--导入java包--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>    <%--指定contentType--%>
<%@ page errorPage="error/500.jsp" %>    <%--发生错误后,转向error下的500.jsp页面--%>
<%--直接将三个页面代码合在一起--%>
<%@include file="common/header.jsp"%>
<h1>我是主体</h1>
<%@include file="common/footer.jsp"%>

补充:错误页面也可以在web.xml中设置

    <error-page>
        <error-code>500</error-code>
        <location>/error/500.jsp</location>
    </error-page>

    <error-page>
        <error-code>404</error-code>
        <location>/error/404.jsp</location>
    </error-page>

jsp标签
使用jsp标签可以简化一些操作,常用的是include(包含页面)、forward(转发)、param(设置参数,转发时会把这些参数带上,保存在Request中)
<jsp:XXX />

<jsp:include page="common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="common/footer.jsp"/>

<jsp:forward page="jsptag2.jsp">
    <jsp:param name="name" value="yuan"/>
    <jsp:param name="age" value="12"/>
</jsp:forward>

JSP的9大内置对象

PageContext、Request、Response、Session、Application(Servlet Context)、config(Servlet Config)、out、page、exception

对于 pageContext、request、 session、 application,会有各自的作用域

下面以存储属性为例展示
pageContext   保存的数据只在一个页面中有效
request   保存的数据在一次请求中有效,请求转发时也会携带这个数据
session   保存的数据在一次会话中有效,从打开浏览器到关闭浏览器
application   保存的数据在服务器中有效,直到服务器关闭,或删除此Servlet对象

pageContext.findAttribute()类似于双亲委派机制,会一直往上查找符合的属性,直到Application

PageContextDemo01.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--内置对象--%>
<%
    pageContext.setAttribute("name1","page");   //保存的数据只在一个页面中有效
    request.setAttribute("name2","request");   //保存的数据在一次请求中有效,请求转发时也会携带这个数据
    session.setAttribute("name3","session");   //保存的数据在一次会话中有效,从打开浏览器到关闭浏览器
    application.setAttribute("name4","application");   //保存的数据在服务器中有效,直到服务器关闭,或删除此Servlet对象
%>

<%
    String name1 = (String)pageContext.findAttribute("name1");
    String name2 = (String)pageContext.findAttribute("name2");
    String name3 = (String)pageContext.findAttribute("name3");
    String name4 = (String)pageContext.findAttribute("name4");
    String name5 = (String)pageContext.findAttribute("name5");
    pageContext.forward("/PageDemo02.jsp");
%>

<%--EL表达式 ${}  --%>
<h1>取出的值为:</h1>
<h1>${name1}</h1>
<h1>${name2}</h1>
<h1>${name3}</h1>
<h1>${name4}</h1>
<h1>${name5}</h1>   <%--不会显示null--%>
<h1><%=name5%></h1>   <%--会显示null--%>
</body>
</html>

之后,我们在PageDemo02.jsp中尝试去取这些属性,结果发现只能取到session和applicaion。说明不同的页面下,不能取到PageContext和Request对象中存的值,这也体现了作用域的概念

当然,我们也可以去设置存进去属性的作用域,会自动判断是存进当前页面,还是session等等

pageContext.setAttribute("name","yuan",1);

在jsp页面中,也可以实现请求转发。转发会携带请求,如果此时获取属性,可以获得Request对象中设置的属性,但Page中的依然不会获得

pageContext.forward("/PageContextDemo01.jsp");

EL表达式 ${}

获取数据
${name1}
执行运算
${score>90}
获取Web开发中常用对象

JSTL标签

JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能,可以让我们的使用更加方便。功能上跟java代码是一样的

JSP标准标签库可以分为五类:核心标签、格式化标签、SQL 标签、XML 标签、JSTL 函数

其中,核心标签是最常用的 JSTL标签。引用核心标签库的语法如下:

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

比如,for each,用el表达式获取列表传给items,用var用来定义变量

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%
    ArrayList<String> list = new ArrayList<>();
    list.add("yuan");
    list.add("qi");
    list.add("bin");
    request.setAttribute("test", list);
%>

<c:forEach var="people" items="${test}" begin="1" end="3" step="1">
    <c:out value="${people}"/>
</c:forEach>

设置变量,choose选择

<c:set var="score" value="88"/>
<c:choose>
    <c:when test="${score>90}">
        <c:out value="优秀"/>
    </c:when>
    <c:when test="${score>80}">
        <c:out value="一般"/>
    </c:when>
</c:choose>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值