Servlet关联其他规范(第十五篇)

本文概述了JavaEE中的关键概念,如会话机制、Web应用的类加载和环境管理,以及安全措施如EJB调用安全和授权。重点讲解了部署描述符元素、注解和资源注入,包括@DeclareRoles、@EJB、@Resource等。同时涉及了CDI和依赖注入在现代JavaEE中的应用。
摘要由CSDN通过智能技术生成

本章列出了产品中还包含其他java技术的web容器的要求,在以下各节中,对 Java EE的任何引用不仅适用于完整的Java EE概要文件,而且适用于包括对Servlet的支持的任何概要文件,例如Java EE Web概要文件,有关概要文件的更多信息,请参考Java EE平台规范。

15.1、会话

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

15.2、Web应用

15.1.1、Web应用的类加载器

  • 属于Java EE产品一部分的Servlet容器不允许应用程序覆盖JavaSE或JavaEE不允许的Java SE或Java EE平台类,例如java.* 和javax.*名称空间中的那些类。

15.1.2、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容器应支持此行为,但当前不是必须的,此类要求将在本规范的下一版中添加,开发人员应注意,不建议将此功能依赖于应用程序创建的线程,因为它不可移植。

15.2.3、JNDI 名称是web模块的上下文Root URL

  • Java EE平台规范定义了一个标准化的全局JNDI命名空间和一系列相关的命名空间,它们映射到java EE应用程序的各种范围,应用程序可以使用这些命名空间来可移植地检索对组件和资源的引用。本部分定义了JNDI名称,用于注册Web应用程序的基本URL。

  • web应用程序上下文root预定义java.net.URL资料名称类,它遵循以下语法:

    • java:global[/<app-nam>]/<module-name>!ROOT  全局命名空间
      java:app/<module-name>!ROOT 应用具体命名空间
      
    • 仅当webapp打包在.ear文件中适用。

    • java:app前缀允许在Java EE应用程序中执行的组件访问特定于应用程序的命名空间,java:app名称允许企业应用程序中的模块引用同一个企业应用程序中另一个模型的上下文root,是java:app URL必须的部分。

  • 例子

    • 可以在应用程序中使用上述URL,如下所示:

    • 如果以模块名称myWebApp的形式独立部署web应用程序,则可以按如下所示将URL注入另一个web模块中:

      • 例子15-1

      • @Resource(lookup="java:global/myWebApp!ROOT")
        URL myWebApp;
        
      • 例子15-2,当打包成ear文件名为myApp 时,将如下使用

      • @Resource(lookup="java:global/myApp/myWebApp!ROOT")
        URL myWebApp;
        

15.3、安全

  • 本节详细介绍了Web容器在包含EJB、JACC或JASPIC的产品中包含的其他安全要求,以下各节列出了要求。

15.3.1、EJB调用时候需要传递安全验证

  • 必须始终提供安全标识或主体,以用于对企业bean的调用。从web应用程序调用企业Bean的默认模式是将Web用户的安全身份传播到EJB容器
  • 在其他情况下,需要web容器以允许web容器或EJB容器未知的web用户调用:
    • 需要web容器来支持尚未向容器进行身份验证的客户端,对web资源的访问,这是访问Internet上的web资源的常用模式。
    • 应用程序代码可能单个处理器处理单点登录和自定义数据
  • 在这些场景下,一个web应用部署描述符可能定义一个run-as元素,当一个run-as角色被指定到这个servlet上,在任何调用情况下,Servlet容器必须传递这个角色对应权限规则给EJB。包括Servlet的init和desroy方法,并且这个安全角色是定义在web应用中的。
  • web容器作为Java EE 平台运行一部分,使用run-as元素必须要支持同一应用EJB调用和其他应用EJB调用

15.3.2、容器授权要求

  • 在java EE产品或那些支持Java Authorization Contracts for Containers(JACC, 也就是JSR115 java 授权合同容器),所有这些Servlet容器必须实现支持JACC,这个JACC规范可以从以下地址获取:http://www.jcp.org/en/jsr/detail?id=115

