Servlet规范之与其他规范有关的要求

Posted 顧棟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet规范之与其他规范有关的要求相关的知识,希望对你有一定的参考价值。

与其他规范有关的要求

文章目录


本章列出了对 Web 容器的要求,这些容器被包含在也包含其他 Java 技术的产品中。

在下面的章节中,任何对Java EE的引用不仅适用于完整的Java EE配置文件,也适用于包括对Servlet支持的任何配置文件,如Java EE Web配置文件。关于配置文件的更多信息,请参考Java EE平台规范。

Sessions

作为Java EE实现一部分的分布式servlet容器必须支持将其他Java EE对象从一个JVM迁移到另一个JVM所必需的机制。

Web Applications

Web 应用程序类加载器

作为Java EE产品一部分的Servlet容器不应允许应用程序覆盖Java SE或Java EE平台的类,如java.*javax.*命名空间中的类,这些类是Java SE或Java EE不允许修改的。

Web 应用程序环境

Java EE定义了一个命名环境,允许应用程序轻松地访问资源和外部信息,而无需明确了解外部信息是如何命名或组织的。

由于servlet是Java EE技术的一个完整的组件类型,在Web应用部署描述符中规定了允许servlet获得对资源和企业bean的引用的信息。包含这种信息的部署元素是:

  • env-entry
  • ejb-ref
  • ejb-local-ref
  • resource-ref
  • resource-env-ref
  • service-ref
  • message-destination-ref
  • persistence-context-ref
  • persistence-unit-ref

开发者使用这些元素来描述Web应用程序在运行时需要在Web容器的JNDI命名空间中注册的某些对象。

关于Java EE环境的设置要求,在《Java EE规范》的第5章中有所描述。

作为符合Java EE技术的实现的一部分的Servlet容器需要支持这种语法。请查阅《Java EE规范》以了解更多细节。当在由servlet容器管理的线程上执行时,这种类型的servlet容器必须支持对这种对象的查找和对这些对象的调用。当在开发者创建的线程上执行时,这种类型的servlet容器应该支持这种行为,但目前不要求这样做。这样的要求将在本规范的下一个版本中加入。要提醒开发者的是,不建议对应用程序创建的线程依赖这种能力,因为它是不可移植的。

Web 模块上下文根网址的JNDI名称

Java EE平台规范定义了一个标准化的全局JNDI命名空间和一系列相关的命名空间,这些命名空间映射到Java EE应用程序的各种作用域。这些命名空间可以被应用程序用来可移植地检索对组件和资源的引用。本节定义了JNDI名称,Web应用程序的基本URL需要通过这些名称来注册。

Web应用程序的上下文根目录的预定义java.net.URL资源的名称有以下语法。

java:global[/<app-name>]/<module-name>!ROOT表示在全局命名空间中,java:app/<module-name>!ROOT表示在特定应用命名空间中。

请参阅EE 8.1.1节(组件创建)和EE 8.1.2节(应用程序组装),以了解确定应用程序名称和模块名称的规则。

<app-name>只适用于webapp被打包在.ear文件中的情况。

java:app前缀允许在Java EE应用程序中执行的组件访问应用程序特定的命名空间。java:app名称允许企业应用中的一个模块引用同一企业应用中另一个模块的上下文根。<module-name>java:app url语法中的一个必要部分。

Examples

然后,上述URL可以在一个应用程序中使用,如下所示:

如果一个Web应用程序是独立部署的,module-namemyWebApp.那么这个URL可以被注入到另一个web模块,如下所示:

CODE EXAMPLE 15-1

@Resource(lookup=“java:global/myWebApp!ROOT)

URL myWebApp;

当打包在一个名为myApp的ear文件中时,它可以按如下方式使用:

CODE EXAMPLE 15-2

@Resource(lookup=“java:global/myApp/myWebApp!ROOT)

URL myWebApp;

安全性

本节详细介绍了在包含EJB、JACC或JASPIC的产品中,对Web容器的额外安全要求。下面几节列出了这些要求

EJB™调用中安全身份的传播

在调用企业Bean时,必须始终提供安全身份或委托人,以便使用。从 Web 应用程序调用企业 bean 的默认模式是将 Web 用户的安全身份传播给 EJB 容器。

在其他情况下,要求 Web 容器允许 Web 容器或 EJB 容器不知道的 Web 用户进行调用。

  • 网络容器需要支持那些没有对容器进行身份验证的客户对网络资源的访问。这是互联网上访问网络资源的常见模式。
  • 应用程序代码可能是基于调用者身份的签到和定制数据的唯一处理器。

