JSP(全称:Java Server Pages):Java 服务端页面(上)

简介: JSP(全称:Java Server Pages):Java 服务端页面

1,JSP 概述


==JSP(全称:Java Server Pages):Java 服务端页面。==是一种动态的网页技术,其中既可以定义 HTML、JS、CSS等静态内容,还可以定义 Java代码的动态内容,也就是 JSP = HTML + Java。如下就是jsp代码


<html><head><title>Title</title></head><body><h1>JSP,HelloWorld</h1><%System.out.println("hello,jsp~");
%></body></html>


上面代码 h1 标签内容是展示在页面上,而 Java 的输出语句是输出在 idea 的控制台。


那么,JSP 能做什么呢?现在我们只用 servlet 实现功能,看存在什么问题。如下图所示,当我们登陆成功后,需要在页面上展示用户名


5d7097f209314fb180f4ca71e9ed1d1d.png


上图的用户名是动态展示,也就是谁登陆就展示谁的用户名。只用 servlet 如何实现呢?在今天的资料里已经提供好了一个 LoginServlet ,该 servlet 就是实现这个功能的,现将资料中的 LoginServlet.java 拷贝到 request-demo 项目中来演示。接下来启动服务器并访问登陆页面


8d2621f1ac0941aabecefcdc517130ef.png


输入了 zhangsan 用户的登陆信息后点击 登陆 按钮,就能看到如下图效果


29a073fd76f84ae19152af7fd8fb967b.png


当然如果是 lisi 登陆的,在该页面展示的就是 lisi,欢迎您,动态的展示效果就实现了。那么 LoginServlet 到底是如何实现的,我们看看它里面的内容


d8426907b00f4536834283c49f9ec356.png


上面的代码有大量使用到 writer 对象向页面写标签内容,这样我们的代码就显得很麻烦;将来如果展示的效果出现了问题,排错也显得有点力不从心。而 JSP 是如何解决这个问题的呢?在资料中也提供了一个 login.jsp 页面,该页面也能实现该功能,现将该页面拷贝到项目的 webapp下,需要修改 login.html 中表单数据提交的路径为下图


6a85bd32347840718c3a5f38c447117f.png


重新启动服务器并进行测试,发现也可以实现同样的功能。那么 login.jsp 又是如何实现的呢?那我们来看看 login.jsp 的代码


9eda7238dfc84952a9d7cd4abbbd37ca.png


上面代码可以看到里面基本都是 HTML 标签,而动态数据使用 Java 代码进行展示;这样操作看起来要比用 servlet 实现要舒服很多。


JSP 作用:简化开发,避免了在Servlet中直接输出HTML标签。


2,JSP 快速入门

接下来我们做一个简单的快速入门代码。


2.1 搭建环境

创建一个maven的 web 项目,项目结构如下:


2209cb3f52ca445c954eb335d2e63721.png


pom.xml 文件内容如下:


<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>jsp-demo</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build></project>


2.2 导入 JSP 依赖

在 dependencies 标签中导入 JSP 的依赖,如下


<dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version><scope>provided</scope></dependency>


该依赖的 scope 必须设置为 provided,因为 tomcat 中有这个jar包了,所以在打包时我们是不希望将该依赖打进到我们工程的war包中。


2.3 创建 jsp 页面

在项目的 webapp 下创建jsp页面


dcf5505bca6a4ef49bfd2c828ecf18ee.png


通过上面方式创建一个名为 hello.jsp 的页面。


2.4 编写代码

在 hello.jsp 页面中书写 HTML 标签和 Java 代码,如下


<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>Title</title></head><body><h1>hellojsp</h1><%System.out.println("hello,jsp~");
%></body></html>


2.5 测试

启动服务器并在浏览器地址栏输入 http://localhost:8080/jsp-demo/hello.jsp,我们可以在页面上看到如下内容


19fa8ec8e5f24611b71121b7dd2ec5a3.png


同时也可以看到在 idea 的控制台看到输出的 hello,jsp~ 内容。


3,JSP 原理

我们之前说 JSP 就是一个页面,那么在 JSP 中写 html 标签,我们能理解,但是为什么还可以写 Java 代码呢?


因为 ==JSP 本质上就是一个 Servlet。==接下来我们聊聊访问jsp时的流程


浏览器第一次访问 hello.jsp 页面

tomcat 会将 hello.jsp 转换为名为 hello_jsp.java 的一个 Servlet

tomcat 再将转换的 servlet 编译成字节码文件 hello_jsp.class

