Servlet的配置与启动有关问题

Servlet的配置与启动问题

初学Servlet,在Eclipse的web.xml中配置Servlet的映射的时候有些地方不大懂,为什么要这样配置,

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <display-name>Web</display-name>

  <welcome-file-list>

    <welcome-file>index.html</welcome-file>

    <welcome-file>index.htm</welcome-file>

    <welcome-file>index.jsp</welcome-file>

    <welcome-file>default.html</welcome-file>

    <welcome-file>default.htm</welcome-file>

    <welcome-file>default.jsp</welcome-file>

  </welcome-file-list>

  <!-- 向容器注册一个servlet -->

  <servlet>

      <servlet-name>HelloServlet</servlet-name>

      <servlet-class>com.servlets.HelloServlet</servlet-class>

  </servlet>

  <!--对servlet作出映射  -->

  <servlet-mapping>

      <servlet-name>HelloServlet</servlet-name>

      <!-- 这个地址是被编译后的servlet的地址 -->

      <url-pattern>/HelloServlet</url-pattern>

  </servlet-mapping>

</web-app>

 开始的时候不清楚做映射的的时候为什么要这么处理,为什么要在映射的servlet前加上'/',后来看了看Tomcat服务器的实例和网上的一些资料,大概了解了以下:

先从Tomcat的启动开始分析的:整个启动过程如下:

三月 17, 2014 12:08:01上午 org.apache.catalina.core.AprLifecycleListener init

INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre7\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\Java\jdk1.7.0_17\bin;D:\Java_IDE\Eclispe_Andriod\sdk\tools;D:\Java_IDE\Eclispe_Andriod\sdk\platform-tools;C:\AppServ\Apache2.2\bin;C:\AppServ\php5;C:\AppServ\MySQL\bin;.

三月 17, 2014 12:08:02上午 org.apache.tomcat.util.digester.SetPropertiesRule begin

WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:Web' did not find a matching property.

三月 17, 2014 12:08:02上午 org.apache.coyote.AbstractProtocol init

INFO: Initializing ProtocolHandler ["http-bio-8080"]

三月 17, 2014 12:08:02上午 org.apache.coyote.AbstractProtocol init

INFO: Initializing ProtocolHandler ["ajp-bio-8009"]

三月 17, 2014 12:08:02上午 org.apache.catalina.startup.Catalina load

INFO: Initialization processed in 725 ms

三月 17, 2014 12:08:02上午 org.apache.catalina.core.StandardService startInternal

INFO: Starting service Catalina

三月 17, 2014 12:08:02上午 org.apache.catalina.core.StandardEngine startInternal

INFO: Starting Servlet Engine: Apache Tomcat/7.0.47

三月 17, 2014 12:08:02上午 org.apache.tomcat.util.digester.Digester endElement

WARNING:   No rules found matching 'Context/Context/WatchedResource'.

三月 17, 2014 12:08:02上午 org.apache.tomcat.util.digester.Digester endElement

WARNING:   No rules found matching 'Context/Context'.

三月 17, 2014 12:08:03上午 org.apache.tomcat.util.digester.Digester endElement

WARNING:   No rules found matching 'Context/Context/WatchedResource'.

三月 17, 2014 12:08:03上午 org.apache.tomcat.util.digester.Digester endElement

WARNING:   No rules found matching 'Context/Context'.

三月 17, 2014 12:08:03上午 org.apache.coyote.AbstractProtocol start

INFO: Starting ProtocolHandler ["http-bio-8080"]

三月 17, 2014 12:08:03上午 org.apache.coyote.AbstractProtocol start

INFO: Starting ProtocolHandler ["ajp-bio-8009"]

三月 17, 2014 12:08:03上午 org.apache.catalina.startup.Catalina start

INFO: Server startup in 1351 ms

 

 

说道整个启动过程,Tomcat会先读取它 的配置文件server.xml,整个文档内容如下:

