整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

放弃JSP吧-否则你无路可走

说一下我自己学习和使用JSP的经历吧

我1998年开始学习Java,那时候学校里老师可能听说过Java,但是同学基本上都不知道Java。校图书馆进第一批Java的书,后面的借阅记录上都是我的名字。当时几乎所有男同学都在学C++、PB、VB、Delphi,女生很多在学ASP。所以很多同学问我学的是什么,Java是干什么的。

大学毕业以后,开始用Java做的第一个实际项目是对日外包,是2001年。日方有一套很老的系统,想用Java重构一下,要求用JSP。我下班就跑去西单图书大厦,发现那里的书都还是Servlet的, 没有JSP的!

还好,当时的公司同时进行的一项业务就是代理BEA的Weblogic(BEA是三个从SUN出来的人创建的,后来被Oracle收购)。Weblogic的产品文档里包含非常全面的JSP介绍,所以起初对JSP的学习都是从Weblogic开始的。

那时候还没听说过什么Struts。自己在SUN的官网发现了WAF的文档,全称是Web Application Framework,算是最早MVC模式的介绍。这个WAF不算是框架,只是介绍了MVC模式应该是个什么样子,如何用Servlet+JSP实现MVC模式。SUN的官网提供了少量的样例代码,剩下的都是我们根据文档自己搭建和实践。

在项目的中后期(02年下半年吧),有一次坐班车,听到后面座位上两个人在说话。一个人问:你知道Struts吗?另外一个人说:不知道。问的那个人说:就是S T R U T S这几个字母,开发Java的。我偷偷记在心里,然后第二天上网查了一下(当时没有智能机,家里也没有WIFI),才算开启了Apache这扇大门。后来在ASF上又学习了Cocoon、pluto、turbine等等很多框架。

大概02年底,对日外包项目顺利完成了,我公司开始接国内的项目。第一个国内项目是东北一所大学的科研经费审批项目。记得去给人家部署和演示的时候特别有意思。我们用了半天时间在服务器上部署好,然后去给客户演示。打开浏览器,输入ip+端口,开始操作。操作了十几分钟,所有的客户没有说一个字。越演示心里越没底,不知道客户啥反应。大概又过了几分钟,客户的主任发话了:你们的软件呢?

我们的软件呢?我给你演示了半天,这不就是我们的软件吗?最后才明白,用户认为只有下载一个类似叫setup.exe或install.exe的程序,双击,然后下一步下一步,最后桌面上出现一个快捷方式,那才算是软件!在经过片刻的不可思议之后,我认为实际用户的理念总是落后于研发人员的理念,这个我很容易想明白。但后来发现,我那些学PB、Delphi的师兄弟也不是一时半会能接受B/S结构的应用算是软件的...他们认为:你不就是写个网页吗???

再后来,从03-08年,长期从事企业应用开发,主要是基于Weblogic Platform,包括Server、Integration、Portal,其中在Portal上工作的时间最多。

其中04-05年用Weblogic Portal做深圳市最大的电子政务项目,06-07年用Weblogic平台做广东省电信的3G业务平台,08-09年用Aqualogic做南方电网的SOA。

Weblogic Server中集成了Struts,没记错的话当时是1.1版本。BEA把Struts做了升级和改造,可以在Weblogic Workshop中可视化开发,就是下面这样:

其中圆形代表Action,有Begin Action,End Action,还有普通的中间节点Action。BEA把Struts的这个升级称作Java Page Flow(Java 页面流)。一组这样的图形当中包含的Action和JSP,会定义在一个扩展名是.jpf的文件中。

后来,BEA把JPF捐献给了Apache,成为ASF下的一个开源项目Apache Beehive。

Welcome to Apache Beehivebeehive.apache.org

这个项目现在已经停止更新了。

大概从06年开始,接触到了YUI,也就是Yahoo User Interface,Yahoo开源的一套前端JS组件库。从此算是开启了我的前端之路。

07-08年开始用Extjs,作者说Ext就是Extension(扩展)的意思,扩展了YUI,提供了更丰富的适合企业开发的前端组件。但这时候,Extjs还仅仅是丰富的UI组件库,算不上框架。就是在JSP生成的HTML里面嵌入Extjs的组件。

09-11年用GWT,就是Google Web Toolkits。Google当时的想法很先进,用Java开发前端UI,最终编译成JS。有点类似于现在TS编译成JS的过程,就是打算利用上Java的强类型、面向对象等特点。这时候就已经完全前后端分离了。可以说从08年之后我就再也没写过JSP,一个页面也没写过。

