从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

    • 服务器软件

    • 环境管理和配置管理-科普篇
    • Servlet入门

      • 什么是Servlet
      • Servlet入门案例
      • Servlet生命周期
      • Servlet中的注解
      • Tomcat集成IDEA
      • Servlet体系结构
      • HTTP协议基础
      • 深入request和response对象
      • request对象基本使用
      • request其他功能
      • Servlet实现登录功能
      • HTTP协议基础-响应
      • Response对象基本使用
      • response对象之重定向
      • response输出字符到浏览器
      • response输出字节数据
      • 验证码案例
      • ServletContext
      • 文件下载案例
      • Cookie笔记
      • Cookie的更多细节
      • Cookie实践:记住上次访问时间
      • JSP入门
        • 在JSP出现之前
        • 动态生成
        • JSP介绍
        • JSP的本质
        • JSP的基本书写
      • JSP的内置对象和案例
      • IDEA与JavaWeb的小技巧
      • Session笔记
      • 验证码案例
      • JSP深入学习
      • MVC开发模式
      • EL表达式和JSTL标签
      • JSTL标签库
      • 案例:列表的增删改查
      • Filter学习
      • Filter案例
      • Listener学习
      • Java中的Ajax
      • Java中的JSON
      • Servlet
    • JavaWeb
  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java并发

  • Java源码

  • JVM

  • 韩顺平

  • Java
  • Java
  • JavaWeb
  • Servlet入门
2023-04-17
目录

JSP入门

# 90.JSP入门

JSP,全称Java Server Pages,可以理解为一个页面模板,其中既可以写HTML,又可以写Java代码,在访问这个JSP的时候,服务器会将其转换为HTML文件返回给浏览器,用来简化书写

‍

# 在JSP出现之前

一个页面,通常是包含动态内容和静态内容。例如一个页面上,有展示用户名的地方,此时用Servlet的话我们只能这样做:

resp.getWriter().write("<p>您好" + username + "欢迎访问</p>" );
1

‍

而一个完整的HTML页面,内容是非常多的,我们得一个个write:

resp.getWriter().write("<HTML>");
resp.getWriter().write("<body>");

resp.getWriter().write("<p>您好" + username + "欢迎访问</p>" );

resp.getWriter().write("</body>");
resp.getWriter().write("</HTML>");
1
2
3
4
5
6
7

在上古时代,通常情况是美工写好html静态页面后,丢给Java程序员。Java程序猿在Servlet中的Service方法里,逐句复制html静态页面上的html语句到Servlet的中,并将需要动态展示的地方动态拼接字符串(例如上面的第4行)。

然后浏览器就会拿到拼接好的HTML文本,并展示到浏览器上,按这种方式,要想拼接数据并完整输出一个html页面,没个几百上千行resp.getWriter.write()​是不可能的。所以基本上敲完两个页面两根手指就麻了。

‍

# 动态生成

而同样是上古时期,PHP和ASP就优秀得多了,不搞这繁琐的一套,它们选择在HTML页面中嵌入相应语言来引入动态数据,避免了手动拷贝HTML片段输出的尴尬局面。例如ASP:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  @foreach(var x in Request)
    {<li>@x</li>}
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13

‍

上述代码会自动执行,生成一系列的 li标签,省去了我们手工拼接的麻烦!

因为仔细想来,我们的主要目的就是希望在最终输出的html的代码中嵌入后台数据罢了,除了把html语句拿出来在Servlet里拼接好再输出这种方式外,我们也可以直接在html语句中写入动态数据!这两种几乎是完全相反的设计思路!孰优孰劣,一看便知。

Java也不甘落后,因此也发明了JSP

‍

# JSP介绍

JSP全称Java Server Page,直译就是“运行在服务器端的页面”。上面已经介绍过,我们可以直接在JSP文件里写HTML代码,使用上把它当做HTML文件。而且JSP中HTML/CSS/JS等的写法和HTML文件中的写法是一模一样的。但它毕竟不是HTML,而且本质差了十万八千里。因为我们还可以把Java代码内嵌在JSP页面中,很方便地把动态数据渲染成静态页面。这一点,打死HTML都做不到。

当有人请求JSP时,服务器内部会经历一次动态资源(JSP)到静态资源(HTML)的转化,服务器会自动帮我们把JSP中的HTML片段和数据拼接成静态资源响应给浏览器。也就是说JSP是运行在服务器端,但最终发给客户端的都已经是转换好的HTML静态页面(在响应体里)。