<?xmlversion="1.0"encoding="UTF-8"?>

<!--

  Licensed to the Apache Software Foundation (ASF) under one or more

  contributor license agreements.  See the NOTICE file distributed with

  this work for additional information regarding copyright ownership.

  The ASF licenses this file to You under the Apache License, Version 2.0

  (the "License"); you may not use this file except in compliance with

  the License.  You may obtain a copy of the License at

 

      http://www.apache.org/licenses/LICENSE-2.0

 

  Unless required by applicable law or agreed to in writing, software

  distributed under the License is distributed on an "AS IS" BASIS,

  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  See the License for the specific language governing permissions and

  limitations under the License.

--><!-- Note:  A "Server" is not itself a "Container", so you may not

     define subcomponents such as "Valves" at this level.

     Documentation at /docs/config/server.html

 --><Serverport="8005"shutdown="SHUTDOWN">

  <!-- Security listener. Documentation at /docs/config/listeners.html

  <Listener className="org.apache.catalina.security.SecurityListener" />

  -->

  <!--APR library loader. Documentation at /docs/apr.html -->

  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>

  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->

  <Listener className="org.apache.catalina.core.JasperListener"/>

  <!-- Prevent memory leaks due to use of particular java/javax APIs-->

  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>

  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>

  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

 

  <!-- Global JNDI resources

       Documentation at /docs/jndi-resources-howto.html

  -->

  <GlobalNamingResources>

    <!-- Editable user database that can also be used by

         UserDatabaseRealm to authenticate users

    -->

    <Resource auth="Container" description="User database that can be updated and saved"factory="org.apache.catalina.users.MemoryUserDatabaseFactory"name="UserDatabase"pathname="conf/tomcat-users.xml"type="org.apache.catalina.UserDatabase"/>

  </GlobalNamingResources>

 

  <!-- A "Service" is a collection of one or more "Connectors" that share

       a single "Container" Note:  A "Service" is not itself a "Container",

       so you may not define subcomponents such as "Valves" at this level.

       Documentation at /docs/config/service.html

   -->

  <Service name="Catalina">

 

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->

    <!--

    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"

        maxThreads="150" minSpareThreads="4"/>

    -->

 

 

    <!-- A "Connector" represents an endpoint by which requests are received

         and responses are returned. Documentation at :

         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)

         Java AJP  Connector: /docs/config/ajp.html

         APR (HTTP/AJP) Connector: /docs/apr.html

         Define a non-SSL HTTP/1.1 Connector on port 8080

    -->

    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

    <!-- A "Connector" using the shared thread pool-->

    <!--

    <Connector executor="tomcatThreadPool"

               port="8080" protocol="HTTP/1.1"

               connectionTimeout="20000"

               redirectPort="8443" />

    -->

    <!-- Define a SSL HTTP/1.1 Connector on port 8443

         This connector uses the JSSE configuration, when using APR, the

         connector should be using the OpenSSL style configuration

         described in the APR documentation -->

    <!--

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"

               maxThreads="150" scheme="https" secure="true"

               clientAuth="false" sslProtocol="TLS" />

    -->

 

    <!-- Define an AJP 1.3 Connector on port 8009 -->

    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>

 

 

    <!-- An Engine represents the entry point (within Catalina) that processes

         every request.  The Engine implementation for Tomcat stand alone

         analyzes the HTTP headers included with the request, and passes them

         on to the appropriate Host (virtual host).

         Documentation at /docs/config/engine.html -->

 

    <!-- You should set jvmRoute to support load-balancing via AJP ie :

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">

    -->

    <Engine defaultHost="localhost" name="Catalina">

 

      <!--For clustering, please take a look at documentation at:

          /docs/cluster-howto.html  (simple how to)

          /docs/config/cluster.html (reference documentation) -->

      <!--

      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

      -->

 

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords

           via a brute-force attack -->

      <Realm className="org.apache.catalina.realm.LockOutRealm">

        <!-- This Realm uses the UserDatabase configured in the global JNDI

             resources under the key "UserDatabase".  Any edits

             that are performed against this UserDatabase are immediately

             available for use by the Realm.  -->

        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"resourceName="UserDatabase"/>

      </Realm>

 

      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">

 

        <!-- SingleSignOn valve, share authentication between web applications

             Documentation at: /docs/config/valve.html -->

        <!--

        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />

        -->

 

        <!-- Access log processes all example.

             Documentation at: /docs/config/valve.html

             Note: The pattern used is equivalent to using pattern="common" -->

        <Valve className="org.apache.catalina.valves.AccessLogValve"directory="logs"pattern="%h %l %u %t &quot;%r&quot; %s %b"prefix="localhost_access_log."suffix=".txt"/>

 

      <Context docBase="Web" path="/Web" reloadable="true" source="org.eclipse.jst.jee.server:Web"/></Host>

    </Engine>

  </Service>