10年开始用Bootstrap。这时候GWT的缺点就暴露出来了,CSS非常难改。直到13年初,开始用上了Angularjs。记得当时在智联招聘上发布职位的时候搜了一下,北京市只有用友和我们公司招聘Angularjs开发。后来就从Angularjs用到React,又用回Angular4,一直到现在都以最新版本的Angular为主,企业应用和互联网应用都有开发。移动开发主要用Ionic,React Native也用过。

为什么要详细介绍我过去和JSP以及前端框架相关的开发经历呢?是因为我想表达一个观点:如果要客观公正评价JSP是否还有必要用,特别是还有必要学,需要一个真正长期用过JSP(前后端不分离)开发,也真正长期用前端框架(前后端分离)开发的人才可以。

就像我在有些知乎答案下评论的那样:

遇到这种情况,我总想起福特的名言:“如果我当年去问顾客他们想要什么,他们肯定会告诉我:‘一匹更快的马。’”

满大街跑马车的时代,福特问顾客需要什么,顾客就说需要一匹更快的马。他们不知道汽车时代会给生活带来怎样革命性的变化。

在BP机时代,大家认为有人戴BP机已经很牛了。满大街诺基亚摩托罗拉功能机的时代,大家也都觉得够用了。问他们需要什么,他们估计会回答:充一次电能不能待机一个月?能不能把自己喜欢的MP3当彩铃?

我觉得要对比评价两代产品,应该给两代产品都熟练体验过的人去判断。从功能机时代过来的人,现在iphone都已经用到第三部了,你再问他功能机够不够用。就拿一个两代产品都具有的功能(比如都可以QQ聊天)对比,你愿意回到功能机时代还是继续用智能机。

一直抱定JSP不撒手,没动力、没能力学习前端技术,没有真正理解前后端分离开发模式的人,不可能得出公正全面的评价。

在校期间或参加培训班就学习了前端框架,参加工作后就开始前后端分离的人,也无法理解老人只用JSP或用JSP+JS前端UI组件的开发模式是个怎么回事。

上面两种人,据我实际接触中了解,大部分都认为自己的开发模式是理所当然的。就像我之前描述自己刚毕业时候的经历一样。大部分客户和我的一些同学,理所当然认为双击setup.exe,然后下一步下一步才是软件。而我理所当然认为B/S架构的也是软件,只是更便于开发和操作。

JSP为什么不适合现在的主流开发,为什么正在被抛弃

过去一年多,陆陆续续在知乎上回答了一些关于JSP的问题。当然,我的回答都是建议淘汰JSP,新人小白一定不要再学JSP了。我现在集中把这些技术因素归纳一下。

一个现代主流Java Web应用,不管前端、后端、还是微服务架构,都在淘汰JSP。

其中,我认为Java服务器端主流技术还是Spring(Spring Boot + Spring MVC + Spring Cloud)。

下面三点,第一点几乎尽人皆知,第二点有一部分人清楚,第三点却很少有人意识到。

前端框架已经非常成熟和稳定,不需要JSP
前后端分离已经不是什么趋势了,而是当前B/S架构开发的主流模式。前后端分离之后,前端只负责展现和交互,后端负责核心业务逻辑。前后端通过API进行交互,并且最好符合RESTful风格。服务器端把数据返回给前端就不再关心这些数据用在哪里、如何布局、什么样式。

这个层面的原因非常容易理解,也是绝大多数讨论JSP是否还有必要学的时候里都会提到的。


服务器端的Spring MVC/WebFlux 和 Spring Boot已经开始抛弃JSP
从Spring 5开始,在原有的基于Servlet技术的Spring MVC之外增加了一个新的编程模型,就是Spring WebFlux。
Spring WebFlux是响应式非阻塞的,而且不支持Servlet API,所以也就不支持JSP!

上图左侧是Spring 5新引入的Spring WebFlux,右侧是大家熟悉的Spring MVC,两者并列,Spring同时支持。

关于这一点,可以看Stack Overflow上面来自Spring Framework和Spring Boot团队成员Brian Clozel的回答:

Spring WebFlux - no JSP support?​stackoverflow.com

新的Spring WebFlux不支持JSP,那咱们不用就好了,至少Spring MVC还是支持JSP的啊。那我们继续看。