tomcat 会执行该字节码文件,向外提供服务

我们可以到项目所在磁盘目录下找 target\tomcat\work\Tomcat\localhost\jsp-demo\org\apache\jsp 目录,而这个目录下就能看到转换后的 servlet


打开 hello_jsp.java 文件,来查看里面的代码


由上面的类的继承关系可以看到继承了名为 HttpJspBase 这个类,那我们在看该类的继承关系。到资料中的找如下目录: 资料\tomcat源码\apache-tomcat-8.5.68-src\java\org\apache\jasper\runtime ,该目录下就有 HttpJspBase 类,查看该类的继承关系


可以看到该类继承了 HttpServlet ;那么 hello_jsp 这个类就间接的继承了 HttpServlet ,也就说明 hello_jsp 是一个 servlet。


继续阅读 hello_jsp 类的代码,可以看到有一个名为 _jspService() 的方法,该方法就是每次访问 jsp 时自动执行的方法,和 servlet 中的 service 方法一样 。


而在 _jspService() 方法中可以看到往浏览器写标签的代码:


以前我们自己写 servlet 时,这部分代码是由我们自己来写,现在有了 jsp 后,由tomcat完成这部分功能。


4,JSP 脚本

JSP脚本用于在 JSP页面内定义 Java代码。在之前的入门案例中我们就在 JSP 页面定义的 Java 代码就是 JSP 脚本。


4.1 JSP 脚本分类

JSP 脚本有如下三个分类:


<%…%>:内容会直接放到_jspService()方法之中

<%=…%>:内容会放到out.print()中,作为out.print()的参数

<%!…%>:内容会放到_jspService()方法之外,被类直接包含

代码演示:


在 hello.jsp 中书写


<%System.out.println("hello,jsp~");
inti=3;
%>


通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,i 变量定义在了 _jspService() 方法中


在 hello.jsp 中书写


<%="hello"%><%=i%>


通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,该脚本的内容被放在了 out.print() 中,作为参数


在 hello.jsp 中书写


<%!voidshow(){}
Stringname="zhangsan";
%>


通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,该脚本的内容被放在了成员位置


4.2 案例


4.2.1 需求

使用JSP脚本展示品牌数据


说明:


在资料 资料\1. JSP案例素材 中提供了 brand.html 静态页面

在该案例中数据不从数据库中查询,而是在 JSP 页面上写死

4.2.2 实现

将资料 资料\1. JSP案例素材 中的 Brand.java 文件放置到项目的 com.itheima.pojo 包下


在项目的 webapp 中创建 brand.jsp ,并将 brand.html页面中的内容拷贝过来。brand.jsp 内容如下


<%@pagecontentType="text/html;charset=UTF-8"language="java"%><!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body><inputtype="button"value="新增"><br><hr><tableborder="1"cellspacing="0"width="800"><tr><th>序号</th><th>品牌名称</th><th>企业名称</th><th>排序</th><th>品牌介绍</th><th>状态</th><th>操作</th></tr><tralign="center"><td>1</td><td>三只松鼠</td><td>三只松鼠</td><td>100</td><td>三只松鼠,好吃不上火</td><td>启用</td><td><ahref="#">修改</a><ahref="#">删除</a></td></tr><tralign="center"><td>2</td><td>优衣库</td><td>优衣库</td><td>10</td><td>优衣库,服适人生</td><td>禁用</td><td><ahref="#">修改</a><ahref="#">删除</a></td></tr><tralign="center"><td>3</td><td>小米</td><td>小米科技有限公司</td><td>1000</td><td>为发烧而生</td><td>启用</td><td><ahref="#">修改</a><ahref="#">删除</a></td></tr></table></body></html>


现在页面中的数据都是假数据。


在 brand.jsp 中准备一些数据


