Servlet 2.5和3之间有哪些区别?

98

我正在编写遵循Servlet 2.5的J2EE代码,想知道2.5和3之间的主要区别。最好提供官方Sun文档和个人经验。

如果我暂时不需要关注3,请告诉我。谢谢!


2
+1 等待回答中 :) - ATorras
4个回答

157

更新

为了更明确地说明,以下是servlet 2.5和3之间的主要区别(我不是在详尽阐述,只是提到最有趣的部分):

使用注释声明servlet、过滤器和监听器(便于开发)

在servlet 2.5中,如果要声明一个具有一个初始化参数的servlet,则需要将其添加到web.xml中:

<servlet>
    <servlet-name>myServlet</servlet-name>
    <servlet-class>my.server.side.stuff.MyAwesomeServlet</servlet-class>
    <init-param>
        <param-name>configFile</param-name>
        <param-value>config.xml</param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>myServlet</servlet-name>
    <url-pattern>/path/to/my/servlet</url-pattern>
</servlet-mapping>
在Servlets 3中,web.xml是可选的,您可以使用注释替代XML。相同的示例:
@WebServlet(name="myServlet",
    urlPatterns={"/path/to/my/servlet"},
    initParams={@InitParam(name="configFile", value="config.xml")})
public class MyAwesomeServlet extends HttpServlet { ... }

过滤器需要在servlets 2.5的web.xml中添加:

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>my.server.side.stuff.MyAwesomeServlet</filter-class>
</filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/path/to/my/filter</url-pattern>
</filter-mapping>

使用Servlets 3中的注释实现相同效果:

@ServletFilter(name="myFilter", urlPatterns={"/path/to/my/filter"})
public class MyAwesomeFilter implements Filter { ... }

在 Servlet 2.5 中,对于一个监听器(在本例中是 ServletContextListener):

<listener>
    <listener-class>my.server.side.stuff.MyAwesomeListener</listener-class>
</listener>

使用注释的方式:

@WebServletContextListener
public class MyAwesomeListener implements ServletContextListener { ... }

Web.xml的模块化(插件化)

  • 在Servlets 2.5中,只有一个庞大的web.xml文件。
  • 在Servlets 3中,每个“可加载”的JAR包都可以在其META-INF目录中拥有一个web-fragment.xml文件,指定servlet、filter等。这是为了允许库和框架指定它们自己的servlet或其他对象。

在上下文初始化时动态注册servlets、filters和listeners(插件化)

在Servlets 3中,ServletContextListener可以使用添加到SevletContext的以下方法动态添加servlets、filters和listeners:addServlet()、addFilter()和addListener()

异步支持

例如:假设某个servlet容器具有五个线程池中的线程,并且需要执行每个请求的耗时进程(如复杂的SQL查询)。

  • 对于Servlets 2.5,如果同时接收到五个请求并且五个可用线程开始处理进程,该servlet容器将耗尽可用线程,因为线程将一直等待直到service()(或doGet()、doPost()等)从头到尾执行并返回响应。

  • 对于Servlets 3.0,这个长时间的进程可以被委托给另一个线程,在发送响应之前完成service()(现在最新的线程将发送响应)。这样,该线程就可以空闲地接收新的响应。

异步支持的示例:

Servlets 2.5:

public class MyAwesomeServlet extends HttpSerlvet {

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        // ...

        runSlowProcess();
        // no async support, thread will be free when runSlowProcess() and
        // doGet finish

        // ...
    }

}

Servlets 3:

@WebServlet(name="myServlet",
             urlPatterns={"/mySlowProcess"},
             asyncSupported=true) // asyncSupported MUST be specified for
                                  // servlets that support asynchronous
                                  // processing
public class MyAwesomeServlet extends HttpSerlvet {

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {


        // an AsyncContext is created, now the response will be completed
        // not when doGet finalizes its execution, but when
        // myAsyncContext.complete() is called.
        AsyncContext myAsyncContext = request.startAsync(request, response);

        // ...

        // myAsyncContext is passed to another thread
        delegateExecutionToProcessingThread(myAsyncContext);

        // done, now this thread is free to serve another request
    }

}

// ... and somewhere in another part of the code:

public class MyProcessingObject {

    public void doSlowProcess() {

        // ...

        runSlowProcess();
        myAsyncContext.complete(); // request is now completed.

        // ...

    }

}

接口 AsyncContext 还有获取请求对象、响应对象和添加监听器以在进程结束时通知它们的方法。

编程式登录和注销 (安全增强)

在servlets 3中,接口 HttpServletRequest 新增了两个方法:login(username, password)logout()

更多细节请参考Java EE 6 API


3
值得一提的是,Servlet 3.0已于2009年12月发布。该问题和当前被接受的答案都早于那个时期。 - eis
1
在官方规范中,@ServletFilter 被翻译为 @WebFilter,而 @WebServletContextListener 则被翻译为 @WebListener - lapo

21

虽然Servlet 3.0尚未发布,但看起来已经非常接近了。3.0中最重要的更改是:可插拔性、开发便利性、异步Servlet和安全性。这些是否对您重要,我无法说。

其中最重要的可能是对异步Servlet的支持。这里有一篇详细介绍的文章。(链接)完整的规范可以在此处下载。(链接)


天啊,太棒了。异步编程看起来很棒,谢谢你的信息。我刚刚完成了一个非常类似的编码工作。 - Max A.
@adi 它在2009年12月发布(https://jcp.org/aboutJava/communityprocess/final/jsr315/) - mauhiz
5
更新:2013年5月发布Servlet 3.1规范。请参阅新内容 - Basil Bourque

13

正如Don所提到的,改进和添加的主要领域包括:

  • 可插拔性(将web.xml模块化)
  • 开发便捷性(注解、泛型、约定优于配置)
  • 异步servlet支持(用于Comet风格编程、异步Web代理、异步Web服务)
  • 安全性增强(编程式登录/注销)
  • 其他功能(HttpOnly Cookie、会话跟踪、WAR文件中的EJB)

请查看Javaone 2008演示文稿 "Java Servlet 3.0 API: 有什么新特性和激动人心的地方"以获取详细信息。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接