如果我们继续使用Spring Boot+Spring MVC开发,那么Spring Boot对JSP是有限制的,看官方文档怎么说的:

链接在这里:

Spring Boot Reference Guide​docs.spring.io

其中那行备注:

If possible, JSPs should be avoided. There are several known limitations when using them with embedded servlet containers.
尽可能避免用JSP。当使用嵌入式Servlet容器时,有一些已知的限制。

关于这些限制和如何继续在Spring Boot中使用JSP,可以自己查一下,知乎里就有好多文章

Spring Boot对JSP有限制,那咱们就凑合用呗,反正我是写Java的,我的发展方向是架构师,我正打算学习微服务,正在看Spring Cloud。那咱们就继续看看Spring Cloud吧。


微服务架构下更没有JSP的用武之地
首先要明白Spring Boot和Spring Cloud的关系。可以先看我的这个回答:

Spring boot与Spring cloud 是什么关系?​www.zhihu.com

还是看这张图吧:

右侧绿色的部分都是Spring Cloud的组成部分,不管是API Gateway、Config Dashboard,Service Registry,还是多个MicroServices,他们都是Spring Boot应用!或者说Spring Boot是整个Spring Cloud的基石(其实也是Spring Cloud Data Flow的基石)。

哦,你明白了,因为有Spring Boot对JSP的限制,而Spring Cloud的组成部分都是Spring Boot应用,所以Spring Cloud也对JSP有限制。其实不仅仅是表面上这个原因,咱们继续分析。

如果强行继续在Spring Cloud环境中继续使用JSP,那么JSP放在哪里?有两种方案。

  1. API Gateway和每个MicroService里面都有@Controller以及对应的JSP。那么这种方案下,不同微服务中的JSP如何通信?用户访问的时候,同一个应用下的所有JSP页面会在不同IP和端口下来回变换。一会是http://ip0:8081/xxx/xxx.jsp,一会是http://ip1:8082/xxx/xxx.jsp,点个连接又跳转到http://ip2:8080/xxx/xxx.jsp....
  2. 把整个微服务应用下的所有@Controller和JSP都放在API Gateway里面,其他Microservice中只有提供REST API的@Controller和@Service。这种方案并不算理想的微服务架构,因为Gateway没有解耦,里面的所有@Controller不能拆分部署。这样就相当于在MicroService架构下有了一个局部的Monolithic(单体应用)。

那怎么才算是使用Spring Cloud的正确姿势?还是看上面那幅图,这次关注左侧三个灰色的部分。IoT(物联网 Internet of Things)、Mobile(移动应用)、Browser(浏览器端),这三个也是应用啊。

我们再看一幅图:

整个Spring体系的图出来了。还是看左侧,Your App,也就是IoT(物联网 Internet of Things)、Mobile(移动应用)、Browser(浏览器端)这三类!

Browser就是前后端分离之后的前端应用,独立开发、独立部署、只和服务器端有HTTP RESTful通信。

我们看看Spring官方给出的Spring Cloud例子,链接在这里:

Spring Projects​spring.io

customers-stores-ui是前端应用,用Angularjs实现的。例子是便于学习的,不应该引入额外的太多其他技术!为什么Spring官方的例子非要用上前端技术?不能只用服务器端开发人员熟悉的模板引擎解(包括JSP)来演示Spring Cloud吗?

我们再看另外一个例子,Spring的Petclinic大家都熟悉吧?Spring 官方例子:

spring-projects/spring-petclinic​github.com

官方的是Monolithic(单体)应用,模板用的是Thymeleaf,自己去看代码。

用Spring Cloud实现的版本:

Spring Petclinic community​github.com

前端有Angular和React两种实现,服务器端有Java和Kotlin两种实现,都没有用服务器端模板。

同样的问题。为什么演示Spring Cloud的开发,要引入额外的前端技术?

答案都是同样的,Spring Cloud就必须前后端分离开发!用JSP就无法完美拆分微服务,无法利用微服务本应带来的各种优势。


总结:

我曾经在知乎某一个问题下总结过:现在JSP处于被前后端夹击的状态,生存空间越来越小了。就算你不打算管前端,只想在服务器端有所建树。微服务的前提也必须前后端分离。

放弃JSP吧,让自己的路走的宽一些。如果死守JSP不放,服务器端只能停留在SSH/SSM阶段,用Spring Boot+Spring MVC已经是你的天花板了。