15.3.3、容器验证要求

  • 在java EE产品或那些支持Java Authentication SPI for Contracts for Containers(JASPIC, 也就是JSR196 java 授权合同容器),所有这些Servlet容器必须实现支持JASPIC,这个JASPIC规范可以从以下地址获取:http://www.jcp.org/en/jsr/detail?id=196

15.4、部署

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

15.4.1、部署描述元素

  • web应用程序部署描述符中存在以下附加元素,以满足启用JSP页面或Java EE应用程序服务器的Web容器的要求,他们并不需要被容器支持,仅支持servlet规范就可以了。
    • jsp-config
    • 声明资源引用元素(env-entry,ejb-local-ref, resource-ref, resource-env-ref)
    • 定义消息目的地元素(message-destination,message-destination-ref)
    • 引用web服务(service-ref)
    • 引用持久化上下文(persistence-context-ref)
    • 引用持久化单元(persistence-unit-ref)

15.4.2、打包和部署JAX-WS组件

  • Web容器可以选择支持正在运行的组件,这些组件为实现由JAX-RPC或JAX-WS规范定义的web服务端点而编写的,嵌入Java EE兼容实现中的web容器对于支持JAX-RPC和JAX-WS Web服务组件是必须的,本节描述了当前web容器包含在支持JAX-RPC和JAX-WS的产品中时,web容器的打包和部署模型。
  • 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。该API定义了其与启用JAX-WS或JAX-RPC的web容器协议。它被打包到WAR文件中,web服务开发人员使用通常的声明对此组件进行声明。
  • 启用JAX-WS和JAX-RPC的Web容器必须支持开发人员使用web部署描述符为端点实现组件定义以下信息,并使用与使用Servlet元素的HTTP Servlet组件相同的语法,子元素用于通过以下方式指定端点信息:
    • servlet-name元素定义了一个逻辑名称,该逻辑名称可用于在WAR中的其他web组件之间定位此端点描述
    • servlet-class 元素需要提供全限定类名表示端点实现
    • description元素可以描述组件,可能被展示在本地工具中
    • load-on-startup 元素指定组件初始化相对其他web组件的顺序
    • run-as 元素可能被重写到EJB调用的身份验证
  • 容器可能会忽略开发人员为此web组件定义的任何servlet的初始化参数,此外,启用了JAX-WS和JAX-RPC的web组件继承了用于定义以下信息的传统web组件机制:
    • mapping 映射连接到web容器的url命名空间使用servlet 映射的技术
    • web组件的授权限制使用的安全限制
    • 使用servlet过滤器为以下内容提供低级字节流支持的能力,使用过滤器映射来操纵JAX-WS和JAX-RPC消息技术
    • 组件HTTP相关联的任何HTTP会话超时特征
    • JNDI命名空间保存Java EE 对象。

15.4.3、处理部署描述的规则

  • 需要使用容器和工具作为java EE技术的兼容实现,才能针对XML模式验证部署描述,以确保结构正确。建议进行验证,但对于不属于Java EE技术的实现中的Web容器和工具,则不需要进行验证。

15.5、注解和资源注入

  • Java元数据规范(JSR-175),它是J2SE 5.0以及以后版本一部分,java代码提供指定和配置,java的元数据可以引用作为注解。在Java EE中,注解被用于声明外部资源依赖和配置数据(这样就不需定义数据到配置文件中)

  • Java EE 注解行为和资源注入符合servlet容器,这个节是扩展在java EE 规范第5章标题为“资源,命名和注入”

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

  • 组件和接口支持注解和依赖注入

    • 组件类型类实现以下接口
      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容器执行资源注入。

    • 组件实例可以被应用获取,在调用任何生命周期方法和使用之前注入引用,

    • 对于注入的资源的位置可以是WEB-INF/classes目录,或者是打包到jar文件中位于WEB-INF/lib路径中。

    • 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文件,必须忽略在WEB-INF/classes带这些注解(@WebServlet, @WebFilter, @WebListener)类、web-fragment.xml、WEB-INF/lib资源,如果metadata-complete属性没有设置为false,上面忽略数据都会被扫描到。

    • web-fragment.xml也可能存在metadata-complete元素标签,如果设置为true,也是忽略fragment相关注解类,跟web.xml类似。

