`
jimichan
  • 浏览: 277957 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

第5章 部署Web应用程序

阅读更多

第5章 部署Web应用程序

    当我们编写好一个web应用程序,如何交付给Jetty容器来运行呢?这也就是所谓“部署web应用程序”。
    本章将介绍如何在Jetty中部署web应用,以及在Jetty的构架体系中是如何实现web应用部署的。

5.1 常用术语

    为了使本章中讨论的内容能得到大家一致的理解,本节先明确一些专业术语,避免大家造成误解。

    web应用程序(Web Application)
    
        经常会说到这个词,大家也不难理解,就是由一组文件构成的集合,这些文件可能包含html文件、图像文件、java编译后的class文件,配置文件等 等所有可能出现的文件。符合Servlet规范的应用程序还要求目录下存在一个WEB-INF的文件夹,在里面还必须存在一个web.xml的web部署 配置文件,关于这个目录和web.xml的内容格式都是Servlet规范中定义的。根据Servlet规范我们还可以web应用程序整个目录打包成 war文件。


    上下文(Context)
    
    上下文是我们经常听到的词汇,可以使用在各种专业场合,但当我谈论web应用程序的时候,是这样的意思
    首先看一个名为Example的web应用程序的访问URL,http://www.yourdomain.com/example /index.jsp。可以发现要访问这个Example应用,所有的路径都需要加前缀“/example”,换句话说,就是该应该的访问地址都符合 http://www.yourdomain.com/example/* 这种模式。所有已http://www.yourdomain.com/example/开头的请求都将有Example应用程序处理。
        
    这就是上下文的概念了。有了上下文的概念后,一个web服务下就可以部署多套不同的web应用程序了,且不同的应用程序不会造成混乱。
    

    上下文路径(Context Path)
    
      在术语 上 下文的中,我们举例的“/example”就是上下文路径。同一个服务器下的不 同的web应用就应该有不同的上下文路径。
    注意:上下文路径必须以“/”开头,且不能以“/”结尾。
    在Servlet规范中,通过API,request.getContextPath()方法来获取当前应用程序的上下文路径

      
    

5.2 初探

     如果你使用过Tomcat服务器的话,那么你一定知道在Tomcat下部署一个web应用会有两种方式:一、将web程序目录或者war文件程序复制到 webapps目录。二、编写配置文件,指向到web程序的目录。我们Jetty也提供类似这两种方式,确有略为不同。
    
    静态部署
    

    在jetty安装目录下存在一个名为webapps的目录,你可以存放web应用程序或者war文件。Jetty服务启动时会扫描webapps目录下 面的文件,如果识别为web应用程序,那么就启动它。上下文路径就是文件夹的名称或者war文件的名称。(文件夹或war的名称是 root,对应的上下文路径为 “/”)


    此类部署方式之所以被称为静态部署 ,是因为在服 务器启动完成后便不在扫描webapps目录变动情况了,换句话说,在服务启动完成后,再在webapps部署新的web应用,不会及时生效,需等到服务 器重启后才能被识别。
    
    顺便提醒下,虽然这里叫静态部署,但是web应用里面的jsp被修好后,还是会被动态重编译。


    动态部署

    在jetty安装目录下存在一个名为contexts的目录,在这个目录里面是用来放置动态部署的配置文件的,配置文件是xml文件,使用的语法和第4 章介绍的Jetty xml Configuration 语法相同。(配置文件语法统一,这也是jetty设计优秀之处)jetty启动服务时,会开启一个线程每隔一段时间扫描contexts目录下的xml配 置文件,然后更加配置文件的内容来部署一个web应用。当服务器启动后的任意时刻,你在contexts下新增一个配置文件,jetty就会动态地启动这 个web应用,同理,删除一个已存在的配置文件,jetty就会关闭相应的web应用。你也可以修改一下配置文件的最后修改时间,来达到重启web应用的 功能。

    此类部署方式就是所谓的动态部署了。

    需要提醒的是,通常情况下你会认为部署一个web应用程序,那么这个web应用一定是符合Servlet规范的,不然jetty为什么会叫 servlet容器呢!但是Jetty的设计哲学没有强迫你非得这样做,Jetty允许你发布一个支持上下文功能,但不支持Servlet的应用。
    
    如,在jetty自带的示例中,contexts目录下有一个文件javadoc.xml,内容如下:
    

<?xml version="1.0"  encoding="ISO-8859-1"?>

<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">

<!--
Configure a custom context for the javadoc.
This context contains only a ServletHandler with a default servlet
to serve static html files and images.
-->

<Configure class="org.mortbay.jetty.handler.ContextHandler">
  <Call class="org.mortbay.log.Log" name="debug"><Arg>Configure javadoc.xml</Arg></Call>
  <Set name="contextPath">/javadoc</Set>
  <Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/javadoc/</Set>
  <Set name="handler">
    <New class="org.mortbay.jetty.handler.ResourceHandler">
      <Set name="welcomeFiles">
        <Array type="String">
          <Item>index.html</Item>
          <Item>contents.html</Item> <!-- the index if javadoc not generated -->
        </Array>
      </Set>
      <Set name="cacheControl">max-age=3600,public</Set>
    </New>
  </Set>
</Configure>

该 配置文件启动了一个java文档的web服务,文档的静态文件被放在 $jetty_home/javadoc目录下,访问地址是http://127.0.0.1:8080/javadoc。
现在看 不懂这个文件也不要紧,后续内容会设计,这里只是用来展示下Jetty的灵活性。


webapps目录和contexts目录

这两个目录的位置一定必须在jetty安装目录下面么?它 们的名字必须如此么?

根据前面不断宣称的Jetty的灵活性,答案肯定是否定 的。目录的名称和位置只是jetty.xml文件中的默认配置,如果你愿意都可以修改。

5.3 Jetty实现上下文功能的基本原理

    既然jetty可以同时部署多个web应用程序,那么必然支持上下文功能。本小节向你展示下Jetty是如何支持上下文功能。

    在默认的服务配置文件jetty.xml中有如下一段配置:

 <!-- =========================================================== -->
    <!-- 设置Handlers --> 
    <!-- =========================================================== -->

    <Set name="handler">
    <!-- HandlerCollection中每一个Handler都会被按顺序执行  --> 
      <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
        <Set name="handlers">
         <Array type="org.mortbay.jetty.Handler">
           <Item>
                <!-- ContextHandler 的集合  --> 
             <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
           </Item>

           <Item>
              <!-- DefaultHandler 如果前一Handler没有处理request的话就会执行它。用来输出提                                 示信息或者输出网站图标  -->
             <New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
           </Item>
            
            <!-- 请求日志记录器  -->
           <Item>
             <New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
           </Item>
         </Array>
        </Set>
      </New>
    </Set>


    通过这段默认配置,为Jetty的Server对象设置了一组Handler对象,结构如下图:


Server对象将接收到的HTTP请求转发到 HandlerCollection对象,再由HandlerCollection对象将HTTP请求按顺序转发给内部所有的Handler对象,即被 HandlerCollection包含的对象都有机会去处理每一个请求。

让我们看一段 HandlerCollection的核心代码,来验证上面的说法:

           for (int i=0;i<_handlers.length;i++)
            {
                try
                {
                    _handlers[i].handle(target,request, response, dispatch);
                }
                catch(IOException e)
                {
                    throw e;
                }
                catch(RuntimeException e)
                {
                    throw e;
                }
                catch(Exception e)
                {
                    if (mex==null)
                        mex=new MultiException();
                    mex.add(e);
                }
            }


现 在来主要看本节的主角ContextHandlerCollection,通过
<New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>来配置,从上图中看 出它也是一个集合,集合就意味着可以容纳其他Handler,再从类名可以看出该集合只能容纳ContextHandler类以及它的子类。New标签的 id属性被设置为“Contexts”,由第4章的内容可知ContextHandlerCollection对象会以key为“Contexts”保存 起来,可以使用Ref标签可以再次引用该对象,如何引用在下面的篇章会介绍。

ContextHandlerCollection 的作用是什么?其作用是将接收到的请求分发给正确的ContextHandler来处理,分发的依据就是ContextHandler的上下文路径。


5.3 静态部署的原理和配置文件

    上一节介绍了ContextHandlerCollection对象,但何时、如何向该对象中放入ContextHandler对象或其子类对象呢?本 节介绍的静态部署将是其中的一种方法。


    先看一段jetty.xml中的配置片段:

    <!-- =========================================================== -->
    <!-- Configure the webapp deployer.                              -->
    <!-- A webapp  deployer will deploy standard webapps discovered  -->
    <!-- in a directory at startup, without the need for additional  -->
    <!-- configuration files.    It does not support hot deploy or   -->
    <!-- non standard contexts (see ContextDeployer above).          -->
    <!--                                                             -->
    <!-- This deployer is configured to deploy webapps from the      -->
    <!-- $JETTY_HOME/webapps directory                               -->
    <!--                                                             -->
    <!-- Normally only one type of deployer need be used.            -->
    <!--                                                             -->
    <!-- =========================================================== -->
    <Call name="addLifeCycle">
      <Arg>
        <New class="org.mortbay.jetty.deployer.WebAppDeployer">
          <Set name="contexts"><Ref id="Contexts"/></Set>
          <Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
 <Set name="parentLoaderPriority">false</Set>
 <Set name="extract">true</Set>
 <Set name="allowDuplicates">false</Set>
          <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
        </New>
      </Arg>
    </Call>

等 价的Java代码是:
WebAppDeployer webAppDeployer = new WebAppDeployer ();
webAppDeployer.setContexts(env.get("Contexts "));
webAppDeployer.setWebAppDir(System.getProperty("jetty.home",".")+"/webapps" );
webAppDeployer.setParentLoaderPriority(false);
webAppDeployer.setExtract(true);
webAppDeployer.setAllowDuplicates(false);
webAppDeployer.setDefaultsDescriptor(System.getProperty("jetty.home",".")+"/etc/webdefault.xml" );

server .addLifeCycle(webAppDeployer );


其实Jetty就是用WebAppDeployer对象来完 成静态部署的任务的。上一节中我们说过ContextHandlerCollection对象会以key为“Contexts”保存起 来,WebAppDeployer.setContexts(env.get("Contexts "));方法将 ContextHandlerCollection对象的引用设置给了webAppDeployer对象,在服务器启动过程中 WebAppDeployer将默认实例化一些的ContextHandler的子类WebappContext的实例,并添加到 ContextHandlerCollection对象中去。大致的过程就是这样的,细节问题接下来会讨论。


WebAppDeployer 类的工作内容

当服务器启动时,WebAppDeployer扫描指定的WebAppDir 目录(默认配置为System.getProperty("jetty.home",".")+"/webapps" ,及jetty安装目录下的webapps目录,可以修改 )。 在WebAppDir目录中发现的文件夹或者.war文件或者.jar文件,每个文件夹或文件都会被看作是一个的web应用程序,实例化一个 WebAppContext对象,并将该对象添加到ContextHandlerCollection对象中去。

WebAppContext 代表一个支持Servlet标准的应用程序。


5.4 动态部署的原理和配置


    动态部署的原理和静态部署基本原理差不多,都是向ContextHandlerCollection对象中增加ContextHandler的实例对 象。
    先看一段jetty.xml的配置:

    <!-- =========================================================== -->
    <!-- Configure the context deployer                              -->
    <!-- A context deployer will deploy contexts described in        -->
    <!-- configuration files discovered in a directory.              -->
    <!-- The configuration directory can be scanned for hot          -->
    <!-- deployments at the configured scanInterval.                 -->
    <!--                                                             -->
    <!-- This deployer is configured to deploy contexts configured   -->
    <!-- in the $JETTY_HOME/contexts directory                       -->
    <!--                                                             -->
    <!-- =========================================================== -->
    <Call name="addLifeCycle">
      <Arg>
        <New class="org.mortbay.jetty.deployer.ContextDeployer">
          <Set name="contexts"><Ref id="Contexts"/></Set>
          <Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
          <Set name="scanInterval">5</Set>
        </New>
      </Arg>
    </Call>

    等价的Java代码是:
    ContextDeployer contextDeployer = new ContextDeployer ();
    contextDeployer.setContexts(env.get("Contexts") );            contextDeployer.setConfigurationDir(System.getProperty("jetty.home",".")+"/contexts" );
    contextDeployer.setScanInterval(5 );//扫描间隔时间

 

    server .addLifeCycle(contextDeployer);

    可以看出Jetty正是利用ContextDeployer类来实现动态部署的功能。
    

    ContextDeployer的工作内容


    当服务器启动时,ContextDeployer扫描$jetty_home/contexts目录下面的所有xml文件,根据xml文件的配置内容, 实例化相应的ContextHandler或其子类实现(WebappContext)对象,并将该对象添加到 ContextHandlerCollection对象中去。

    ContextDeployer的方法setScanInterval会设定一个扫描间隔时间,单位为秒。服务器启动完成后,会有一个后台线程以 scanInterval为间隔,不断扫描configurationDir指定的目录,如果发现xml文件的新增、删除、修改会相应的执行对应 ContextHandler对象的部署、移除、重新部署等工作。

    Contexts目录下面的配置文件是怎样的?使用的是Jetty xml Configuration的语法。先看一个文件示例:

$JettyHome/contexts/test.xml文件
<Configure class="org.mortbay.jetty.webapp.WebAppContext">

   <!-- 设定上下文路径 -->
  <Set name="contextPath">/test</Set>
    <!-- 设定web应用程序的war文件位置 -->
  <Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test</Set>

  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
  <!-- 其他可选的配置属性                                  -->
  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
  <Set name="extractWAR">false</Set>
  <Set name="copyWebDir">false</Set>
  <Set name="defaultsDescriptor"> <SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>

  <!-- virtual hosts
  <Set name="virtualHosts">
    <Array type="String">
      <Item>www.myVirtualDomain.com</Item>
      <Item>localhost</Item>
      <Item>127.0.0.1</Item>
    </Array>
  </Set>
  -->

  <!-- disable cookies 
  <Get name="sessionHandler">
     <Get name="sessionManager">
        <Set name="usingCookies" type="boolean">false</Set>
     </Get>
  </Get>
  -->

</Configure>

类 ContextDeployer是如何使用这个配置的呢?看下ContextDeployer中的一段核心代码:


XmlConfiguration xmlConfiguration=new XmlConfiguration(resource.getURL());
...
ContextHandler context=(ContextHandler) xmlConfiguration.configure();

第 四章中介绍过XmlConfiguration类,相信你也知道它的用途了。$JettyHome/contexts/test.xml文件中 Configure标签的属性class="org.mortbay.jetty.webapp.WebAppContext"指明了最终需要实例化的 类,这个类必须是ContextHandler本身或其子类,否则就会抛出异常。

在 text.xml文件中我们可以对当前test应用程序设定更多的特性,比如虚拟主机、是否启用Session功能等等,详细可以参考 WebAppContext类的API文档。


5.5 jetty-web.xml 配置文件

    在动态部署的方式下,我们可以对WebAppContext对象进行详细设置,但是在静态部署时却不可以。而且把和web应用程序功能相关的配置放在 contexts目录下的一个配置文件中,对部署人员也是一个挑战,很容易混乱。
    
    Jetty为了解决这个问题,运行我们在WEB-INF目录下面放入一个名为jetty-web.xml的文件(文件名还可以为jetty6- web.xml 或者 web-jetty.xml),这个配置文件的语法同样也是jetty xml configuration语法,其中Configure标签的class属性是 org.mortbay.jetty.webapp.WebAppContext。

    一个jetty-web.xml的示例:
<?xml version="1.0"  encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">

<!--
This is the jetty specific web application configuration file.  When starting
a Web Application, the WEB-INF/web-jetty.xml file is looked for and if found, treated
as a org.mortbay.xml.XmlConfiguration file and is applied to the
org.mortbay.jetty.servlet.WebApplicationContext objet
-->

<Configure class="org.mortbay.jetty.webapp.WebAppContext">
  <Call class="org.mortbay.log.Log" name="debug"><Arg>executing jetty-web.xml</Arg></Call>
  <!-- <Set name="contextPath">/mycontext</Set> -->
</Configure>

 

在 这个配置文件中你可以对已经实例化的WebAppContext对象进行操作。

    Jetty服务在启动一个WebAppContext应用程序时,WebAppContext类会在当前应用的WEB-INF目录下面搜寻jetty- web.xml的配置文件,如果发现了类似文件,就调用XmlConfiguration类对WebAppContext的实例对象进行配置。

    核心代码:
JettyWebXmlConfiguration.java

    XmlConfiguration jetty_config=new XmlConfiguration(jetty.getURL());
                    jetty_config.configure(getWebAppContext());

     jetty_config.configure(getWebAppContext());


    其中getWebAppContext()方法的作用是取得当前启动的WebAppContext对象。

    在Contexts目录下的配置文件中可以做的事情,在jetty-web.xml文件中一样可以做到。
    
    同样即使我们使用静态部署的方式部署一个WebAppContext的应用程序,一样可以通过在WEB-INF目录下加入jetty-web.xml文 件来控制WebAppContext对象的行为和属性。

5.6 webdefault.xml 文件

在ContextDeployer和WebAppDeployer两个类的实例化配置中我们都可 以看到一个名为defaultsDescriptor的属性配置,默认情况下都指向了$jetty_home/etc/webdefault.xml文 件。当然你可以不配置这个属性,默认会指向jetty.jar文件中的org/mortbay/jetty/webapp/webdefault.xml 文件,不过为了修改方便我们还是使用etc/webdefault.xml文件。

webdefault.xml 作用是什么?相信你在tomcat中也见过这种类似配置文件,作用就是为WebAppContext类型的应用程序提供一个默认的配置,其语法就是 Servlet规范中定义的web.xml文件的语法。

webdefault.xml主要定义了一 些组件如:
  • DefaultServlet:服务静态文件
  • JspServlet:     服务jsp页面

其余定义了常用的配置,比如默认Session过期时间、welcome- file-list等等。

接下来的章节会介绍DefaultServlet和JspServlet 的配置。



5.7 DefaultServlet配置

在webdefault.xml定义了DefaultServlet对象,DefaultServlet有很 多可选的配置。


参数名 可选值 默认值 作用
acceptRanges true 或 false true
服务器是否支持静态文件下载的断点 续传功能。
true支持,false不支持。

dirAllowed true 或 false true
如果访问的地址指向一个目录,且目录下不存在一个webcome文件的情况下,是否显 示该目录列表内容。true显示,false不显示。

注意:在生产环境下,建议设置为false,避免泄露不必要的详细。


welcomeServlets true 或 false false
一般情况下welcome- file-list指定的是具体存在文件,当文件不存在时要么显示403错误、要么显示目录列表内容。webcomeServlets的作用是,当 welcome文件不存在是是否把请求地址映射到响应的Servlet上执行。true映射,false不映射。
默认情况下是不映射的,除非你想 将一个某个Servlet路径作为一个webcome-file-list的一员时,可以将该设置为true。

redirectWelcome true 或 false false 请求发送给welcome文件路径的方 式。true使用redirect方式,false使用forward方式。

gzip true 或 false false
resoureBase


relativeResourceBase


useFileMappedBuffer true 或 false

cacheControl


maxCacheSize


maxCachedFileSize


maxCachedFiles


cacheType  "nio", "bio" or "both"

 

5.8 JSP配置

 <!-- ==================================================================== -->
  <!-- JSP Servlet                                                          -->
  <!-- This is the jasper JSP servlet from the jakarta project              -->
  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
  <!-- The JSP page compiler and execution servlet, which is the mechanism  -->
  <!-- used by Glassfish to support JSP pages.  Traditionally, this servlet -->
  <!-- is mapped to URL patterh "*.jsp".  This servlet supports the         -->
  <!-- following initialization parameters (default values are in square    -->
  <!-- brackets):                                                           -->
  <!--                                                                      -->
  <!--   checkInterval       If development is false and reloading is true, -->
  <!--                       background compiles are enabled. checkInterval -->
  <!--                       is the time in seconds between checks to see   -->
  <!--                       if a JSP page needs to be recompiled. [300]    -->
  <!--                                                                      -->
  <!--   compiler            Which compiler Ant should use to compile JSP   -->
  <!--                       pages.  See the Ant documenation for more      -->
  <!--                       information. [javac]                           -->
  <!--                                                                      -->
  <!--   classdebuginfo      Should the class file be compiled with         -->
  <!--                       debugging information?  [true]                 -->
  <!--                                                                      -->
  <!--   classpath           What class path should I use while compiling   -->
  <!--                       generated servlets?  [Created dynamically      -->
  <!--                       based on the current web application]          -->
  <!--                       Set to ? to make the container explicitly set  -->
  <!--                       this parameter.                                -->
  <!--                                                                      -->
  <!--   development         Is Jasper used in development mode (will check -->
  <!--                       for JSP modification on every access)?  [true] -->
  <!--                                                                      -->
  <!--   enablePooling       Determines whether tag handler pooling is      -->
  <!--                       enabled  [true]                                -->
  <!--                                                                      -->
  <!--   fork                Tell Ant to fork compiles of JSP pages so that -->
  <!--                       a separate JVM is used for JSP page compiles   -->
  <!--                       from the one Tomcat is running in. [true]      -->
  <!--                                                                      -->
  <!--   ieClassId           The class-id value to be sent to Internet      -->
  <!--                       Explorer when using <jsp:plugin> tags.         -->
  <!--                       [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93]   -->
  <!--                                                                      -->
  <!--   javaEncoding        Java file encoding to use for generating java  -->
  <!--                       source files. [UTF-8]                          -->
  <!--                                                                      -->
  <!--   keepgenerated       Should we keep the generated Java source code  -->
  <!--                       for each page instead of deleting it? [true]   -->
  <!--                                                                      -->
  <!--   logVerbosityLevel   The level of detailed messages to be produced  -->
  <!--                       by this servlet.  Increasing levels cause the  -->
  <!--                       generation of more messages.  Valid values are -->
  <!--                       FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
  <!--                       [WARNING]                                      -->
  <!--                                                                      -->
  <!--   mappedfile          Should we generate static content with one     -->
  <!--                       print statement per input line, to ease        -->
  <!--                       debugging?  [false]                            -->
  <!--                                                                      -->
  <!--                                                                      -->
  <!--   reloading           Should Jasper check for modified JSPs?  [true] -->
  <!--                                                                      -->
  <!--   suppressSmap        Should the generation of SMAP info for JSR45   -->
  <!--                       debugging be suppressed?  [false]              -->
  <!--                                                                      -->
  <!--   dumpSmap            Should the SMAP info for JSR45 debugging be    -->
  <!--                       dumped to a file? [false]                      -->
  <!--                       False if suppressSmap is true                  -->
  <!--                                                                      -->
  <!--   scratchdir          What scratch directory should we use when      -->
  <!--                       compiling JSP pages?  [default work directory  -->
  <!--                       for the current web application]               -->
  <!--                                                                      -->
  <!--   tagpoolMaxSize      The maximum tag handler pool size  [5]         -->
  <!--                                                                      -->
  <!--   xpoweredBy          Determines whether X-Powered-By response       -->
  <!--                       header is added by generated servlet  [false]  -->
  <!--                                                                      -->
  <!-- If you wish to use Jikes to compile JSP pages:                       -->
  <!--   Set the init parameter "compiler" to "jikes".  Define              -->
  <!--   the property "-Dbuild.compiler.emacs=true" when starting Jetty     -->
  <!--   to cause Jikes to emit error messages in a format compatible with  -->
  <!--   Jasper.                                                            -->
  <!--   If you get an error reporting that jikes can't use UTF-8 encoding, -->
  <!--   try setting the init parameter "javaEncoding" to "ISO-8859-1".     -->
  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->

5.9 Servlet2.5规范新特性

分享到:
评论
2 楼 宋建勇 2013-05-21  
解了心中疑惑,很好的东西,我越来越喜欢jetty了
1 楼 SINCE1978 2012-11-18  
写的不咋地,看了看给人感觉比tomcat麻烦得多!
整个半天连jetty代码启动还没讲?!WebAppDeployer这玩意还用讲吗?有tomcat要它干嘛?
比较失望

相关推荐

    面向.NET的WEB应用程序设计课件

    第15章 配置、优化和部署 Microsoft ASP.NET Web 应用程序 第16章 Web 安全性介绍 第17章 Web 应用程序安全性规划 第18章 验证用户输入 第19章 Internet 信息服务身份验证 第20章 保护 Web 页面安全 第21章 保护文件...

    Csharp入门经典(第四版).part5.rar

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    微软应用架构指南(第2版)

     第21章设计Web应用程序  第22章设计富客户端应用程序  第23章设计富Internet应用程序  第24章设计移动应用程序  第25章设计服务应用程序  第26章设计托管和云服务  第27章设计Office业务应用程序  第28章...

    第1章_作业——Java Web应用程序的开发与部署.pptx

    在MyEclipse下创建Web项目以及如何部署、运行。 建立与部署Java Web项目的步骤: (1)启动MyEclipse,并...(5)启动Web 服务器(Tomcate),然后运行程序。 (6)若需要部署到其他服务器,还需要生成并发布war文件。

    C#入门经典第五版.part2

    第20章 部署Web应用程序 第Ⅳ部分 数据访问 第21章 文件系统数据 第22章 XML 第23章 LINQ简介 第24章 应用LINQ 第Ⅴ部分 其他技术 第25章 Windows Presentation 第26章 Windows Communication 第27章 ...

    C#入门经典第五版.part1

    第20章 部署Web应用程序 第Ⅳ部分 数据访问 第21章 文件系统数据 第22章 XML 第23章 LINQ简介 第24章 应用LINQ 第Ⅴ部分 其他技术 第25章 Windows Presentation 第26章 Windows Communication 第27章 ...

    c#入门经典(第五版)中文版.PDF 分卷2(共3分卷)

    第20章 部署Web应用程序 第Ⅳ部分 数据访问 第21章 文件系统数据 第22章 XML 第23章 LINQ简介 第24章 应用LINQ 第Ⅴ部分 其他技术 第25章 Windows Presentation 第26章 Windows Communication 第27章 ...

    c#入门经典(第五版)中文版.PDF 分卷1(共3卷)

    第20章 部署Web应用程序 第Ⅳ部分 数据访问 第21章 文件系统数据 第22章 XML 第23章 LINQ简介 第24章 应用LINQ 第Ⅴ部分 其他技术 第25章 Windows Presentation 第26章 Windows Communication 第27章 ...

    c#入门经典(第五版)中文版.PDF 分卷3(共3分卷)

    第20章 部署Web应用程序 第Ⅳ部分 数据访问 第21章 文件系统数据 第22章 XML 第23章 LINQ简介 第24章 应用LINQ 第Ⅴ部分 其他技术 第25章 Windows Presentation 第26章 Windows Communication 第27章 ...

    Csharp入门经典(第四版).part1.rar

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    Csharp入门经典(第四版).part4.rar

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    Csharp入门经典(第四版).part3.rar

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    Csharp入门经典(第四版).part2.rar

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    C#入门经典(第四版)(美)沃森 内格尔.源码

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    有关初级C#教程ppt

    这是一C#教程,对于初学者很有益哦, 第1章 程序设计语言与程序设计方法 第2章 Visual C#概述 第3章 C#语法基础 第4章 顺序结构程序设计 第5章 选择结构程序设计 ...第15章 开发Web应用程序 第16章 部署应用程序

    MVC4web编程

    第5章:Web应用程序架构 第6章:使用AJAX提升网站体验 第7章:ASP.NET Web API 第8章:高级数据 第9章:安全 第10章:移动Web网站开发 第11章:并行计算、异步和实时数据操作 第12章:缓存 第13章:客户端优化技术 ...

    C#入门经典(第4版)中文版高清PDF【共16个分卷】.part10

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    C#入门经典(第4版)中文版高清PDF【共16个分卷】.part08

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    C#入门经典(第4版)中文版高清PDF【共16个分卷】.part06

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

    C#入门经典(第4版)中文版高清PDF【共16个分卷】.part01

    第23章 部署Web应用程序 第4部分 数据访问 第24章 文件系统数据 第25章 XML 第26章 LINQ简介 第27章 LINQ to SQL 第28章 ADO.NET和LINQ over 第29章 LINQ to XML 第5部分 其他技术 第30章 属性 第31章 XML文档说明 ...

Global site tag (gtag.js) - Google Analytics