yEclipse官方最新版免费下载|Myeclipse汉化下载.MyEclipse-功能最全面的Java IDE. - MyEclipse官方中文网

如果您有HTML或JSP文件要编辑,这里将介绍如何编辑。查找以下信息:

  • 编辑源代码
  • 大纲和属性视图
  • 参数页面

该功能在MyEclipse中是可用的。

一、HTML / JSP编辑器

要编辑HTML或JSP文件,请执行以下操作当中的一个:

  • 双击HTML或JSP文件。
  • 右键单击HTML或JSP文件,并选择Open。

HTML编辑器有以下模式:

  • 源模式 — 源模式是HTML和JSP代码的源代码编辑器,它包括智能内容辅助、行编号、彩色语法高亮显示、格式操作、实时验证、在输入时标记有问题的源代码以及代码格式化。
  • 设计模式 — 设计模式具有双面板视图,顶部面板为设计模式,底部面板为源模式。设计模式为所见即所得的可视化编辑模式,设计画布允许选择、复制、剪切、粘贴和使用拖放重新定位Web UI控件。此模式包括一个设计调色板,其中包含可以添加到设计画布的UI Web控件。
  • 预览模式 — 预览模式允许用户快速查看页面在浏览器中的外观,预览模式从设计模式加载当前源代码,即使编辑器内容尚未保存。HTML源代码以预览模式呈现,并且“扎根”于资源所在的位置。如果HTML文档中的图像相对于HTML页面的当前位置,则图像将在预览中正确呈现。

打开文件时,默认模式是Design(设计),通过单击编辑器底部的适当选项卡来更改模式。

本文概述了使用源代码编辑器编辑HTML时最重要的概念和特性。

二、编辑源代码

用户可以从源代码模式或设计模式访问源代码,设计模式具有双面板视图,设计模式位于顶部面板,源模式位于底部面板。

直接编辑源代码时,可以使用以下功能:

  • 语法、颜色和高亮
  • 智能代码完成和内容辅助
  • HTML验证
  • 源格式和清理
  • HTML模板
  • HTML片段

2.1 智能代码完成和内容辅助

在整个源代码中,编辑器提供特定于内容的代码帮助。

Tag names(标记名称):Code assist根据当前上下文提供可用HTML标记的列表。

Tag attributes(标记属性):代码辅助提供了特定于正在编辑的标记属性列表。

Attribute values(属性值):在适当的时候,代码帮助会为您提供一个已知可能值的列表。

2.2 HTML验证

有两种类型的HTML验证:“输入时”和“资源更改”。

“输入时”:当对HTML文档进行更改时,编辑器总是检查HTML语法的有效性,就像Java编辑器一样。

注意:这种类型的验证错误和警告不会出现在Problems视图中。

资源更改:当资源被修改(保存、移动、复制或导入)时,资源构建器将对资源执行HTML验证。

注意:您可以通过从菜单中选择Window>Preferences,展开MyEclipse并选择Validation来设置验证参数。

2.3 源格式化和清理

要快速格式化源代码,请右键单击编辑器,并选择Source>Format。格式化器不会在内部修改HTML标记元素,它只调整HTML元素的缩进和间距。

使用Cleanup Document选项进行高级格式化和样式调整,允许您更改标记名称和属性的大小写,还有其他选项可以插入所需的标记和属性。要使用此选项,请在编辑器中右键单击并选择Source>Cleanup Document,选择Format source复选框,来将Format Document操作作为文档清理的一部分。

JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用。JSP动作元素是用XML语法写成的。

利用JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。

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

<jsp:action_name attribute="value" />

动作元素基本上都是预定义的函数,JSP规范定义了一系列的标准动作,它用JSP作为前缀,可用的标准动作元素如下:

语法描述
jsp:include在页面被请求的时候引入一个文件。
jsp:useBean寻找或者实例化一个JavaBean。
jsp:setProperty设置JavaBean的属性。
jsp:getProperty输出某个JavaBean的属性。
jsp:forward把请求转到一个新的页面。
jsp:plugin根据浏览器类型为Java插件生成OBJECT或EMBED标记。
jsp:element定义动态XML元素
jsp:attribute设置动态定义的XML元素属性。
jsp:body设置动态定义的XML元素内容。
jsp:text在JSP页面和文档中使用写入文本的模板

常见的属性