即:JSP = HTML + Java片段(各种标签本质上还是Java片段)

‍

‍

‍

‍

‍

# JSP的本质

JSP本质上就是一个Servlet,访问一个JSP,服务器内发生的事情如下:

  1. 服务器解析浏览器的HTTP请求,寻找是否有JSP文件,没有则返回404
  2. 有该文件,则会将JSP文件转为一个Servlet(一个.java文件)
  3. 编译该Servlet会被编译为字节码,然后生成Servlet对象,处理请求并返回给浏览器

‍

我们来亲自验证下。首先在web目录下新建index.jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
    <h1>Hello JSP!</h1>
  </body>
</html>
1
2
3
4
5
6
7
8
9

‍

启动Tomcat,并访问http://localhost:8080/hello/index.jsp。

我们可以看到工作空间目录为:

Using CATALINA_BASE:   "C:\Users\peterjxl\AppData\Local\JetBrains\IntelliJIdea2022.3\tomcat\f48a6060-bf20-4710-adb8-4ae1308d09c7"
1

‍

我们打开这个目录,可以看到有work目录。之前我们学习Tomcat的时候,讲解过目录结构,work目录是存放运行时产生的一些临时文件。我们直接进入到最里面的文件夹:

C:\Users\peterjxl\AppData\Local\JetBrains\IntelliJIdea2022.3\tomcat\f48a6060-bf20-4710-adb8-4ae1308d09c7\work\Catalina\localhost\hello\org\apache\jsp
1

‍

‍

可以看到有一个Java文件和一个class文件:

​​

‍

‍

我们打开这个Java文件:

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {
1
2
3

‍

我们可以看到其继承了HttpJspBase类,而这个类我们可以在Tomcat的源码中找到:apache-tomcat-9.0.73-src\java\org\apache\jasper\runtime\HttpJspBase.java,打开,可以看到其继承了HttpServlet。

public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
1

‍

因此,我们验证了一个点:JSP本质上是一个Servlet。index_jsp.java里还干了什么事情呢?既然是个Servlet,肯定有个service方法,我们继续往下看,可以看到这样的代码:

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
//... 省略其他代码

      out.write("\n");
      out.write("\n");
      out.write("<html>\n");
      out.write("  <head>\n");
      out.write("    <title>$Title$</title>\n");
      out.write("  </head>\n");
      out.write("  <body>\n");
      out.write("  $END$\n");
      out.write("  </body>\n");
      out.write("</html>\n");
//... 省略其他代码
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

‍

破案了,原理Servlet本质上也是拼接字符串来输出HTML文件的!因此使用JSP,能极大简化我们的代码。

‍

# JSP的基本书写

既然JSP里可以写Java代码,要怎么写呢?不可能说我直接写个Java代码,Tomcat就会知道要执行。例如我们有一个User对象,要展示其用户名:

<h1>user.getName()</h1>
1

上述代码,肯定是不会被当成Java代码来执行的。

‍

‍

要如何与HTML标签区分出来呢?有如下3种格式:

  1. ​<% 代码 %>​:定义的Java代码,编译后在Servlet的service方法中。service方法中可以写什么,该脚本中就可以写什么。
  2. ​<%! 代码 %>​:定义的Java代码,在JSP转换后会放在类的成员位置。相当于定义一个成员变量、成员方法,用的较少,因为之前讲过,最好不要定义,怕引发线程安全问题
  3. ​<%= 代码 %>​:相当于定义了一个输出语句,会将代码里的执行结果输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。

‍

我们来演示下

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
    <h1>Hello JSP!</h1>
    <% System.out.println("Hello"); %>

    <%! int i = 1; %>

    <%= "hello".toUpperCase() %>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

‍

更新Tomcat,访问http://localhost:8080/hello/index.jsp。

首先可以看到IDEA里打印了Hello,这是第8行的代码起作用了;

我们还是访问JSP编译后的index_jsp.java,可以看到有我们定义的变量 i ;

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

 int i = 1; 
1
2
3
4
5

‍

最后我们可以看到页面下面有HELLO,这是第12行代码的作用

​​

‍

‍

‍

‍

在GitHub上编辑此页 (opens new window)
上次更新: 2023/5/6 21:54:08
Cookie实践:记住上次访问时间
JSP的内置对象和案例

← Cookie实践:记住上次访问时间 JSP的内置对象和案例→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式