15.5.1、@DeclareRoles

  • 此注解用于定义构成应用程序安全模型的安全角色。此注解是在类上指定的,并且用于定义可以从带注解的类的方法中进行测试的角色(即通过调用isUserInRole),由于在@RolesAllowed中使用隐式声明的角色,无需使用@DeclareRoles注解显式声明。@DeclareRoles批注只能在实现javax.servlet.Servlet接口或子类的类中定义。

  • 下面的例子展示如何使用这个注解

    • 例子15-3 @DeclareRoles例子

    • @DeclareRoles("BusinessAdmin")
      public class CalculatorServlet{
        
      }
      
    • 例子15-4 等同上面功能,只是配置在web.xml

    • <web-app>
      	<security-role>
        	<role-name>BusinessAdmin</role-name>
        </security-role>
      </web-app>
      
  • 此注解不用于将应用程序角色充重新链接到其他角色,当需要这种链接时,可以通过在关联的部署描述符中定义适当的security-role-ref来实现。

  • 当从带注解的类中调用isUserInRole时,将测试与该类的调用相关联的调用者身份,以查找与isCallerInRole的参数名称相同的角色中的成员身份,如果已经为参数role-name定义了安全角色引用,则将测试调用方法是否具有映射到角色名称的角色的成员资格。

  • 对于更多关于@DeclareRoles的信息,可以参考 Common Annotation for java platform specification(JSR 250)

15.5.2、@EJB注解

  • 可以使用@EJB注解从WEb组件引用的Enterprise JavaBeans$^{TM}$3.2(EJB)组件。@EJB注解提供了与在部署描述符中声明ejb-ref或ejb-local-ref元素等效的功能,具有相应@EJB注解的字段将带有对应EJB组件的引用。

  • 例子

    • @EJB 
      private ShoppingCart myCart;
      
  • 在上述情况下,在声明注入可用的类之前,将对EJB组件“myCart”的引用做为私有字段“myCart"的值进行注入。

  • @EJB注解进一步了解可以参考EJB3.2规范(JSR345) 第11.5.1节

15.5.3、@EJBs注解

  • @EJBs注解允许多个@EJB注解到单个资源上

  • 例子 15-5

    • @EJBs({@EJB(Calculator), @EJB(ShopingCart)})
      public  class ShopingCartServlet{
        
      }
      
    • EJB 组件ShoppingCart和Calculator注入到ShoppingCartServlet中,ShoppingCartServlet仍必须使用JNDI查找引用,但是EJB不需要在web.xml文件中声明。

15.5.4、@Resource 注解

  • @Resource注解被用于声明资源的引用,例如data数据,Java Messaging Service (JMS)目的地,或环境变量,这个注解等同于配置在部署描述符的resource-ref, message-destination-ref 或env-ref 或 resource-env-ref元素。

  • @Resource注解在类上、方法或字段上指定。容器负责注入对@Resource注解声明的资源的引用,并将其映射到适当的JNDI资源,有关更多详情信息,请参见Java EE规范第5章。

  • @Resource例子 15-6

    • @Resource
      private javax.sql.DataSource catalogDS;
      public getProductByCategory(){
        //获取连接,执行查询
        Connection conn = catalogDS.getConnection();
      }
      
    • 上面示例代码中,一个servlet,过滤器或监听器声明一个javax.sql.DataSource类型的字段catalogDS,在组件可供应程序使用之前,容器已经为字段注入了对数据源的引用。数据源JNDI映射是从字段名称”catalogDS"和类型(javax.sql.DataSource)推断出来的,此外,不再需要在部署描述符中定义catlogDS资源

    • 对于更多关于@Resource的信息,可以参考 Common Annotation for java platform specification(JSR 250)

15.5.5、@PersistenceContext注解

  • 该注解引用的持久性单元指定容器管理的实体管理器

  • 例子 15-7

    • @PersistenceContext(type=EXTENDED)
      EntityManager em;
      
  • 了解更多@PersistenceContext注解行为参考Java Persistence API 2.1版本(JSR 338)的10.5.1规范

15.5.6、@PersistenceContexts 注解

  • 允许多个@PersistenceContext注解