</Server>

 注释就不要看了,直接分析

1.<Server port="8005" shutdown="SHUTDOWN"> 启动Tomcat服务器,该服务器运行在8005号端口

2. <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>

 <Listener className="org.apache.catalina.core.JasperListener"/>

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

这些都使一些java类,负责监听和数据加密的监听器,其中只要了解整个单词catalina,该文件下的java文件的作用就是

脚本catalina用于启动和关闭tomcat服务器,是最关键的脚本(百度百科上)

3.<Service name="Catalina">

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>

<Engine defaultHost="localhost" name="Catalina">

<Realm className="org.apache.catalina.realm.LockOutRealm">

 <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log." suffix=".txt"/>

      <Context docBase="Web" path="/Web" reloadable="true" source="org.eclipse.jst.jee.server:Web"/></Host>

这才是要说明的东西,是开启Tomecat容器的服务说明,因为我是向解决路径映射问题,因此没有去关注其他细节,我看到了里面有一行

<Context docBase="Web" path="/Web" reloadable="true" source="org.eclipse.jst.jee.server:Web"/></Host>这样的说明,里面的path属性的值为/Web,而不是/Web/,

  因此问题应该就在这里了.

4.接下来我们再看一下上面的整个红色代码,是Tomcat启动的过程,最开始是启动这个监听器org.apache.catalina.core.AprLifecycleListener init,对应着server.xml文件的配置内容

 接下来后面跟着长长的一串INFO,不要去看,是我没把Tomcat配置到系统的环境变量中去,如果你设置了,就不会出现.

上午 org.apache.tomcat.util.digester.SetPropertiesRule begin

Initializing ProtocolHandler ["http-bio-8080"]

Initializing ProtocolHandler ["ajp-bio-8009"]

Initialization processed in 725 ms

这些都是一些初始化,不用关注,

5.Starting service Catalina

Starting Servlet Engine: Apache Tomcat/7.0.47

org.apache.coyote.AbstractProtocol start

org.apache.coyote.AbstractProtocol start

org.apache.catalina.startup.Catalina start

  这里才真正开启好了Tomcat服务器.

但是在整个启动过程中,没有发现我想要的信息,但是哪出错了呢?我又从新看了一遍,才发现我的思路有问题,然后又去看了相关资料,后来在Tomcat v7.0 Server at localhost-config下的web.xml文件中找到了说明,

<servlet>

        <servlet-name>default</servlet-name>

        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>

        <init-param>

            <param-name>debug</param-name>

            <param-value>0</param-value>

        </init-param>

        <init-param>

            <param-name>listings</param-name>

            <param-value>false</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

    </servlet>

 