所有的动作要素都有两个属性:id属性和scope属性。

  • id属性:

    id属性是动作元素的唯一标识,可以在JSP页面中引用。动作元素创建的id值可以通过PageContext来调用。

  • scope属性:

    该属性用于识别动作元素的生命周期。 id属性和scope属性有直接关系,scope属性定义了相关联id对象的寿命。 scope属性有四个可能的值: (a) page, (b)request, (c)session, 和 (d) application。


<jsp:include>动作元素

<jsp:include>动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面。语法格式如下:

<jsp:include page="相对 URL 地址" flush="true" />

前面已经介绍过include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。

以下是include动作相关的属性列表。

属性描述
page包含在页面中的相对URL地址。
flush布尔属性,定义在包含资源前是否刷新缓存区。

实例

以下我们定义了两个文件 date.jspmain.jsp,代码如下所示:

date.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%><p>
 今天的日期是: <%= (new java.util.Date()).toLocaleString()%></p>

main.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>菜鸟教程(runoob.com)</title></head><body><h2>include 动作实例</h2><jsp:include page="date.jsp" flush="true" /></body></html>

现在将以上两个文件放在服务器的根目录下,访问main.jsp文件。显示结果如下:

include 动作实例今天的日期是: 2016-6-25 14:08:17

<jsp:useBean>动作元素

jsp:useBean 动作用来加载一个将在JSP页面中使用的JavaBean。

这个功能非常有用,因为它使得我们可以发挥 Java 组件复用的优势。

jsp:useBean动作最简单的语法为:

<jsp:useBean id="name" class="package.class" />

在类载入后,我们既可以通过 jsp:setProperty 和 jsp:getProperty 动作来修改和检索bean的属性。

以下是useBean动作相关的属性列表。

属性描述
class指定Bean的完整包名。
type指定将引用该对象变量的类型。
beanName通过 java.beans.Beans 的 instantiate() 方法指定Bean的名字。

在给出具体实例前,让我们先来看下 jsp:setProperty 和 jsp:getProperty 动作元素:


<jsp:setProperty>动作元素

jsp:setProperty用来设置已经实例化的Bean对象的属性,有两种用法。首先,你可以在jsp:useBean元素的外面(后面)使用jsp:setProperty,如下所示:

<jsp:useBean id="myName" ... />...<jsp:setProperty name="myName" property="someProperty" .../>

此时,不管jsp:useBean是找到了一个现有的Bean,还是新创建了一个Bean实例,jsp:setProperty都会执行。第二种用法是把jsp:setProperty放入jsp:useBean元素的内部,如下所示:

<jsp:useBean id="myName" ... >... <jsp:setProperty name="myName" property="someProperty" .../></jsp:useBean>

此时,jsp:setProperty只有在新建Bean实例时才会执行,如果是使用现有实例则不执行jsp:setProperty。

jsp:setProperty动作有下面四个属性,如下表:

属性描述
namename属性是必需的。它表示要设置属性的是哪个Bean。
propertyproperty属性是必需的。它表示要设置哪个属性。有一个特殊用法:如果property的值是"*",表示所有名字和Bean属性名字匹配的请求参数都将被传递给相应的属性set方法。
valuevalue 属性是可选的。该属性用来指定Bean属性的值。字符串数据会在目标类中通过标准的valueOf方法自动转换成数字、boolean、Boolean、 byte、Byte、char、Character。例如,boolean和Boolean类型的属性值(比如"true")通过 Boolean.valueOf转换,int和Integer类型的属性值(比如"42")通过Integer.valueOf转换。   value和param不能同时使用,但可以使用其中任意一个。
paramparam 是可选的。它指定用哪个请求参数作为Bean属性的值。如果当前请求没有参数,则什么事情也不做,系统不会把null传递给Bean属性的set方法。因此,你可以让Bean自己提供默认属性值,只有当请求参数明确指定了新值时才修改默认属性值。

<jsp:getProperty>动作元素

jsp:getProperty动作提取指定Bean属性的值,转换成字符串,然后输出。语法格式如下:

<jsp:useBean id="myName" ... />...<jsp:getProperty name="myName" property="someProperty" .../>

下表是与getProperty相关联的属性:

属性描述
name要检索的Bean属性名称。Bean必须已定义。
property表示要提取Bean属性的值

实例

以下实例我们使用了Bean:

package com.runoob.main;public class TestBean {
 private String message = "菜鸟教程";
 public String getMessage() {
 return(message);
 }
 public void setMessage(String message) {
 this.message = message;
 }}

