Java EE 6 Web层综述:Servlet获得异步支持、扩展性改善

很多Java Web应用都是基于某个框架的,如Apache Wicket、Java ServerFaces、Struts或是Spring MVC等等。要想使用框架,开发者需要在应用的web.xml配置文件中注册框架的切入代码,如Servlet、Filter或是Listener。这么 做的后果就是部署描述符变得很庞大,同时导致框架所用的XML与特定于应用的XML混杂在了一起。Servlet 3.0规范的一个主要目标就是让开发者无需编辑web.xml部署描述符就能部署Servlet、Filter和Listener,同时可以将 web.xml文件拆分成多个模块。为了实现这一点,Servlet 3.0规范增加了基于注解的配置(@WebServlet、@ServletFilter以及@WebServletContextListener), 这使得我们可以不再需要web.xml文件,同时规范还引入了一个新的概念:Web片段(Web Fragment)。

Web片段可以将框架的“样板”XML与应用的其他配置分开,并且能够实现应用的自我注册。Web片段必须放在名为web- fragment.xml的文件中,该文件只要位于Web应用的classpath下即可,但通常都将其放到META-INF目录下或是框架的jar文件 中。XML以<web-fragment>元素开始,里面包含的元素与web.xml部署描述符大同小异。如下代码所示:

<web-fragment>
        <filter>
                <filter-name>MyXSSFilter</filter-name>
                <filter-class> MyXssFilter</filter-class>
        </filter>
        <servlet>
                <servlet-name>myFrameworkServlet</servlet-name>
                <servlet-class> MyFrameworkServlet</servlet-class>
        </servlet>
        <listener>
                <listener-class> MyFrameworkListener</listener-class>
        </listener>
</web-fragment>

容器在部署时会处理XML片段并组装成最终的部署描述符。由于容器负责组装web.xml文件,因此如果需要按照特定的顺序来调用框架的 Servlet、Listener或Filter时就可能产生问题。为了避免这个问题,Servlet 3.0 API支持绝对与相对顺序的部署描述符。我们可以在web.xml文件中使用<absolute-ordering>元素指定绝对顺序,这样 WEB-INF/lib下的每个jar都可以通过META-INF/web-fragment.xml文件的<name>元素获得一个名字。 接下来,Web应用的WEB-INF/web.xml文件可以通过<absolute-ordering>元素按照顺序列举出这些片段名,这 个顺序就是jar的调用顺序,同时还有一个可选的<others/>元素用于指定是否以及何时包含那些未命名的jar文件。由于部署者可以选 择只列出那些受信任的jar以进行部署,这样就可以避免意外情况的发生。除此之外,通过顺序还可以排除那些不需要被扫描的jar,这样就可以加快应用的部 署速度。最后,如果你不想在产品环境下看到自我注册的情况发生,那就可以在web.xml文件中使用<metadata-complete> 元素,这会告诉Web容器只去寻找注解而非Web片段。

由于既支持片段,又可以使用注解作为另一种配置机制,Servlet 3.0可以插入框架的共享拷贝,比如JAX-WS、JAX-RS以及JSF等,他们都构建在Web容器之上,使用了 ServletContainerInitializers。这些框架是通过jar services API被检测到的,同时还可以指定其处理的类型列表。对于WEB-INF/lib下的任何jar来说,只要其中包含的类被检测到都会传递给 ServletContainerInitializer。这样,我们还可以将同样的API作为ServletContextListeners。

从Servlet API首次发布以来,构建Web应用的方法发生了翻天覆地的变化,尤其是使用越来越多的异步Web技术。这些技术(一般统称为Ajax或是Web 2.0)对于Web客户端(比如浏览器)与服务器端之间的传输机制产生了重要的影响,因为客户端会在一个页面中向服务器端发出更多的请求而不是每次请求都 刷新一次页面。

长时间的服务器端处理会恶化这一情况,比如等待JDBC连接池中的连接,或是等待JMS队列中的消息等。在Servlet中等待实在是太低效了,因为这种 阻塞会消耗线程以及其他有限的系统资源。鉴于此,Servlet 3.0引入了异步处理请求的功能,这样线程就可以返回到容器中并执行其他任务。在请求上的异步处理开始时,其他线程或是回调既可以生成响应,也可以分发请 求以便通过AsyncContext.dispatch方法在容器上下文中执行请求。

由于异步Servlet的行为与同步的差别非常大,因此Servlet 3.0要求开发者指定asyncSupported=true以表示Servlet支持异步请求。不仅是Servlet,Filter也可以异步执行。 Servlet 3.0通过新的ServletRequest方法来支持异步处理,比如startAsync()会返回一个AsyncContext对象,该对象用于持有 传递给方法的request与response对象。这里,处理原始请求的线程还可以执行其他操作。此外,API还引入了一个新的Listener 类:AsyncListener,它会告诉我们异步操作何时结束或者是否超时了。AsyncContext类拥有一个complete()方法,凭借该方 法我们可以在异步操作结束后提交响应。AsyncListener类拥有一个dispatch()方法,它会将异步请求转发给容器,这样其他框架(比如 JSP)就可以生成响应了。

除了引入大量的新技术和新方法外,Servlet 3.0规范还对其他地方进行了大量的增强:HttpServletRequest终于获得对multipart/form-data MIME类型的内置支持了、Cookie类开始支持“HttpOnly” cookie以避免某些跨站点的脚本攻击、ServletContext API也得到了更新,我们可以通过编程的方式将Servlet和Filter加到上下文中了。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值