15.5.7、@PersistenceUnit 注解

  • @PersistenceUnit注解提供了在Servlet中声明的Enterprise Java Beans组件对实体管理器工厂的引用。实体管理器工厂绑定到单独的persistence.xml配置文件。如EJB3.2规范(JSR345)的11.10节所述。

  • 例子 15-8

  • @PersistenceUnit
    EntityManagerFactory emf;
    
  • 了解更多@PersistenceUnit注解行为参考Java Persistence API 2.1版本(JSR 338)的10.5.2规范

15.5.8、@PersistencUnits注解

  • 允许多个@PersistenceUnit

15.5.9、@PostConstruct 注解

  • @PostConstruct注解在不带任何参数的方法上声明,并且不得引发任何检查异常,返回值为空,必须在资源注入完成之后并且在组件上的任何生命周期方法被调用之前,调用该方法。

  • 例子 15-9 @PostConstruct

  • @PostConstruct
    public void postConstruct(){
      // 初始化完成之后调用这个方法
    }
    
  • 所有支持依赖注入的类都必须支持@PostConstruct注解,即使该类不要求注入任何资源,也必须调用@PostConstruct注解,如果该方法抛出未检查的异常,则该类一定不能投入使用,并且该实例上的任何方法都不能调用。

  • 详情可以参考Java EE规范 第2.5节和common Annotations for the Java T M ^{TM} TM Platform T M ^{TM} TM 第2.5节。

15.5.10、@PreDestroy注解

  • @PreDestroy注解在容器托管组件的方法上声明,在容器删除组件之前调用该方法。

  • 例子15-10

  • @PreDestroy
    public void clearup(){
      // 清除任何打开的资源
      
    }
    
  • 带有@PreDestroy注解的方法返回void,必须不能抛出一个检查异常,这个方法必须是public,protected,package private 或private. 这个方法不能是静态的,可以是final修饰的

  • 详情参看JSR250 第2.6节

15.5.11、@Resources 注解

  • @Resources注解充当多个@Resource注解的容器,因为Java MetaData规范不允许在同一注解目标上使用多个具有相同名称的注解。

  • 例子 15-11

  • @Resources({
      @Resource(name="myDB", type=javax.sql.DataSource),
      @Resource(name="myMQ", type=javax.jms.ConnectionFactory)
    })
    public class CalculatorSerlvet{
      
    }
    
  • @上述例子表示,JMS连接工厂和数据源连接都是可以被CalculatorServlet使用

  • 对于更多关于@Resources的信息,可以参考 Common Annotation for java platform specification(JSR 250)

15.5.12、@RunAs注解

  • @RunAs注解等同于在部署描述符中的run-as元素,@RunAs注解实现javax.servlet.Servlet接口和子类

  • 例子15-12

  • @RunAs("Admin")
    public class CalculatorServlet{
      @EJB
      private ShoppingCart myCart;
      public void doGet(HttpServletRequest req, HttpServletResponse res){
        // 
        myCart.getTotal();
      }
    }
    
  • 等同于上面java类注解

  • <servlet>
    	<servlet-name>CalculatorServlet</servlet-name>
      <run-as>Admin</run-as>
    </servlet>
    
  • 这个例子展示了当myCart.getTotal()调用的时候,servlet使用@RunAs注解将Admin这个安全验证传递给EJB组件,详情查看15.3.1、EJB调用时候需要传递安全验证

  • 了解更多@RunAs注解,可以参考 Common Annotation for java platform specification(JSR 250)第2.7节

15.5.13、@WebServiceRef注解

  • 在web应用中@WebServiceRef注解提供引用web服务左右,于此类似在部署描述符配置resource-ref元素。

  • 例子 15-13

  • @WebServiceRef
    private MyService service;
    
  • 了解更多@WebServiceRef信息,参考JAX-W规范(JSR 224)第7节

15.5.14、@WebServiceRefs注解

  • 允许多个@WebServiceRef注解

15.5.15、对于Java EE 上下文和依赖注入要求。

  • 在支持java EE 上下文和依赖注入(CDI)【Contexts and Dependency Injection】并且启用了CDI的产品中,实现必须支持CDI托管Bean使用。Servlet、过滤器、监听器和HttpUpgradeHandlers务必支持CDI注入和拦截器的使用。如java EE 7 平台规范”对依赖注入的支持“中所述。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值