编译以上实例文件 TestBean.java :

$ javac TestBean.java

编译完成后会在当前目录下生成一个 TestBean.class 文件, 将该文件拷贝至当前 JSP 项目的 WebContent/WEB-INF/classes/com/runoob/main 下( com/runoob/main 包路径,没有需要手动创建)。

下面是一个 Eclipse 中目录结构图:

下面是一个很简单的例子,它的功能是装载一个Bean,然后设置/读取它的message属性。

现在让我们在main.jsp文件中调用该Bean:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>菜鸟教程(runoob.com)</title></head><body><h2>Jsp 使用 JavaBean 实例</h2><jsp:useBean id="test" class="com.runoob.main.TestBean" />
<jsp:setProperty name="test"
 property="message"
 value="我爱学习..." />
<p>输出信息....</p>
<jsp:getProperty name="test" property="message" /></body></html>

<jsp:forward> 动作元素

jsp:forward动作把请求转到另外的页面。jsp:forward标记只有一个属性page。语法格式如下所示:

<jsp:forward page="相对 URL 地址" />

以下是forward相关联的属性:

属性描述
pagepage属性包含的是一个相对URL。page的值既可以直接给出,也可以在请求的时候动态计算,可以是一个JSP页面或者一个 Java Servlet.

实例

以下实例我们使用了两个文件,分别是: date.jsp 和 main.jsp。

date.jsp 文件代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%><p>
 今天的日期是: <%= (new java.util.Date()).toLocaleString()%></p>

main.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>菜鸟教程(runoob.com)</title></head><body><h2>forward 动作实例</h2><jsp:forward page="date.jsp" /></body></html>

现在将以上两个文件放在服务器的根目录下,访问main.jsp文件。显示结果如下:

今天的日期是: 2016-6-25 14:37:25

<jsp:plugin>动作元素

jsp:plugin动作用来根据浏览器的类型,插入通过Java插件 运行Java Applet所必需的OBJECT或EMBED元素。

如果需要的插件不存在,它会下载插件,然后执行Java组件。 Java组件可以是一个applet或一个JavaBean。

plugin动作有多个对应HTML元素的属性用于格式化Java 组件。param元素可用于向Applet 或 Bean 传递参数。

以下是使用plugin 动作元素的典型实例:

<jsp:plugin type="applet" codebase="dirname" code="MyApplet.class"
 width="60" height="80">
 <jsp:param name="fontcolor" value="red" />
 <jsp:param name="background" value="black" />
 <jsp:fallback>
 Unable to initialize Java Plugin </jsp:fallback>
</jsp:plugin>

如果你有兴趣可以尝试使用applet来测试jsp:plugin动作元素,<fallback>元素是一个新元素,在组件出现故障的错误时发送给用户错误信息。


<jsp:element> 、 <jsp:attribute>、 <jsp:body>动作元素

<jsp:element> 、 <jsp:attribute>、 <jsp:body>动作元素动态定义XML元素。动态是非常重要的,这就意味着XML元素在编译时是动态生成的而非静态。

以下实例动态定义了XML元素:

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>菜鸟教程(runoob.com)</title></head><body><jsp:element name="xmlElement"><jsp:attribute name="xmlElementAttr">
 属性值</jsp:attribute><jsp:body>
 XML 元素的主体</jsp:body></jsp:element></body></html>

<jsp:text>动作元素

<jsp:text>动作元素允许在JSP页面和文档中使用写入文本的模板,语法格式如下:

<jsp:text>模板数据</jsp:text>

以上文本模板不能包含其他元素,只能只能包含文本和EL表达式(注:EL表达式将在后续章节中介绍)。请注意,在XML文件中,您不能使用表达式如 ${whatever > 0},因为>符号是非法的。 你可以使用 ${whatever gt 0}表达式或者嵌入在一个CDATA部分的值。

<jsp:text><![CDATA[<br>]]></jsp:text>

如果你需要在 XHTML 中声明 DOCTYPE,必须使用到<jsp:text>动作元素,实例如下:

<jsp:text><![CDATA[<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">]]></jsp:text><head><title>jsp:text action</title></head><body><books><book><jsp:text> 
 Welcome to JSP Programming</jsp:text></book></books></body></html>

你可以对以上实例尝试使用<jsp:text>及不使用该动作元素执行结果的区别。