<servlet-mapping>

        <servlet-name>default</servlet-name>

        <url-pattern>/</url-pattern>

    </servlet-mapping>

 

    <!-- The mappings for the JSP servlet -->

    <servlet-mapping>

        <servlet-name>jsp</servlet-name>

        <url-pattern>*.jsp</url-pattern>

        <url-pattern>*.jspx</url-pattern>

    </servlet-mapping>

 这是官方给出的实例,但是还是没找到我想要的,好吧,我承认我搞错了,

localhost:8080/Web/HelloServlet看了看自己的路径和网上的好博客,才发现,/只是作为我们URL的一部分上下文.

后来才在网上找到了答案,转载内容如下:

Web容器需要本章描述的映射技术去映射客户端请求到Servlet(该规范2.5以前的版本,使用这些映射技术是作为一个建议而不是要求,允许servlet容器各有其不同的schema用于映射客户端请求到servlet)。

12.1 使用URL路径

在收到客户端请求时,web容器确定转发到哪一个Web应用。选择的Web应用必须具有最长的上下文路径匹配请求URL的开始。当映射到Servlet时,URL匹配的一部分是上下文。

Web容器接下来必须用下面描述的路径匹配步骤找出servlet来处理请求。

用于映射到Servlet的路径是请求对象的请求URL减去上下文和路径参数部分。下面的URL路径映射规则按顺序使用。使用第一个匹配成功的且不会进一步尝试匹配:

1. 容器将尝试找到一个请求路径到servlet路径的精确匹配。成功匹配则选择该servlet。

2. 容器将递归地尝试匹配最长路径前缀。这是通过一次一个目录的遍历路径树完成的,使用‘/’字符作为路径分隔符。最长匹配确定选择的servlet。

3. 如果URL最后一部分包含一个扩展名(如 .jsp),servlet容器将视图匹配为扩展名处理请求的Servlet。扩展名定义在最后一部分的最后一个‘.’字符之后。

4. 如果前三个规则都没有产生一个servlet匹配,容器将试图为请求资源提供相关的内容。如果应用中定义了一个“default”servlet,它将被使用。许多容器提供了一种隐式的default servlet用于提供内容。

容器必须使用区分大小写字符串比较匹配。

12.2 映射规范

在web应用部署描述符中,以下语法用于定义映射:

■ 以‘/’字符开始、以‘/*’后缀结尾的字符串用于路径匹配。

■ 以‘*.’开始的字符串用于扩展名映射。

■ 空字符串“”是一个特殊的URL模式,其精确映射到应用的上下文根,即,http://host:port/<context-root>/请求形式。在这种情况下,路径信息是‘/’且servlet路径和上下文路径是空字符串(“”)。

■ 只包含“/”字符的字符串表示应用的“default”servlet。在这种情况下,servlet路径是请求URL减去上下文路径且路径信息是null。

■ 所以其他字符串仅用于精确匹配。

12.2.1 隐式映射

如果容器有一个内部的JSP容器,*.jsp扩展名映射到它,允许执行JSP页面的要求。该映射被称为隐式映射。如果Web应用定义了一个*.jsp映射,它的优先级高于隐式映射。

Servlet容器允许进行其他的隐式映射,只要显示映射的优先。例如,一个*.shtml隐式映射可以映射到包含在服务器上的功能。

12.2.2 示例映射集合

请看下面的一组映射:

表 12-1  示例映射集合

Path Pattern

Servlet

/foo/bar/*

servlet1

/baz/*

servlet2

/catalog

servlet3

*.bop

servlet4

 

将产生以下行为:

表 12-2  传入路径应用于示例映射

Incoming Path

Servlet Handling Request

/foo/bar/index.html

servlet1

/foo/bar/index.bop

servlet1

/baz

servlet2

/baz/index.html

servlet2

/catalog

servlet3

/catalog/index.html

“default” servlet

/catalog/racecar.bop

servlet4

/index.bop

servlet4

 

请注意,在/catalog/index.html和/catalog/racecar.bop的情况下,不使用映射到“/catalog”的servlet,因为不是精确匹配的。