本人在实际项目和各种框架中,发现Servlet, JSP, JSTL, EL在maven中依赖的写法种类非常多,可谓五花八门,为了搞明白不同的写法有何不同,花了些时间研究了下在maven的pom.xml中如何合理的加入Servlet, JSP, JSTL, EL的依赖,本文即是研究的结果。
为了说明清楚,首先简要的介绍下这几种组件,然后重点说明如何在maven中配置,内容分为几下几个部分:
0. Servlet, JSP, JSTL, EL这些东西都是什么,做什么用的,之间有什么关系
1. 这些东西的版本是怎么回事
2. 如何在maven中具体配置
这些东西都是什么,做什么用的,之间有什么关系
这四个东西都是JavaEE规范标准的一部分,注意这只是标准而不是实现,标准和实现相当于接口和接口的实现类。JavaEE规范中有很多标准,其中这四个在JavaWeb开发中比较常用,具体来说:
- Servlet & JSP,这个估计都比较清楚;
- JSTL叫做JSP标准标签库,它是一个JSP标签集合,封装了JSP应用的通用核心功能,这个东西一般在JSP页面里使用;
- EL表达式,主要用于替换JSP页面中的脚本表达式,一般也是用在JSP页面里。
另外:如果一个容器(例如GlassFish)实现了JavaEE的全部标准,这个容器可以称之为JavaEE的容器,如果一个容器(例如Tomcat)实现了Servlet规范,可以称之为Servlet容器。
这些东西的版本是怎么回事
JavaEE有不同的版本,其组件也有不同的版本,所运行的容器也有对应的版本,在一个项目开发之初的时候,就应该明确使用哪个版本的组件,如果没有特别的情况,最好使用最新的稳定版本,在编写本文的2016年11月,本人推荐如下的组件版本组合:
Servlet 3.1
JSP 2.3
JSTL 1.2
EL 3.0
tomcat 8.0.x或者tomcat8.5.x
另外,wiki上有一个关于JavaEE版本和组件版本的对应 :Java_EE_version_history;
Tomcat官方也有一个版本和组件的对应关系说明 : tomcat版本说明。
如何在maven中具体配置
原则
我们在开发的时候,是按照标准开发的,而程序运行时是在容器中运行,容器可能会提供组件的具体(注意这里是可能会,例如Tomcat提供了Servlet和JSP的实现,但是没有提供JSTL的实现),这里有两种情况实现:
- 程序部署的容器从一开始就确定了,例如应用程序未来部署的生产环境是Tomcat;
- 程序部署的容器不确定,或者需要程序可以在不同的容器下部署,例如应用程序既能在Tomcat中部署,又可以在jetty中部署。
第一种情况,本人建议在将标准和实现的依赖都放到pom.xml中,并且scope使用provided,第二种情况复杂一些,因为不确定容器是否会提供组件的实现,不同的容器对组件支持的程度不同,具体的依赖也是不同的,这种情况可以使用maven的profile解决,在下面的配置中,以Tomcat 8.0.36作为具体的部署环境为例来重点说明第一种情况,第二种情况也会提到一些。
Servlet
- 既引入标准,也进入具体实现的写法
<!-- servlet标准 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> <version>3.1.0</version> </dependency> <!-- tomcat提供的servlet实现 --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <scope>provided</scope> <version>8.0.36</version> </dependency>
实际当中,Tomcat的servlet-api实现已经整合了标准在内,所以我们只需要在maven的pom.xml中加入如下内容就可以了
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <scope>provided</scope> <version>8.0.36</version> </dependency>
注意,在maven中加入Servlet标准的依赖,不同版本的标准写法是不一样的,具体来说,是artifactId不一样。
Servlet 3.0.1以前的写法:
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <scope>provided</scope> <version>2.5</version> </dependency>
Servlet 3.0.1以后的写法:
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> <version>3.1.0</version> </dependency>
- 只引入标准的写法
<!-- servlet标准 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> <version>3.1.0</version> </dependency>
JSP
- 既引入标准,也进入具体实现的写法
和Servlet类似,Tomcat的jsp实现已经整合了标准在内,所以我们只需要在maven的pom.xml中加入如下内容就可以了:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> <scope>provided</scope> <version>8.0.36</version> </dependency>
- 只引入标准的写法
如果需要在maven中加入JSP标准,请注意不同版本JSP标准的artifactId略有不同
2.2.1-b03之前的写法
<dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <scope>provided</scope> <version>2.2</version> </dependency>
2.2.1-b03之后的写法
<dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <scope>provided</scope> <version>2.3.1</version> </dependency>
JSTL
JSTL的情况比较复杂,首先JSTL和Servlet,JSP不太一样,Tomcat没有提供JSTL的实现。所以在maven中加入依赖的时候,既要加入标准,也要加入具体实现,并且不能使用provided scope;再者JSTL依赖的写法非常多,我在mvnrepository.com上查了一下,以版本1.2为例,至少有以下几种写法:
<dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jstl-impl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
其中有的是标准, 有的是实现,我们具体分析一下,考虑到从2006年的Java EE 5到预计2017年发布的Java EE 8,对应的JSTL版本均为1.2,我们以下的分析采用这个版本。
首先看下面这两种写法
<dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jstl-impl</artifactId> <version>1.2</version> </dependency>
其中第一种写法是标准,第二写法是GlassFish的具体实现,这个实现中没有包括标准。需要注意的是,这两个组件分别依赖与其他的组件,jstl-api有两个依赖:
Servlet 2.5和JSP 2.1
[INFO] \- javax.servlet.jsp.jstl:jstl-api:jar:1.2:compile [INFO] +- javax.servlet:servlet-api:jar:2.5:compile [INFO] \- javax.servlet.jsp:jsp-api:jar:2.1:compile
jstl-impl有三个依赖,分别是:
Servlet 2.5、JSP 1.2,以及jstl-api 1.2(也就是上面第一个),
[INFO] \- org.glassfish.web:jstl-impl:jar:1.2:compile [INFO] +- javax.servlet:servlet-api:jar:2.5:compile [INFO] +- javax.servlet.jsp:jsp-api:jar:2.1:compile [INFO] \- javax.servlet.jsp.jstl:jstl-api:jar:1.2:compile
如果项目中使用的Servlet和JSP不是这个版本,建议将其排除。
然后看下面这两种写法:
<dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
这两种写法都是就是包括了标准,也包括了实现,本人花了些时间分析这两个组件之间的不同,到头来结论是没有任何不同,这两个jar文件的md5校验码是一样的。
MD5 (jstl/jstl/1.2/jstl-1.2.jar) = 51e15f798e69358cb893e38c50596b9b MD5 (javax/servlet/jstl/1.2/jstl-1.2.jar) = 51e15f798e69358cb893e38c50596b9b
这两个的实现部分和上面GlassFish的实现是一样,没有区别,另外,这两个组件都没有自己的依赖。
最后说下这种写法
<dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
这些写法虽然还存在于mvnrepository.com,但是对应的jar文件已经在maven的公共库中不存在了。其访问地址
https://repo.maven.apache.org/maven2/javax/servlet/jsp/jstl/jstl/1.2/jstl-1.2.pom
已经是404 Not Found。
解释完了这些,给出具体的写法
- 只引入标准的写法
<dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> </exclusions> </dependency>
- 既引入标准,也进入具体实现的写法
以下三种写法都可以,第一种
<dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jstl-impl</artifactId> <version>1.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> </exclusions> </dependency>
第二种
<dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
第三种
<dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
这三种写法中,第一种是标准和实现分开,后两种的组件是包括了标准和实现,本人推荐分开写的第一种,查阅了一些较为权威的开源程序(例如spring官方的spring-mvc-showcase),也是采用第一种写法的居多。
EL
EL的标准和实现
GlassFish版:
<dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> <version>3.0.0</version> </dependency>
Tomcat版:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-el-api</artifactId> <version>8.0.36</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper-el</artifactId> <version>8.0.36</version> </dependency>
注意,如果使用Tomcat作为部署容器,Tomcat已经集成了EL,而jsp在构建阶段(mvn clean package)是不会被编译的,所以使用Tomcat作为部署容器时,不需要加入EL表达式的依赖
一个完整的pom例子
最后,给一个使用Servlet 3.1, JSP 2.3, JSTL 1.2,以Tomcat 8.0.36作为部署容器的完整pom.xml
<project xmlns="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>cn.foo</groupId> <artifactId>bar</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <properties> <tomcat.version>8.0.36</tomcat.version> <jstl.version>1.2</jstl.version> </properties> <dependencies> <!-- Servlet --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <scope>provided</scope> <version>${tomcat.version}</version> </dependency> <!-- JSP --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> <scope>provided</scope> <version>${tomcat.version}</version> </dependency> <!-- JSTL --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>${jstl.version}</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jstl-impl</artifactId> <version>${jstl.version}</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
欢迎批评指正,全文完。
相关推荐
在Java Web开发中,`javax.servlet.jsp.jspl.core.ConditionalTagSupport`是JSTL(JavaServer Pages Standard Tag Library)库中的一个核心类,用于支持条件标签的实现。当你遇到`java.lang.NoClassDefFoundError: ...
在Maven项目中,如果要使用JSTL,可以在POM.xml文件中添加相应的依赖项,如下所示: ```xml <groupId>javax.servlet.jsp.jstl <artifactId>jstl <version>1.2 ``` 这样,Maven会自动下载并管理JSTL的相关依赖,...
1. 添加JSTL的依赖:在Maven或Gradle的配置文件中,添加JSTL的依赖库,或者在Web应用的WEB-INF/lib目录下手动放置对应的jar文件。 2. 引入JSTL标签库:在JSP页面顶部,通过`<%@ taglib %> `指令引入JSTL的核心库和...
在JSP页面中,我们可以通过EL(Expression Language)或JSTL(JavaServer Pages Standard Tag Library)来访问和操作Bean的属性。 JavaBean是一种符合特定规范的Java类,它具有默认构造器、getter和setter方法,...
在宿舍管理系统中,JSP主要负责展示用户界面,结合EL表达式和JSTL标签库,使得视图与控制逻辑分离,提高代码可维护性。 3. **Maven**:Maven是Java项目管理工具,用于构建、依赖管理和项目信息管理。在本系统开发...
在使用IntelliJ IDEA开发基于Maven的Web项目时,开发者可能会遇到JSTL(JavaServer Pages Standard Tag Library)标签在JSP页面中无法正常工作的问题。JSTL是一组支持JSP页面中常见任务的自定义标签库,比如迭代、...
4. **javax.servlet.jsp.jstl.sql.jar**:提供了数据库操作相关的标签,如 `<sql:update>`, `<sql:query>` 等,可以方便地在JSP页面中执行SQL查询和更新操作。 5. **javax.servlet.jsp.jstl.tlv.jar**:包含自定义...
在员工信息管理系统中,JSP页面用于展示数据和接收用户输入,与Servlet交互,将前端的用户交互转化为后端的Java逻辑处理。 **Servlet**: Servlet是Java提供的一种服务器端组件,用于扩展服务器的功能。在本系统中,...
对于现代的Maven或Gradle项目,可以在构建配置中声明这两个依赖。 总结来说,JSTL和EL是Java Web开发中的重要工具,它们提供了强大的标签和表达式功能,帮助开发者编写更清晰、更易维护的JSP页面。standard.jar和...
配置JSTL还需要在JSP页面中声明标签库,通常在页面顶部添加以下代码: ```jsp <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> ``` 这行代码声明了使用前缀“c”的JSTL核心库,其他库(如...
2. **配置web.xml**:在Web应用的`web.xml`配置文件中,需要声明JSTL的JAR文件,并启用JSP的EL支持。如下所示: ```xml <jsp-config> <taglib-uri>/WEB-INF/c.tld <taglib-location>/WEB-INF/c.tld ...
在JSP中使用JSTL,需要引入对应的jar包。这些jar包通常包括以下两个: - `jstl.jar`:包含了JSTL的核心标签库和其他基本功能。 - `standard.jar`:包含了Servlet API的标签库实现,如EL(Expression Language)的...
通常,这可以通过将它们放入WEB-INF/lib目录下,或者在Maven或Gradle等构建工具的依赖管理中进行配置来实现。一旦添加成功,我们就可以在JSP页面中自由地使用EL表达式和JSTL标签,从而提高开发效率和代码可读性。 ...
**JSTL(JavaServer Pages ...在JSP页面中,需要引入JSTL的核心库和EL(Expression Language)库。这通过`<%@ taglib %>`指令完成: ```jsp <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> ...
- **JspContext**:相当于Servlet中的ServletContext,但在JSP中,它被称为PageContext,提供了访问页面范围内的变量、表达式语言(EL)和JSP动作的接口。 - **Page指令**和**声明**:JSP页面的元数据,如导入的包、...
在Java Web开发中,JSTL(JavaServer Pages Standard Tag Library)是一个标准的标签库,它为JSP页面提供了一套强大的标签,用于处理常见任务,如迭代、条件语句、XML处理等,从而减少Java脚本的使用,提高代码的...
综合以上信息,"servlet/jsp 员工管理系统"是一个采用现代Java Web技术实现的管理应用,通过MVC架构实现了业务逻辑和显示逻辑的分离,利用注解简化了配置,使用JDBC处理数据存储,EL和JSTL增强了页面功能,而Maven则...
开发者可以在JSP页面中定义EL(Expression Language)表达式和JSTL(JavaServer Pages Standard Tag Library)标签,以简洁的方式处理数据和呈现动态内容。 系统架构方面,可能采用了MVC(Model-View-Controller)...
综上所述,配置JSTL 1.1.2涉及到将JSTL库和TLD文件引入项目,修改`web.xml`配置,并在JSP页面中使用JSTL标签。了解并熟练掌握这些步骤和相关标签,能够极大地提高JSP开发的效率和代码的可读性。
例如,在Maven中,你应添加如下依赖: ```xml <groupId>javax.servlet.jsp.jstl <artifactId>jstl <version>1.2 ``` 并确保有对应的`standard`库。 4. **Web应用配置问题**:在`WEB-INF/web.xml`文件中,...