在这些情况下,网络应用程序部署描述符可以指定一个run-as元素。当为Servlet指定run-as角色时,Servlet容器必须在从Servlet到EJBs的任何调用中传播映射到该角色的本金作为安全身份,包括来自Servlet的init和destroy方法的调用。安全角色名称必须是为Web应用程序定义的安全角色名称之一。

对于作为Java EE平台的一部分运行的Web容器,必须支持使用 "run-as"元素来调用同一Java EE应用程序中的EJB组件,以及调用部署在其他Java EE应用程序中的EJB组件。

容器授权的要求

在Java EE产品或包括支持容器的Java授权合同(JACC,即JSR 115)的产品中,所有Servlet容器必须实现对JACC的支持。JACC规范可在http://www.jcp.org/en/jsr/detail?id=115下载。

容器认证的要求

在Java EE产品中,或包括支持The Java Authentication SPI for Containers(JASPIC,即JSR 196)的产品中,所有Servlet容器都必须实现JASPIC规范的Servlet容器配置文件。JASPIC规范可在http://www.jcp.org/en/jsr/detail?id=196下载。

部署

本节详细介绍了符合 Java EE 技术的容器和包括对 JSP 和或 Web 服务支持的产品的部署描述符、打包和部署描述符处理要求。

部署描述符的元素

在Web应用程序部署描述符中存在以下额外的元素,以满足支持JSP页面的Web容器或Java EE应用服务器的一部分的要求。希望只支持Servlet规范的容器不需要支持这些元素:

  • jsp-config
  • 声明资源引用的语法 (env-entry, ejb-ref, ejb-local-ref, resource-ref, resource-env-ref)
  • 用于指定消息目的地的语法 (message-destination, message-destination-ref)
  • 对一个Web服务的引用 (service-ref)
  • 对一个持久化上下文的引用 (persistence-context-ref)
  • 对持久化单元的引用 (persistence-unit-ref)

这些元素的语法现在被保留在JavaServer Pages规范2.2版和Java EE规范中。

JAX-WS组件的打包和部署

Web 容器可以选择支持运行为实现 JAX-RPC、JAX-WS 规范所定义的 Web 服务端点而编写的组件。嵌入 Java EE 符合性实现中的 Web 容器需要支持 JAX-RPC 和 JAX-WS Web 服务组件。本节描述了当 Web 容器包含在同时支持 JAX-RPC 和 JAX-WS 的产品中时的打包和部署模型。