<%// 查询数据库List<Brand>brands=newArrayList<Brand>();
brands.add(newBrand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
brands.add(newBrand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
brands.add(newBrand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
%>


==注意:==这里的类是需要导包的


将 brand.jsp 页面中的 table 标签中的数据改为动态的


<tableborder="1"cellspacing="0"width="800"><tr><th>序号</th><th>品牌名称</th><th>企业名称</th><th>排序</th><th>品牌介绍</th><th>状态</th><th>操作</th></tr><%for (inti=0; i<brands.size(); i++) {
//获取集合中的 每一个 Brand 对象Brandbrand=brands.get(i);
     }
%><tralign="center"><td>1</td><td>三只松鼠</td><td>三只松鼠</td><td>100</td><td>三只松鼠,好吃不上火</td><td>启用</td><td><ahref="#">修改</a><ahref="#">删除</a></td></tr></table>



上面的for循环需要将 tr 标签包裹起来,这样才能实现循环的效果,代码改进为


<tableborder="1"cellspacing="0"width="800"><tr><th>序号</th><th>品牌名称</th><th>企业名称</th><th>排序</th><th>品牌介绍</th><th>状态</th><th>操作</th></tr><%for (inti=0; i<brands.size(); i++) {
//获取集合中的 每一个 Brand 对象Brandbrand=brands.get(i);
%><tralign="center"><td>1</td><td>三只松鼠</td><td>三只松鼠</td><td>100</td><td>三只松鼠,好吃不上火</td><td>启用</td><td><ahref="#">修改</a><ahref="#">删除</a></td></tr><%     }
%></table>



注意:<%%> 里面写的是 Java 代码,而外边写的是 HTML 标签


上面代码中的 td 标签中的数据都需要是动态的,所以还需要改进


<tableborder="1"cellspacing="0"width="800"><tr><th>序号</th><th>品牌名称</th><th>企业名称</th><th>排序</th><th>品牌介绍</th><th>状态</th><th>操作</th></tr><%for (inti=0; i<brands.size(); i++) {
//获取集合中的 每一个 Brand 对象Brandbrand=brands.get(i);
%><tralign="center"><td><%=brand.getId()%></td><td><%=brand.getBrandName()%></td><td><%=brand.getCompanyName()%></td><td><%=brand.getOrdered()%></td><td><%=brand.getDescription()%></td><td><%=brand.getStatus() ==1?"启用":"禁用"%></td><td><ahref="#">修改</a><ahref="#">删除</a></td></tr><%     }
%></table>



4.2.3 成品代码

<%@pageimport="com.itheima.pojo.Brand"%><%@pageimport="java.util.List"%><%@pageimport="java.util.ArrayList"%><%@pagecontentType="text/html;charset=UTF-8"language="java"%><%// 查询数据库List<Brand>brands=newArrayList<Brand>();
brands.add(newBrand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
brands.add(newBrand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
brands.add(newBrand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
%><!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body><inputtype="button"value="新增"><br><hr><tableborder="1"cellspacing="0"width="800"><tr><th>序号</th><th>品牌名称</th><th>企业名称</th><th>排序</th><th>品牌介绍</th><th>状态</th><th>操作</th></tr><%for (inti=0; i<brands.size(); i++) {
Brandbrand=brands.get(i);
%><tralign="center"><td><%=brand.getId()%></td><td><%=brand.getBrandName()%></td><td><%=brand.getCompanyName()%></td><td><%=brand.getOrdered()%></td><td><%=brand.getDescription()%></td><td><%=brand.getStatus() ==1?"启用":"禁用"%></td><td><ahref="#">修改</a><ahref="#">删除</a></td></tr><%        }
%></table></body></html>


4.2.4 测试

在浏览器地址栏输入 http://localhost:8080/jsp-demo/brand.jsp ,


4.3 JSP 缺点

通过上面的案例,我们可以看到 JSP 的很多缺点。


由于 JSP页面内,既可以定义 HTML 标签,又可以定义 Java代码,造成了以下问题:


书写麻烦:特别是复杂的页面


既要写 HTML 标签,还要写 Java 代码


阅读麻烦


上面案例的代码,相信你后期再看这段代码时还需要花费很长的时间去梳理


复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…


占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存


调试困难:出错后,需要找到自动生成的.java文件进行调试


不利于团队协作:前端人员不会 Java,后端人员不精 HTML


如果页面布局发生变化,前端工程师对静态页面进行修改,然后再交给后端工程师,由后端工程师再将该页面改为 JSP 页面


由于上述的问题, ==JSP 已逐渐退出历史舞台,==以后开发更多的是使用 HTML + Ajax 来替代。Ajax 是我们后续会重点学习的技术。有个这个技术后,前端工程师负责前端页面开发,而后端工程师只负责前端代码开发。下来对技术的发展进行简单的说明


第一阶段:使用 servlet 即实现逻辑代码编写,也对页面进行拼接。这种模式我们之前也接触过


第二阶段:随着技术的发展,出现了 JSP ,人们发现 JSP 使用起来比 Servlet 方便很多,但是还是要在 JSP 中嵌套 Java 代码,也不利于后期的维护


第三阶段:使用 Servlet 进行逻辑代码开发,而使用 JSP 进行数据展示


第四阶段:使用 servlet 进行后端逻辑代码开发,而使用 HTML 进行数据展示。而这里面就存在问题,HTML 是静态页面,怎么进行动态数据展示呢?这就是 ajax 的作用了。


那既然 JSP 已经逐渐的退出历史舞台,那我们为什么还要学习 JSP 呢?原因有两点:


一些公司可能有些老项目还在用 JSP ,所以要求我们必须动 JSP

我们如果不经历这些复杂的过程,就不能体现后面阶段开发的简单

接下来我们来学习第三阶段,使用 EL表达式 和 JSTL 标签库替换 JSP 中的 Java 代码。

相关文章
|
29天前
|
缓存 安全 Java
Java服务器端技术:Servlet与JSP的集成与扩展
Java服务器端技术:Servlet与JSP的集成与扩展
22 3
|
29天前
|
存储 缓存 前端开发
Servlet与JSP在Java Web应用中的性能调优策略
Servlet与JSP在Java Web应用中的性能调优策略
24 1
|
1月前
|
安全 Java 应用服务中间件
【Azure 应用服务】App Service中,为Java应用配置自定义错误页面,禁用DELETE, PUT方法
【Azure 应用服务】App Service中,为Java应用配置自定义错误页面,禁用DELETE, PUT方法
【Azure 应用服务】App Service中,为Java应用配置自定义错误页面,禁用DELETE, PUT方法
|
1月前
|
JSON 前端开发 Java
java系列之 页面打印出 [object Object],[object Object]
文章解释了在前端页面打印JSON对象时出现`[object Object]`的原因,并提供了使用`JSON.stringify(json对象)`方法将对象转换为可读字符串的解决方案。
java系列之 页面打印出 [object Object],[object Object]
|
29天前
|
存储 Java 关系型数据库
基于Servlet和JSP的Java Web应用开发指南
基于Servlet和JSP的Java Web应用开发指南
17 0
|
29天前
|
前端开发 安全 Java
在Java服务器端开发的浩瀚宇宙中,Servlet与JSP犹如两颗璀璨的明星,它们联袂登场,共同编织出动态网站的绚丽篇章。
在Java服务器端开发的浩瀚宇宙中,Servlet与JSP犹如两颗璀璨的明星,它们联袂登场,共同编织出动态网站的绚丽篇章。
16 0
|
1月前
|
SQL Java 数据库
jsp中使用Servlet查询SQLSERVER数据库中的表的信息,并且打印在屏幕上
该博客文章介绍了在JSP应用中使用Servlet查询SQL Server数据库的表信息,并通过JavaBean封装图书信息,将查询结果展示在Web页面上的方法。
jsp中使用Servlet查询SQLSERVER数据库中的表的信息,并且打印在屏幕上
|
1月前
|
供应链 前端开发 Java
JSP+servlet+mybatis+layui服装库存管理系统(大三上学期课程设计)
这篇文章通过一个服装库存管理系统的实例,展示了在Spring Boot项目中使用Ajax、JSON、layui、MVC架构和iframe等技术,涵盖了注册登录、权限管理、用户管理、库存管理等功能,并提供了系统运行环境和技术要求的详细说明。
JSP+servlet+mybatis+layui服装库存管理系统(大三上学期课程设计)
|
3月前
|
自然语言处理 前端开发 Java
Servlet与JSP:Java Web开发的基石技术详解
【6月更文挑战第23天】Java Web的Servlet与JSP是动态网页的核心。Servlet是服务器端的Java应用,处理HTTP请求并响应;JSP则是结合HTML与Java代码的页面,用于动态内容生成。Servlet通过生命周期方法如`init()`、`service()`和`destroy()`工作,而JSP在执行时编译成Servlet。两者在MVC架构中分工,Servlet处理逻辑,JSP展示数据。尽管有Spring MVC等框架,Servlet和JSP仍是理解Web开发基础的关键。
85 12
|
3月前
|
存储 Java 关系型数据库
基于Servlet和JSP的Java Web应用开发指南
【6月更文挑战第23天】构建Java Web应用,Servlet与JSP携手打造在线图书管理系统,涵盖需求分析、设计、编码到测试。通过实例展示了Servlet如何处理用户登录(如`LoginServlet`),JSP负责页面展示(如`login.jsp`和`bookList.jsp`)。应用基于MySQL数据库,包含用户和图书表。登录失败显示错误信息,成功后展示图书列表。部署到Tomcat服务器测试功能。此基础教程为深入Java Web开发奠定了基础。
82 10