JSR-109 [http://jcp.org/jsr/detail/109.jsp] 定义了用于打包 Web 服务接口及其相关 WSDL 描述和相关类的模型。它为支持 JAX-WS 和 JAX-RPC 的 Web 容器定义了一种机制,以链接到实现该 Web 服务的组件。JAX-WS 或 JAX-RPC Web 服务实现组件使用 JAX-WS 和/或 JAX-RPC 规范所定义的 API,它定义了它与 JAX-WS 和/或启用 JAX-RPC 的 Web 容器的契约。它被打包到 WAR 文件中。Web 服务开发者使用通常的 <servlet> 声明对该组件进行声明。

JAX-WS 和启用 JAX-RPC 的 Web 容器必须支持开发者使用 Web 部署描述符来定义端点实现组件的以下信息,使用的语法与使用 servlet 元素的 HTTP Servlet 组件相同。子元素用于以下列方式指定端点信息:

  • servlet-name元素定义了一个逻辑名称,可以用来在WAR中的其他Web组件中定位这个端点描述。
  • servlet-class元素提供了该端点实现的完全合格的Java类名称。
  • description元素可用于描述该组件,并可在工具中显示。
  • load-on-startup元素指定了组件相对于Web容器中其他Web组件的初始化顺序。
  • security-role-ref元素可用于测试认证用户是否处于一个逻辑安全角色中。
  • run-as元素可用于覆盖传播给由该组件调用的EJB的身份。

开发者为该 Web 组件定义的任何 servlet 初始化参数都可能被容器忽略。此外,启用了 JAX-WS 和 JAX-RPC 的 Web 组件继承了传统的 Web 组件机制,用于定义以下信息。

  • 使用 servlet 映射技术将该组件映射到 Web 容器的 URL 命名空间中
  • 使用安全约束对Web组件进行授权约束
  • 使用servlet过滤器提供低级别的字节流支持的能力,以便使用过滤器映射技术操纵JAX-WS和/或JAX-RPC消息
  • 与组件相关的任何 HTTP 会话的超时特性
  • 与存储在JNDI命名空间中的Java EE对象的链接

所有上述要求都可以使用第 8.2 节 “Pluggability”(第 8-71 页)中定义的可插拔机制来满足。

部署描述符的处理规则

作为符合 Java EE 技术的实施的一部分的容器和工具被要求根据 XML 模式验证部署描述符的结构正确性。对于不属于 Java EE 技术兼容实施的 Web 容器和工具,建议进行验证,但不是必须的。

注解和资源注入

Java元数据规范(JSR-175)是J2SE 5.0及以后版本的一部分,它提供了一种在Java代码中指定配置数据的方法。Java代码中的元数据也被称为注解。在 Java EE 中,注解被用来在 Java 代码中声明对外部资源和配置数据的依赖性,而不需要在配置文件中定义这些数据。

本节描述了在符合Java EE技术的Servlet容器中注释和资源注入的行为。本节是对Java EE规范中题为 "资源、命名和注入 "的第5节的扩展。

以下容器管理类必须支持注解,这些类实现了以下接口,并在 Web 应用程序部署描述符中声明或使用第 8-67 页上的第 8.1 节 "注解和可插拔性 "中定义的注解,或以编程方式添加。

TABLE 15-1 支持注解和依赖注入的组件和接口

Component TypeClasses implementing the following interfaces
Servletsjavax.servlet.Servlet
Filtersjavax.servlet.Filter
Listenersjavax.servlet.ServletContextListener
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
javax.servlet.http.HttpSessionIdListener
javax.servlet.AsyncListener

Web 容器不需要对发生在表 15-1 中所列类之外的注释进行资源注入。

引用必须在任何生命周期方法被调用和组件实例被提供给应用程序之前被注入。

在Web应用程序中,使用资源注入的类只有在它们位于WEB-INF/classes目录下,或者它们被打包在位于WEB-INF/lib的jar文件中时,才会被处理其注释。容器可以选择性地处理应用程序classpath中其他地方的类的资源注入注释。

web应用程序部署描述符在web-app元素上包含一个metadata-complete属性。metadata-complete属性定义了web.xml描述符是否完整,或者是否应该考虑部署过程使用的其他元数据来源。元数据可能来自web.xml文件、web-fragment.xml文件、WEB-INF/classes中类文件的注释、以及WEB-INF/lib目录中jar文件的类注释。如果metadata-complete设置为 “true”,部署工具只检查web.xml文件,必须忽略诸如@WebServlet@WebFilter@WebListener等存在于应用程序类文件中的注释,还必须忽略任何web-fragment.xml描述符打包在WEB-INF/lib中的jar文件。如果没有指定metadata-complete属性或将其设置为 “false”,部署工具必须检查类文件和web-fragment.xml文件的元数据,如之前指定的那样。

web-fragment.xml也包含web-fragment元素上的metadata-complete属性。该属性定义了web-fragment.xml描述符对于给定的片段是否完整,或者它是否应该扫描相关jar文件中的类的注释。如果metadata-complete设置为 “true”,部署工具只检查web-fragment.xml,并且必须忽略注释,如@WebServlet, @WebFilter@WebListener存在于片段的类文件中。如果没有指定metadata-complete或者设置为 “false”,部署工具必须检查类文件的元数据。

以下是符合Java EE技术的Web容器所需的注释。

@DeclareRoles

该注解用于定义构成应用程序安全模型的安全角色。这个注解被指定在一个类上,它被用来定义可以从注解类的方法中测试的角色(即通过调用isUserInRole)。由于在"@RolesAllowed"中使用而被隐式声明的角色不需要使用"@DeclareRoles"注解来明确声明。@DeclareRoles注解只能在实现javax.servlet.Servlet接口的类或其子类中定义。

Following is an example of how this annotation would be used.

CODE EXAMPLE 15-3 @DeclareRoles Annotation Example

@DeclareRoles("BusinessAdmin")
public class CalculatorServlet 
//...

声明@DeclareRoles(“BusinessAdmin”)相当于在web.xml中定义如下。

CODE EXAMPLE 15-4 @DeclareRoles web.xml

<web-app>
    <security-role>
    	<role-name>BusinessAdmin</role-name>
    </security-role>
</web-app>

这个注解不用于将应用程序角色重新链接到其它角色。当这种链接是必要的,它是通过在相关的部署描述符中定义一个适当的安全角色引用来完成的。

当从被注释的类中调用isUserInRole时,与调用该类相关的调用者身份将被测试是否属于与isCallerInRole的参数相同名称的角色。如果为参数role-name定义了security-role-ref,则测试调用者是否属于映射到role-name的角色。

关于"@DeclareRoles "注解的更多细节,请参考Java™ Platform™规范(JSR 250)第2.12节的通用注解。

@EJB Annotation

Enterprise JavaBeans™ 3.2 (EJB)组件可以使用@EJB注解从Web组件中引用。@EJB注解提供了与在部署描述符中声明ejb-refejb-local-ref元素相当的功能。具有相应的@EJB注解的字段被注入到相应的EJB组件的引用。

An example:

@EJB private ShoppingCart myCart;

在上面的例子中,对EJB组件 "myCart "的引用被注入,作为私有字段 "myCart "的值,在声明注入的classs被提供之前。

@ EJB注解的行为在EJB 3.2规范(JSR 345)的第11.5.1节中进一步详细说明。

@EJBs Annotation

The @EJBs annotation allows more than one @EJB annotations to be declared on a single resource.

@EJBs注解允许在一个资源上声明一个以上的@EJB注解。

An example:

CODE EXAMPLE 15-5 @EJBs Annotation Example

@EJBs(@EJB(Calculator), @EJB(ShoppingCart))
public class ShoppingCartServlet 
//...

上面的例子中,EJB组件ShoppingCartCalculator被提供给ShoppingCartServlet使用。ShoppingCartServlet仍然必须使用JNDI查找参考,但EJB不需要在web.xml文件中声明。

@Resource Annotation

@Resource注解用于声明对资源的引用,如数据源、Java消息传递服务(JMS)目的地或环境条目。这个注解相当于在部署描述符中声明一个resource-refmessage-destination-refenv-ref,或resource-env-ref元素。

@Resource注解被指定在类、方法或字段上。容器负责注入对@Resource注解所声明的资源的引用,并将其映射到适当的JNDI资源。更多细节请参见《Java EE规范》第5章。

An example of a @Resource annotation follows:

CODE EXAMPLE 15-6 @Resource Example

@Resource private javax.sql.DataSource catalogDS;
public getProductsByCategory() 
    // get a connection and execute the query
    Connection conn = catalogDS.getConnection();
    ..

在上面的示例代码中,servlet、过滤器或监听器声明了一个类型为javax.sql.DataSource的字段catalogDS,在组件对应用程序可用之前,容器注入了对数据源的引用。数据源的JNDI映射是由字段名 "catalogDS "和类型(javax.sql.DataSource)推断出来的。此外,catalogDS资源不再需要在部署描述符中定义。

@Resource注解的语义在Java™ Platform™规范(JSR 250)第2.3节和Java EE 7规范5.2.5中进一步详细说明。

@PersistenceContext Annotation

该注解为被引用的持久化单元指定了容器管理的实体管理器。

An example:

CODE EXAMPLE 15-7 @PersistenceContext Example

@PersistenceContext (type=EXTENDED)
EntityManager em;

@PersistenceContext注解的行为在Java Persistence API, Version 2.1 (JSR 338)的10.5.1节中进一步详细说明。

@PersistenceContexts Annotation

PersistenceContexts注解允许在一个资源上声明一个以上的@PersistenceContext。`@PersistenceContexts’注解的行为在Java Persistence API, version 2.1 (JSR 338)的10.5.1节中进一步详细说明。

@PersistenceUnit Annotation

@PersistenceUnit注解为在servlet中声明的Enterprise Java Beans组件提供对实体管理器工厂的引用。如EJB 3.2规范(JSR 345)第11.10节所述,实体管理工厂被绑定到一个单独的persistence.xml配置文件中。

An example:

CODE EXAMPLE 15-8 @PersistenceUnit Example

@PersistenceUnit
EntityManagerFactory emf;

@PersistenceUnit注解的行为在Java Persistence API, version 2.1 (JSR 338)的10.5.2节中进一步详细说明。

@PersistenceUnits Annotation

这个注解允许在一个资源上声明一个以上的@PersistentUnit注解。@PersistenceUnits注解的行为在Java Persistence API, version 2.1 (JSR 338)第10.5.2节中进一步详细说明。

@PostConstruct Annotation

@PostConstruct注解被声明在一个不需要任何参数的方法上,并且不能抛出任何检查过的异常。其返回值必须是无效的。该方法必须在资源注入完成后,在组件的任何生命周期方法被调用之前被调用。

An example:

CODE EXAMPLE 15-9 @PostConstruct Example

@PostConstruct
public void postConstruct() 
...

上面的例子显示了一个使用@PostConstruct注解的方法。

所有支持依赖注入的类都必须支持@PostConstruct注解,即使该类没有请求注入任何资源,也要调用该注解。如果该方法抛出一个未被选中的异常,那么该类必须不被投入服务,并且该实例上的任何方法都不能被调用。更多细节请参考 Java EE 规范第 2.5 节和 Java™ Platform™ 规范第 2.5 节的通用注解。

@PreDestroy Annotation

@PreDestroy注解被声明在一个容器管理的组件的方法上。该方法在组件被容器删除之前被调用。

An example:

CODE EXAMPLE 15-10 @PreDestroy Example

@PreDestroy
public void cleanup() 
// clean up any open resources
...

带有@PreDestroy注解的方法必须无返回,并且不能抛出一个检查过的异常。该方法可以是public、protected、package或private。该方法不能是静态的,但是它可以是最终的。

更多细节请参考JSR 250第2.6节。

@Resources Annotation

@Resources注解作为多个@Resource注解的容器,因为Java MetaData规范不允许在同一个注解目标上有多个同名注解。

An example:

CODE EXAMPLE 15-11 @Resources Example

@Resources (
@Resource(name=”myDB” type=javax.sql.DataSource),
@Resource(name=”myMQ” type=javax.jms.ConnectionFactory)
)

CODE EXAMPLE 15-11 @Resources Example

public class CalculatorServlet 
//...

在上面的例子中,一个JMS连接工厂和一个数据源通过@Resources注解被提供给CalculatorServlet

`@Resources’注解的语义在Java™平台通用注解规范(JSR 250)第2.4节中进一步详细说明。

@RunAs Annotation

@RunAs注解等同于部署描述符中的run-as元素。@RunAs注释只能在实现javax.servlet.Servlet接口的类或其子类中定义。

An example:

CODE EXAMPLE 15-12 @RunAs Example

@RunAs(Admin)
public class CalculatorServlet 

    @EJB private ShoppingCart myCart;
    public void doGet(HttpServletRequest, req, HttpServletResponse res) 
        //....
        myCart.getTotal();
        //....
    
    //....

@RunAs("Admin")语句相当于在web.xml中定义以下内容。

CODE EXAMPLE 15-13 @RunAs web.xml Example

<servlet>
    <servlet-name>CalculatorServlet</servlet-name>
    <run-as>Admin</run-as>
</servlet>

上面的例子显示了当调用myCart.getTotal()方法时,servlet如何使用@RunAs注解将安全身份 "Admin "传播给EJB组件。关于传播身份的更多细节,请参见15.3.1节 “EJB™调用中安全身份的传播”(15-186页)。

关于"@RunAs "注解的更多细节,请参考Java™ Platform™规范的通用注解(JSR 250)第2.7节。

@WebServiceRef Annotation

@WebServiceRef注解在Web组件中提供对Web服务的引用,其方式与部署描述符中的resource-ref元素相同。

An example:

@WebServiceRef private MyService service;

在这个例子中,对网络服务"MyService"的引用将被注入到声明该注解的类中。

这个注解和行为在JAX-WS规范(JSR 224)第7节中有进一步的说明。

@WebServiceRefs Annotation

这个注解允许在一个资源上声明多个@WebServiceRef注解。该注解的行为在 JAX-WS 规范(JSR 224)第 7 节中有进一步的详细说明。

针对Java EE需求的上下文和依赖注入

在支持 Java EE 的上下文和依赖注入(CDI)并启用了 CDI 的产品中,实现必须支持使用 CDI 管理的 Bean。Servlets、过滤器、监听器和 HttpUpgradeHandlers 必须支持 CDI 注入和使用拦截器,如 Java EE 7 平台规范的第 EE.5.24 节 "Support for Dependency Injection"中所述。

以上是关于Servlet规范之与其他规范有关的要求的主要内容,如果未能解决你的问题,请参考以下文章

【ceph】对象存储 - bucket命名规范

Jetty 和其他容器如何在遵守 Servlet 规范的同时利用 NIO?

Servlet

Servlet规范之预览

如何写出规范的JavaScript代码

Servlet的历史与规范